tomcat-connectors-1.2.41-src/0000755000000000000020000000000012555256556014333 5ustar rootbintomcat-connectors-1.2.41-src/support/0000755000000000000020000000000012555256552016043 5ustar rootbintomcat-connectors-1.2.41-src/support/os_apache.m40000644000000000000020000000250710666607673020240 0ustar rootbindnl dnl Licensed to the Apache Software Foundation (ASF) under one or more dnl contributor license agreements. See the NOTICE file distributed with dnl this work for additional information regarding copyright ownership. dnl The ASF licenses this file to You under the Apache License, Version 2.0 dnl (the "License"); you may not use this file except in compliance with dnl the License. You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl dnl copied from httpd-2.0/os/config.m4 dnl OS changed to OS_APACHE and OS_DIR to OS_APACHE_DIR AC_MSG_CHECKING(for target platform) #PLATFORM=`${CONFIG_SHELL-/bin/sh} $ac_config_guess` PLATFORM=$host case "$PLATFORM" in *beos*) OS_APACHE="beos" OS_APACHE_DIR=$OS_APACHE ;; *pc-os2_emx*) OS_APACHE="os2" OS_APACHE_DIR=$OS_APACHE ;; bs2000*) OS_APACHE="unix" OS_APACHE_DIR=bs2000 # only the OS_APACHE_DIR is platform specific. ;; *) OS_APACHE="unix" OS_APACHE_DIR=$OS_APACHE;; esac AC_MSG_RESULT($OS_APACHE) tomcat-connectors-1.2.41-src/support/jk_pcre.m40000644000000000000020000000233410516516102017705 0ustar rootbindnl dnl Licensed to the Apache Software Foundation (ASF) under one or more dnl contributor license agreements. See the NOTICE file distributed with dnl this work for additional information regarding copyright ownership. dnl The ASF licenses this file to You under the Apache License, Version 2.0 dnl (the "License"); you may not use this file except in compliance with dnl the License. You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl AC_DEFUN( [JK_PCRE], [ AC_ARG_WITH(pcre, [ --with-pcre Build pcre support], [ case "${withval}" in y | yes | true) use_pcre=true ;; n | no | false) use_pcre=false ;; *) use_pcre=true ;; esac if ${TEST} ${use_pcre} ; then HAS_PCRE="-I${includedir} -DHAS_PCRE" PCRE_LIBS="-L${libdir} -lpcre -lpcreposix" fi ]) ]) dnl vi:set sts=2 sw=2 autoindent: tomcat-connectors-1.2.41-src/support/jk_apxs.m40000644000000000000020000001272610516516102017735 0ustar rootbindnl dnl Licensed to the Apache Software Foundation (ASF) under one or more dnl contributor license agreements. See the NOTICE file distributed with dnl this work for additional information regarding copyright ownership. dnl The ASF licenses this file to You under the Apache License, Version 2.0 dnl (the "License"); you may not use this file except in compliance with dnl the License. You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl dnl -------------------------------------------------------------------------- dnl Author Henri Gomez dnl dnl Inspired by Pier works on webapp m4 macros :) dnl dnl Version $Id: jk_apxs.m4 466585 2006-10-21 22:16:34Z markt $ dnl -------------------------------------------------------------------------- dnl -------------------------------------------------------------------------- dnl JK_APXS dnl dnl Get APXS to be used, determine if Apache 1.3 or 2.0 are target dnl $1 => blank/2 if you want to detect Apache 1.3 & 2.0 dnl $2 => comment for --with-apxs dnl -------------------------------------------------------------------------- AC_DEFUN( [JK_APXS], [ tempval="" AC_ARG_WITH(apxs$1, [ --with-apxs$1[=FILE] $2], [ case "${withval}" in y | yes | true) find_apxs=true ;; n | no | false) find_apxs=false ;; *) find_apxs=false ;; esac if ${TEST} ${find_apxs} ; then AC_MSG_RESULT([need to check for Perl first, apxs depends on it...]) AC_PATH_PROG(PERL,perl,$PATH)dnl if ${TEST} ${find_apxs} ; then APXS$1=${withval} else AC_PATH_PROG(APXS$1,apxs$1,$PATH)dnl fi use_apxs$1=true; if ${TEST} -n "${APXS$1}" ; then dnl Seems that we have it, but have to check if it is OK first if ${TEST} ! -x "${APXS$1}" ; then AC_MSG_ERROR(Invalid location for apxs: '${APXS$1}') fi ${APXS$1} -q PREFIX >/dev/null 2>/dev/null || apxs_support=false if ${TEST} "${apxs_support}" = "false" ; then AC_MSG_RESULT(could not find ${APXS$1}) AC_MSG_ERROR(You must specify a valid --with-apxs$1 path) fi dnl apache_dir and apache_include are also needed. APACHE$1_HOME=`${APXS$1} -q PREFIX` APACHE$1_INCL="-I`${APXS$1} -q INCLUDEDIR`" APACHE$1_INCDIR="`${APXS$1} -q INCLUDEDIR`" APACHE$1_LIBEXEC="`${APXS$1} -q LIBEXECDIR`" APACHE$1_CC="`${APXS$1} -q CC`" dnl test apache version APA=`${GREP} STANDARD20 ${APXS$1}` dnl check if we have an apxs for Apache 1.3 or 2.0 if ${TEST} -z "$APA" ; then if ${TEST} ! -z "$1" ; then AC_MSG_ERROR(Do not use --with-apxs$1 but --with-apxs) fi WEBSERVERS="${WEBSERVERS} server/apache13" RWEBSERVER="apache-1.3" APXS$1_CFLAGS="`${APXS$1} -q CFLAGS`" APXS$1_CPPFLAGS="" else if ${TEST} -z "$1" ; then AC_MSG_ERROR(Do not use --with-apxs but --with-apxs2) fi WEBSERVERS="${WEBSERVERS} server/apache2" RWEBSERVER="apache-2.0" APACHE2_CONFIG_VARS=${apache_dir}/build/config_vars.mk JK_CHANNEL_APR_SOCKET="\${JK}jk_channel_apr_socket\${OEXT}" JK_POOL_APR="\${JK}jk_pool_apr\${OEXT}" APXS$1_CFLAGS="`${APXS$1} -q CFLAGS` `${APXS$1} -q EXTRA_CFLAGS`" APXS$1_CPPFLAGS="`${APXS$1} -q EXTRA_CPPFLAGS`" APR_INCDIR="-I`${APXS$1} -q APR_INCLUDEDIR`" APR_UTIL_INCDIR="-I`${APXS$1} -q APU_INCLUDEDIR`" APACHE2_LIBDIR="`${APXS$1} -q LIBDIR`" LIBTOOL=`${APXS$1} -q LIBTOOL` if ${TEST} -f ${APACHE2_LIBDIR}/libapr-1.so \ -o -f ${APACHE2_LIBDIR}/libapr-1.sl \ -o -f ${APACHE2_LIBDIR}/libapr-1.dylib; then APR_LIBS="-L${APACHE2_LIBDIR} -lapr-1" elif ${TEST} -f ${APACHE2_LIBDIR}/libapr-0.so \ -o -f ${APACHE2_LIBDIR}/libapr-0.sl \ -o -f ${APACHE2_LIBDIR}/libapr-0.dylib; then APR_LIBS="-L${APACHE2_LIBDIR} -lapr-0" elif ${TEST} -f ${APACHE2_LIBDIR}/libapr.so \ -o -f ${APACHE2_LIBDIR}/libapr.sl \ -o -f ${APACHE2_LIBDIR}/libapr.dylib; then APR_LIBS="-L${APACHE2_LIBDIR} -lapr" else AC_MSG_ERROR(can't locate libapr) fi fi AC_MSG_RESULT([building connector for \"$RWEBSERVER\"]) fi fi ], [ AC_MSG_RESULT(no apxs$1 given) ]) unset tempval AC_SUBST(APXS$1) AC_SUBST(APXS$1_CFLAGS) AC_SUBST(APACHE$1_CONFIG_VARS) AC_SUBST(APXS$1_CPPFLAGS) AC_SUBST(APACHE$1_DIR) AC_SUBST(APACHE$1_HOME) AC_SUBST(APACHE$1_INCDIR) AC_SUBST(APACHE$1_INCL) AC_SUBST(APACHE$1_LIBEXEC) AC_SUBST(APACHE$1_LIBDIR) AC_SUBST(APACHE$1_CC) AC_SUBST(APXS$1_LDFLAGS) AC_SUBST(APR_LIBS) ]) dnl vi:set sts=2 sw=2 autoindent: tomcat-connectors-1.2.41-src/support/jk_tchome.m40000644000000000000020000000440410516516102020233 0ustar rootbindnl dnl Licensed to the Apache Software Foundation (ASF) under one or more dnl contributor license agreements. See the NOTICE file distributed with dnl this work for additional information regarding copyright ownership. dnl The ASF licenses this file to You under the Apache License, Version 2.0 dnl (the "License"); you may not use this file except in compliance with dnl the License. You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl dnl -------------------------------------------------------------------------- dnl Author Henri Gomez dnl dnl Inspired by Pier works on webapp m4 macros :) dnl dnl Version $Id: jk_tchome.m4 466585 2006-10-21 22:16:34Z markt $ dnl -------------------------------------------------------------------------- dnl -------------------------------------------------------------------------- dnl JK_TCHOME dnl Set the Tomcat Home directory. dnl $1 => Tomcat Name dnl $2 => Tomcat VarName dnl $3 => File which should be present dnl -------------------------------------------------------------------------- AC_DEFUN( [JK_TCHOME], [ tempval="" AC_MSG_CHECKING([for $1 location]) AC_ARG_WITH( [$1], [ --with-$1=DIR Location of $1 ], [ case "${withval}" in ""|"yes"|"YES"|"true"|"TRUE") ;; "no"|"NO"|"false"|"FALSE") AC_MSG_ERROR(valid $1 location required) ;; *) tempval="${withval}" if ${TEST} ! -d ${tempval} ; then AC_MSG_ERROR(Not a directory: ${tempval}) fi if ${TEST} ! -f ${tempval}/$3; then AC_MSG_ERROR(can't locate ${tempval}/$3) fi ;; esac ]) if ${TEST} -z "$tempval" ; then AC_MSG_RESULT(not provided) else [$2]=${tempval} AC_MSG_RESULT(${[$2]}) fi unset tempval ]) dnl vi:set sts=2 sw=2 autoindent: tomcat-connectors-1.2.41-src/support/jk_dominohome.m40000644000000000000020000000452010516516102021111 0ustar rootbindnl dnl Licensed to the Apache Software Foundation (ASF) under one or more dnl contributor license agreements. See the NOTICE file distributed with dnl this work for additional information regarding copyright ownership. dnl The ASF licenses this file to You under the Apache License, Version 2.0 dnl (the "License"); you may not use this file except in compliance with dnl the License. You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl dnl -------------------------------------------------------------------------- dnl Author Andy Armstrong dnl Shamelessly cribbed from Henri Gomez dnl dnl He was inspired by Pier works on webapp m4 macros :) dnl dnl Version $Id: jk_dominohome.m4 466585 2006-10-21 22:16:34Z markt $ dnl -------------------------------------------------------------------------- dnl -------------------------------------------------------------------------- dnl JK_DOMHOME dnl Set the Domino Home directory. dnl $1 => Domino Name dnl $2 => Domino VarName dnl $3 => File which should be present dnl -------------------------------------------------------------------------- AC_DEFUN( [JK_DOMHOME], [ tempval="" AC_MSG_CHECKING([for $1 location]) AC_ARG_WITH( [$1], [ --with-$1=DIR Location of $1 ], [ case "${withval}" in ""|"yes"|"YES"|"true"|"TRUE") ;; "no"|"NO"|"false"|"FALSE") AC_MSG_ERROR(valid $1 location required) ;; *) tempval="${withval}" if ${TEST} ! -d ${tempval} ; then AC_MSG_ERROR(Not a directory: ${tempval}) fi if ${TEST} ! -f ${tempval}/$3; then AC_MSG_ERROR(can't locate ${tempval}/$3) fi ;; esac ]) if ${TEST} -z "$tempval" ; then AC_MSG_RESULT(not provided) else [$2]=${tempval} AC_MSG_RESULT(${[$2]}) fi unset tempval ]) dnl vi:set sts=2 sw=2 autoindent: tomcat-connectors-1.2.41-src/support/jk_java.m40000644000000000000020000001463511107344437017713 0ustar rootbindnl dnl Licensed to the Apache Software Foundation (ASF) under one or more dnl contributor license agreements. See the NOTICE file distributed with dnl this work for additional information regarding copyright ownership. dnl The ASF licenses this file to You under the Apache License, Version 2.0 dnl (the "License"); you may not use this file except in compliance with dnl the License. You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl dnl -------------------------------------------------------------------------- dnl Author Henri Gomez dnl dnl Inspired by Pier works on webapp m4 macros :) dnl dnl Version $Id: jk_java.m4 714101 2008-11-14 18:53:19Z rjung $ dnl -------------------------------------------------------------------------- dnl -------------------------------------------------------------------------- dnl JK_JDK dnl dnl Detection of JDK location and Java Platform (1.1, 1.2, 1.3, 1.4) dnl result goes in JAVA_HOME / JAVA_PLATFORM (1 -> 1.1, 2 -> 1.2 and higher) dnl dnl -------------------------------------------------------------------------- AC_DEFUN( [JK_JNI], [ AC_ARG_WITH(jni, [ --with-jni Build jni support], [ case "${withval}" in y | yes | true) use_jni=true ;; n | no | false) use_jni=false ;; *) use_jni=true ;; esac if ${TEST} "${use_jni}" = "true"; then HAVE_JNI="-DHAVE_JNI" JNI_BUILD="jni-build" fi ]) ]) AC_DEFUN( [JK_JDK], [ if ${TEST} "${use_jni}" = "true"; then tempval="" AC_MSG_CHECKING([for JDK location (please wait)]) if ${TEST} -n "${JAVA_HOME}" ; then JAVA_HOME_ENV="${JAVA_HOME}" else JAVA_HOME_ENV="" fi JAVA_HOME="" JAVA_PLATFORM="" AC_ARG_WITH( [java-home], [ --with-java-home=DIR Location of JDK directory.], [ # This stuff works if the command line parameter --with-java-home was # specified, so it takes priority rightfully. tempval=${withval} if ${TEST} ! -d "${tempval}" ; then AC_MSG_ERROR(Not a directory: ${tempval}) fi JAVA_HOME=${tempval} AC_MSG_RESULT(${JAVA_HOME}) ], [ # This works if the parameter was NOT specified, so it's a good time # to see what the enviroment says. # Since Sun uses JAVA_HOME a lot, we check it first and ignore the # JAVA_HOME, otherwise just use whatever JAVA_HOME was specified. if ${TEST} -n "${JAVA_HOME_ENV}" ; then JAVA_HOME=${JAVA_HOME_ENV} AC_MSG_RESULT(${JAVA_HOME_ENV} from environment) fi ]) if ${TEST} -z "${JAVA_HOME}" ; then # Oh well, nobody set neither JAVA_HOME nor JAVA_HOME, have to guess # The following code is based on the code submitted by Henner Zeller # for ${srcdir}/src/scripts/package/rpm/ApacheJServ.spec # Two variables will be set as a result: # # JAVA_HOME # JAVA_PLATFORM AC_MSG_CHECKING([Try to guess JDK location]) for JAVA_PREFIX in /usr/local /usr/local/lib /usr /usr/lib /opt /usr/java ; do for JAVA_PLATFORM in 4 3 2 1 ; do for subversion in .9 .8 .7 .6 .5 .4 .3 .2 .1 "" ; do for VARIANT in IBMJava2- java java- jdk jdk-; do GUESS="${JAVA_PREFIX}/${VARIANT}1.${JAVA_PLATFORM}${subversion}" dnl AC_MSG_CHECKING([${GUESS}]) if ${TEST} -d "${GUESS}/bin" & ${TEST} -d "${GUESS}/include" ; then JAVA_HOME="${GUESS}" AC_MSG_RESULT([${GUESS}]) break fi done if ${TEST} -n "${JAVA_HOME}" ; then break; fi done if ${TEST} -n "${JAVA_HOME}" ; then break; fi done if ${TEST} -n "${JAVA_HOME}" ; then break; fi done if ${TEST} ! -n "${JAVA_HOME}" ; then AC_MSG_ERROR(can't locate a valid JDK location) fi fi if ${TEST} -n "${JAVA_PLATFORM}"; then AC_MSG_RESULT(Java Platform detected - 1.${JAVA_PLATFORM}) else AC_MSG_CHECKING(Java platform) fi AC_ARG_WITH(java-platform, [ --with-java-platform[=2] Force the Java platform (value is 1 for 1.1.x or 2 for 1.2.x or greater)], [ case "${withval}" in "1"|"2") JAVA_PLATFORM=${withval} ;; *) AC_MSG_ERROR(invalid java platform provided) ;; esac ], [ if ${TEST} -n "${JAVA_PLATFORM}"; then AC_MSG_RESULT(Java Platform detected - 1.${JAVA_PLATFORM}) else AC_MSG_CHECKING(Java platform) fi ]) AC_MSG_RESULT(${JAVA_PLATFORM}) unset tempval else # no jni, then make sure JAVA_HOME is not picked up from env JAVA_HOME="" JAVA_PLATFORM="" fi ]) AC_DEFUN( [JK_JDK_OS], [ if ${TEST} "${use_jni}" = "true"; then tempval="" OS="" AC_ARG_WITH(os-type, [ --with-os-type[=SUBDIR] Location of JDK os-type subdirectory.], [ tempval=${withval} if ${TEST} ! -d "${JAVA_HOME}/${tempval}" ; then AC_MSG_ERROR(Not a directory: ${JAVA_HOME}/${tempval}) fi OS = ${tempval} ], [ AC_MSG_CHECKING(os_type directory) if ${TEST} -f ${JAVA_HOME}/include/jni_md.h; then OS="" else for f in ${JAVA_HOME}/include/*/jni_md.h; do if ${TEST} -f $f; then OS=`dirname ${f}` OS=`basename ${OS}` echo " ${OS}" fi done if ${TEST} -z "${OS}"; then AC_MSG_RESULT(Cannot find jni_md.h in ${JAVA_HOME}/${OS}) AC_MSG_ERROR(You should retry --with-os-type=SUBDIR) fi fi ]) fi ]) dnl vi:set sts=2 sw=2 autoindent: tomcat-connectors-1.2.41-src/support/jk_exec.m40000644000000000000020000000550611237120030017674 0ustar rootbindnl dnl Licensed to the Apache Software Foundation (ASF) under one or more dnl contributor license agreements. See the NOTICE file distributed with dnl this work for additional information regarding copyright ownership. dnl The ASF licenses this file to You under the Apache License, Version 2.0 dnl (the "License"); you may not use this file except in compliance with dnl the License. You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl dnl -------------------------------------------------------------------------- dnl dnl Inspired by Pier works on webapp m4 macros :) dnl dnl Version $Id: jk_exec.m4 802231 2009-08-07 21:43:52Z markt $ dnl -------------------------------------------------------------------------- dnl -------------------------------------------------------------------------- dnl JK_EXEC dnl Execute a program filtering its output (pretty printing). dnl dnl Parameters: dnl $1 => name of the variable containing the return value (error code). dnl $2 => name of the binary/script to invoke dnl $3 => message used for pretty printing output dnl $4 => the directory where the command must be executed dnl -------------------------------------------------------------------------- AC_DEFUN( [JK_EXEC], [ jk_exec_curdir="`pwd`" if test -d "$4" ; then cd "$4" else AC_MSG_ERROR([can't switch to directory $4]) fi echo " invoking \"$2\"" echo " in directory \"$4\"" echo "-1" > retvalue.tmp set $2 jk_exec_file=[$]1 if test ! -x "${jk_exec_file}" ; then cd "${jk_exec_curdir}" AC_MSG_ERROR([cannot find or execute \"${jk_exec_file}\" in \"$4\"]) exit 1 fi unset jk_exec_file { $2 echo echo "jk_exec_retvalue $?" } | { jk_exec_ret=0 while true ; do read jk_exec_first jk_exec_line if test ! "$?" -eq "0" ; then break else if test "${jk_exec_first}" = "jk_exec_retvalue" ; then jk_exec_ret="${jk_exec_line}" else if test -n "${jk_exec_line}" ; then echo " $3: ${jk_exec_first} ${jk_exec_line}" fi fi fi done echo "${jk_exec_ret}" > retvalue.tmp unset jk_exec_first unset jk_exec_line unset jk_exec_ret } $1="`cat retvalue.tmp`" rm -f retvalue.tmp echo " execution of \"$2\"" echo " returned with value \"${$1}\"" cd "${jk_exec_curdir}" unset jk_exec_curdir ]) tomcat-connectors-1.2.41-src/support/jk_ws.m40000644000000000000020000001537610516516102017417 0ustar rootbindnl dnl Licensed to the Apache Software Foundation (ASF) under one or more dnl contributor license agreements. See the NOTICE file distributed with dnl this work for additional information regarding copyright ownership. dnl The ASF licenses this file to You under the Apache License, Version 2.0 dnl (the "License"); you may not use this file except in compliance with dnl the License. You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl dnl -------------------------------------------------------------------------- dnl Author Henri Gomez dnl dnl Inspired by Pier works on webapp m4 macros :) dnl dnl Version $Id: jk_ws.m4 466585 2006-10-21 22:16:34Z markt $ dnl -------------------------------------------------------------------------- dnl -------------------------------------------------------------------------- dnl JK_WS_DIR dnl Set the WebServer source dir. dnl $1 => Webserver name dnl $2 => Webserver vars prefix name dnl $3 => File which should be present dnl $4 => Server specific source directory dnl -------------------------------------------------------------------------- AC_DEFUN( [JK_WS_DIR], [ tempval="" AC_ARG_WITH( [$1], [ --with-$1=DIR Location of $1 source dir ], [ case "${withval}" in ""|"yes"|"YES"|"true"|"TRUE") AC_MSG_ERROR(valid $1 source dir location required) ;; "no"|"NO"|"false"|"FALSE") AC_MSG_ERROR(Don't use with/without $1 if you don't have $1) ;; *) tempval="${withval}" if ${TEST} ! -d ${tempval} ; then AC_MSG_ERROR(Not a directory: ${tempval}) fi if ${TEST} ! -f ${tempval}/$3; then AC_MSG_ERROR(can't locate ${tempval}/$3) fi if ${TEST} ! -z "$tempval" ; then $2_BUILD="true" $2_CFLAGS="-I ${tempval}/include" $2_DIR=${tempval} $2_HOME="${tempval}" $2_LIBDIR="" if ${TEST} -d ${withval}/include ; then $2_INCL="-I${tempval}/include" $2_INCDIR="${tempval}/include" fi if ${TEST} -d ${withval}/src/include ; then # read osdir from the existing apache. osdir=`${GREP} '^OSDIR=' ${withval}/src/Makefile.config | ${SED} -e 's:^OSDIR=.*/os:os:'` if ${TEST} -z "${osdir}" ; then osdir=os/unix fi $2_INCL="-I${tempval}/src/include -I${withval}/src/${osdir}" $2_INCDIR="${tempval}/src/include" fi if ${TEST} -d ${tempval}/srclib/apr ; then # Apache 2 contains apr. if ${TEST} ! -f ${tempval}/srclib/apr/config.status ; then AC_MSG_ERROR(configure Apache2 before mod_jk2) fi osdir=`${GREP} @OSDIR@ ${tempval}/srclib/apr/config.status | sed 's:s,@OSDIR@,::' | sed 's:,;t t::'` $2_INCL="-I${tempval}/include -I${withval}/os/${osdir}" $2_LIBEXEC=`${GREP} "^exp_libexecdir =" ${tempval}/build/config_vars.mk | sed 's:exp_libexecdir = ::'` LIBTOOL=${tempval}/srclib/apr/libtool APR_INCDIR=-I${tempval}/srclib/apr/include APR_CFLAGS=`${tempval}/srclib/apr/apr-config --cflags` APR_UTIL_INCDIR=-I${tempval}/srclib/apr-util/include APR_LIBDIR_LA=`${tempval}/srclib/apr/apr-config --apr-la-file` $2_LIBDIR=${tempval}/lib AC_SUBST(APR_INCDIR) AC_SUBST(APR_CFLAGS) AC_SUBST(APR_INCDIR) AC_SUBST(APR_UTIL_INCDIR) fi $2_LDFLAGS="" WEBSERVERS="${WEBSERVERS} $4" AC_SUBST($2_BUILD) AC_SUBST($2_CFLAGS) AC_SUBST($2_DIR) AC_SUBST($2_HOME) AC_SUBST($2_INCL) AC_SUBST($2_INCDIR) AC_SUBST($2_LDFLAGS) AC_SUBST($2_LIBDIR) fi ;; esac ]) if ${TEST} -z "$tempval" ; then AC_MSG_RESULT(not provided) else AC_MSG_RESULT(${tempval}) fi unset tempval ]) dnl -------------------------------------------------------------------------- dnl JK_WS_INCDIR dnl Set the WebServer include dir. dnl $1 => Webserver name dnl $2 => Webserver vars prefix name dnl $3 => File which should be present dnl -------------------------------------------------------------------------- AC_DEFUN( [JK_WS_INCDIR], [ tempval="" AC_ARG_WITH( [$1-include], [ --with-$1-include=DIR Location of $1 include dir ], [ case "${withval}" in ""|"yes"|"YES"|"true"|"TRUE") ;; "no"|"NO"|"false"|"FALSE") AC_MSG_ERROR(valid $1 include dir location required) ;; *) tempval="${withval}" if ${TEST} ! -d ${tempval} ; then AC_MSG_ERROR(Not a directory: ${tempval}) fi if ${TEST} ! -f ${tempval}/$3; then AC_MSG_ERROR(can't locate ${tempval}/$3) fi if ${TEST} ! -z "$tempval" ; then $2_BUILD="" $2_CFLAGS="-I${tempval}" $2_CLEAN="" $2_DIR="" $2_INCDIR=${tempval} AC_MSG_RESULT($2_INCDIR) AC_SUBST($2_BUILD) AC_SUBST($2_CFLAGS) AC_SUBST($2_CLEAN) AC_SUBST($2_DIR) AC_SUBST($2_INCDIR) fi ;; esac ]) unset tempval ]) dnl -------------------------------------------------------------------------- dnl JK_WS_LIBDIR dnl Set the WebServer library dir. dnl $1 => Webserver name dnl $2 => Webserver vars prefix name dnl -------------------------------------------------------------------------- AC_DEFUN( [JK_WS_LIBDIR], [ tempval="" AC_ARG_WITH( [$1-lib], [ --with-$1-lib=DIR Location of $1 lib dir ], [ case "${withval}" in ""|"yes"|"YES"|"true"|"TRUE") ;; "no"|"NO"|"false"|"FALSE") AC_MSG_ERROR(valid $1 lib directory location required) ;; *) tempval="${withval}" if ${TEST} ! -d ${tempval} ; then AC_MSG_ERROR(Not a directory: ${tempval}) fi if ${TEST} ! -z "$tempval" ; then $2_BUILD="" $2_CLEAN="" $2_DIR="" $2_LIBDIR=${tempval} $2_LDFLAGS="" AC_MSG_RESULT($2_LIBDIR) AC_SUBST($2_BUILD) AC_SUBST($2_CLEAN) AC_SUBST($2_DIR) AC_SUBST($2_LIBDIR) AC_SUBST($2_LDFLAGS) fi ;; esac ]) unset tempval ]) dnl vi:set sts=2 sw=2 autoindent: tomcat-connectors-1.2.41-src/support/get_ver.awk0000644000000000000020000000571510666607673020217 0ustar rootbinBEGIN { # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # fetch mod_jk version numbers from input file and writes them to STDOUT while ((getline < ARGV[1]) > 0) { if (match ($0, /^#define JK_VERMAJOR [^"]+/)) { jk_ver_major = substr($3, 1, length($3)); } else if (match ($0, /^#define JK_VERMINOR [^"]+/)) { jk_ver_minor = substr($3, 1, length($3)); } else if (match ($0, /^#define JK_VERFIX [^"]+/)) { jk_ver_fix = substr($3, 1, length($3)); } else if (match ($0, /^#define JK_VERISRELEASE [^"]+/)) { jk_ver_isrelease = substr($3, 1, length($3)); } else if (match ($0, /^#define JK_VERBETA [^"]+/)) { jk_ver_isbeta = substr($3, 1, length($3)); } else if (match ($0, /^#define JK_BETASTRING [^"]+/)) { jk_ver_betastr = substr($3, 2, length($3) - 2); } } jk_ver = jk_ver_major "," jk_ver_minor "," jk_ver_fix; jk_ver_str = jk_ver_major "." jk_ver_minor "." jk_ver_fix; if (jk_ver_isrelease != 1) { jk_ver_str = jk_ver_str "-dev"; } if (jk_ver_isbeta == 1) { jk_ver_str = jk_ver_str "-beta-" jk_ver_betastr; } # fetch Apache version numbers from input file and writes them to STDOUT if (ARGV[2]) { if (match (ARGV[2], /ap_release.h/)) { while ((getline < ARGV[2]) > 0) { if (match ($0, /^#define AP_SERVER_MAJORVERSION "[^"]+"/)) { ap_ver_major = substr($3, 2, length($3) - 2); } else if (match ($0, /^#define AP_SERVER_MINORVERSION "[^"]+"/)) { ap_ver_minor = substr($3, 2, length($3) - 2); } else if (match ($0, /^#define AP_SERVER_PATCHLEVEL/)) { ap_ver_str_patch = substr($3, 2, length($3) - 2); if (match (ap_ver_str_patch, /[0-9][0-9]*/)) { ap_ver_patch = substr(ap_ver_str_patch, RSTART, RLENGTH); } } } ap_ver_str = ap_ver_major "." ap_ver_minor "." ap_ver_str_patch; } if (match (ARGV[2], /httpd.h/)) { while ((getline < ARGV[2]) > 0) { if (match ($0, /^#define SERVER_BASEREVISION "[^"]+"/)) { ap_ver_str = substr($3, 2, length($3) - 2); } } } print "AP_VERSION_STR = " ap_ver_str ""; } print "JK_VERSION = " jk_ver ""; print "JK_VERSION_STR = " jk_ver_str ""; } tomcat-connectors-1.2.41-src/support/apache.m40000644000000000000020000001436010666607673017537 0ustar rootbindnl dnl Licensed to the Apache Software Foundation (ASF) under one or more dnl contributor license agreements. See the NOTICE file distributed with dnl this work for additional information regarding copyright ownership. dnl The ASF licenses this file to You under the Apache License, Version 2.0 dnl (the "License"); you may not use this file except in compliance with dnl the License. You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl dnl dnl apache.m4: autoconf macro for Apache/apxs dnl dnl dnl check for apxs. dnl AC_DEFUN(JTC_CHECK_APXS,[ WEBSERVER="" apache_dir="" apache_include="" APXS="apxs" AC_ARG_WITH(apxs, [ --with-apxs[=FILE] Build shared Apache module. FILE is the optional pathname to the apxs tool; defaults to finding apxs in your PATH.], [ case "${withval}" in y | yes | true) find_apxs=true ;; n | no | false) find_apxs=false ;; *) find_apxs=false ;; esac if ${TEST} ${find_apxs} ; then AC_MSG_RESULT([need to check for Perl first, apxs depends on it...]) AC_PATH_PROG(PERL,perl,$PATH)dnl if ${TEST} ${find_apxs} ; then APXS=${withval} else AC_PATH_PROG(APXS,apxs,$PATH)dnl fi if ${TEST} -n "${APXS}" ; then dnl Seems that we have it, but have to check if it is OK first if ${TEST} ! -x "${APXS}" ; then AC_MSG_ERROR(Invalid location for apxs: '${APXS}') fi $APXS -q PREFIX >/dev/null 2>/dev/null || apxs_support=false if ${TEST} "${apxs_support}" = "false" ; then AC_MSG_RESULT(could not find apxs) AC_MSG_ERROR(You must specify a valid --with-apxs path) fi dnl test apache version $RM -rf test $APXS -n test -g APA=`grep STANDARD20 test/mod_test.c` $RM -rf test if ${TEST} -z "$APA" ; then WEBSERVER="apache-1.3" else WEBSERVER="apache-2.0" fi AC_MSG_RESULT([building connector for \"$WEBSERVER\"]) AC_SUBST(APXS) dnl apache_dir and apache_include are also needed. apache_dir=`$APXS -q PREFIX` apache_include="-I`$APXS -q INCLUDEDIR`" fi fi ], [ AC_MSG_RESULT(no apxs given) ]) ])dnl dnl dnl check for apache (static link). dnl AC_DEFUN(JTC_CHECK_APACHE,[ dnl it is copied from the configure of JServ ;=) dnl and adapted. apache_dir_is_src="false" AC_ARG_WITH(apache, [ --with-apache=DIR Build static Apache module. DIR is the pathname to the Apache source directory.], [ if ${TEST} ! -z "$WEBSERVER" ; then AC_MSG_ERROR([Sorry cannot use --with-apxs=${APXS} and --with-apache=${withval} togother, please choose one of both]) fi AC_MSG_CHECKING([for Apache source directory (assume static build)]) if ${TEST} -n "${withval}" && ${TEST} -d "${withval}" ; then if ${TEST} -d "${withval}/src" ; then # handle the case where people use relative paths to # the apache source directory by pre-pending the current # build directory to the path. there are probably # errors with this if configure is run while in a # different directory than what you are in at the time if ${TEST} -n "`${ECHO} ${withval}|${GREP} \"^\.\.\"`" ; then withval=`pwd`/${withval} fi apache_dir=${withval} apache_dir_is_src="true" AC_MSG_RESULT(${apache_dir}) AC_MSG_CHECKING(for Apache include directory) if ${TEST} -d "${withval}/src/include" ; then # read osdir from the existing apache. osdir=`${GREP} '^OSDIR=' ${withval}/src/Makefile.config | ${SED} -e 's:^OSDIR=.*/os:os:'` if ${TEST} -z "${osdir}" ; then osdir=os/unix fi apache_include="-I${withval}/src/include \ -I${withval}/src/${osdir}" WEBSERVER="apache-1.3" AC_MSG_RESULT([${apache_include}, version 1.3]) else AC_MSG_ERROR([Sorry Apache 1.2.x is no longer supported.]) fi else if ${TEST} -d "${withval}/include" ; then # osdir for Apache20. WEBSERVER="apache-2.0" apache_dir=${withval} apache_dir_is_src="true" AC_MSG_RESULT(${apache_dir}) fi fi fi dnl Make sure we have a result. if ${TEST} -z "$WEBSERVER" ; then AC_MSG_ERROR([Directory $apache_dir is not a valid Apache source distribution]) fi # VT: Now, which one I'm supposed to use? Let's figure it out later configure_apache=true configure_src=true AC_MSG_RESULT([building connector for \"$WEBSERVER\"]) ], [ AC_MSG_RESULT(no apache given) ]) AC_SUBST(apache_include) APACHE_DIR=${apache_dir} AC_SUBST(APACHE_DIR) ]) dnl dnl check for EAPI (static link only). dnl AC_DEFUN(JTC_CHECK_EAPI,[ dnl CFLAGS for EAPI mod_ssl (Apache 1.3) dnl it also allows the CFLAGS environment variable. CFLAGS="${CFLAGS}" AC_ARG_ENABLE( EAPI, [ --enable-EAPI Enable EAPI support (mod_ssl, Apache 1.3)], [ case "${enableval}" in y | Y | YES | yes | TRUE | true ) CFLAGS="${CFLAGS} -DEAPI" AC_MSG_RESULT([...Enabling EAPI Support...]) ;; esac ]) AC_SUBST(CFLAGS) ]) dnl dnl set flags for apxs. dnl AC_DEFUN(JTC_SET_APXS_FLAGS,[ dnl the APXSCFLAGS is given by apxs to the C compiler dnl the APXSLDFLAGS is given to the linker (for APRVARS). APXSLDFLAGS="" APXSCFLAGS="" if ${TEST} -n "${CFLAGS}" ; then APXSCFLAGS="${CFLAGS}" fi dnl the APXSLDFLAGS is normaly empty but APXSCFLAGS is not. if ${TEST} -n "${LDFLAGS}" ; then APXSLDFLAGS="-Wl,${LDFLAGS}" fi AC_SUBST(APXSCFLAGS) AC_SUBST(APXSLDFLAGS) ]) tomcat-connectors-1.2.41-src/support/jk_apache_static.m40000644000000000000020000001156510516516102021552 0ustar rootbindnl dnl Licensed to the Apache Software Foundation (ASF) under one or more dnl contributor license agreements. See the NOTICE file distributed with dnl this work for additional information regarding copyright ownership. dnl The ASF licenses this file to You under the Apache License, Version 2.0 dnl (the "License"); you may not use this file except in compliance with dnl the License. You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl dnl -------------------------------------------------------------------------- dnl Author Henri Gomez dnl dnl Inspired by Pier works on webapp m4 macros :) dnl dnl Version $Id: jk_apache_static.m4 466585 2006-10-21 22:16:34Z markt $ dnl -------------------------------------------------------------------------- dnl Apache-2.0 needs the os subdirectory to include os.h dnl this include is copy from os/config.m4 sinclude(os_apache.m4) dnl -------------------------------------------------------------------------- dnl JK_APACHE_STATIC dnl Set the APACHE 1.3/2.0 source dir. dnl $1 => apache source dir to detect ("", 2) dnl $2 => apache 1.3 build dir dnl $3 => apache 2.0 build dir dnl dnl -------------------------------------------------------------------------- AC_DEFUN( [JK_APACHE_STATIC], [ tempval="" AC_ARG_WITH( [apache$1], [ --with-apache$1=DIR Location of Apache$2 source dir], [ if ${TEST} ${use_apxs$1} ; then AC_MSG_ERROR([Sorry cannot use --with-apxs= and --with-apache= together, please choose one]) fi AC_MSG_CHECKING([for Apache source directory (assume static build)]) if ${TEST} -n "${withval}" && ${TEST} -d "${withval}" ; then if ${TEST} -d "${withval}/src" ; then # handle the case where people use relative paths to # the apache source directory by pre-pending the current # build directory to the path. there are probably # errors with this if configure is run while in a # different directory than what you are in at the time if ${TEST} -n "`${ECHO} ${withval}|${GREP} \"^\.\.\"`" ; then withval=`pwd`/${withval} fi APACHE$1_DIR=${withval} use_static="true" AC_MSG_RESULT(${APACHE$1_DIR}) AC_MSG_CHECKING(for Apache include directory) if ${TEST} -d "${withval}/src/include" ; then # read osdir from the existing apache. osdir=`${GREP} '^OSDIR=' ${withval}/src/Makefile.config | ${SED} -e 's:^OSDIR=.*/os:os:'` if ${TEST} -z "${osdir}" ; then osdir=os/unix fi APACHE$1_DIR=${withval} APACHE$1_HOME=${withval} APACHE$1_INCL="-I${withval}/src/include -I${withval}/src/${osdir}" EXTRA_CFLAGS="" EXTRA_CPPFLAGS="" REPORTED_SERVER="apache-1.3" SERVER_DIR="$3" use_static="true" use_apache13="true" AC_MSG_RESULT([${APACHE$1_INCL}, version 1.3]) else AC_MSG_ERROR([Sorry Apache 1.2.x is no longer supported.]) fi else if ${TEST} -d "${withval}/include" ; then # osdir for Apache20. APACHE$1_DIR=${withval} APACHE$1_HOME=${withval} APACHE$1_INCL="-I${withval}/include -I${withval}/srclib/apr/include -I${withval}/os/${OS_APACHE_DIR} -I${withval}/srclib/apr-util/include" EXTRA_CFLAGS="" EXTRA_CPPFLAGS="" REPORTED_SERVER="apache-2.0" SERVER_DIR="$3" use_static="true" use_apache2="true" APACHE$1_INCL="-I${withval}/include -I${withval}/srclib/apr/include -I${withval}/os/${OS_APACHE_DIR} -I${withval}/srclib/apr-util/include" AC_MSG_RESULT(${APACHE$1_DIR}) JK_CHANNEL_APR_SOCKET="\${JK}jk_channel_apr_socket\${OEXT}" JK_POOL_APR="\${JK}jk_pool_apr\${OEXT}" HAS_APR="-DHAS_APR" fi fi fi dnl Make sure we have a result. if ${TEST} -z "$WEBSERVER" ; then AC_MSG_ERROR([Directory $apache_dir is not a valid Apache source distribution]) fi # VT: Now, which one I'm supposed to use? Let's figure it out later configure_apache=true configure_src=true AC_MSG_RESULT([building connector for \"$WEBSERVER\"]) ], [ AC_MSG_RESULT(no apache$1 dir given) ]) dnl vi:set sts=2 sw=2 autoindent: tomcat-connectors-1.2.41-src/support/jk_apr.m40000644000000000000020000002366110516516102017544 0ustar rootbindnl dnl Licensed to the Apache Software Foundation (ASF) under one or more dnl contributor license agreements. See the NOTICE file distributed with dnl this work for additional information regarding copyright ownership. dnl The ASF licenses this file to You under the Apache License, Version 2.0 dnl (the "License"); you may not use this file except in compliance with dnl the License. You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl dnl -------------------------------------------------------------------------- dnl Author Henri Gomez dnl dnl Inspired by Pier works on webapp m4 macros :) dnl dnl Version $Id: jk_apr.m4 466585 2006-10-21 22:16:34Z markt $ dnl -------------------------------------------------------------------------- dnl -------------------------------------------------------------------------- dnl JK_APR_THREADS dnl Configure APR threading for use with --with-apr. dnl Result goes into APR_CONFIGURE_ARGS dnl -------------------------------------------------------------------------- AC_DEFUN( [JK_APR_THREADS], [ AC_ARG_ENABLE( [apr-threads], [ --enable-apr-threads Configure APR threading for use with --with-apr ], [ case "${enableval}" in ""|"yes"|"YES"|"true"|"TRUE") APR_CONFIGURE_ARGS="--enable-threads ${APR_CONFIGURE_ARGS}" ;; "no"|"NO"|"false"|"FALSE") APR_CONFIGURE_ARGS="--disable-threads ${APR_CONFIGURE_ARGS}" ;; *) APR_CONFIGURE_ARGS="--enable-threads=${enableval} ${APR_CONFIGURE_ARGS}" esac ]) ]) dnl -------------------------------------------------------------------------- dnl JK_APR dnl Set the APR source dir. dnl $1 => File which should be present dnl -------------------------------------------------------------------------- AC_DEFUN( [JK_APR], [ tempval="" AC_ARG_WITH( [apr], [ --with-apr=DIR Location of APR source dir ], [ case "${withval}" in ""|"yes"|"YES"|"true"|"TRUE") AC_MSG_ERROR(valid apr source dir location required) ;; "no"|"NO"|"false"|"FALSE") AC_MSG_ERROR(valid apr source dir location required) ;; *) tempval="${withval}" if ${TEST} ! -d ${tempval} ; then AC_MSG_ERROR(Not a directory: ${tempval}) fi if ${TEST} ! -f ${tempval}/$1; then AC_MSG_ERROR(can't locate ${tempval}/$1) fi if ${TEST} ! -z "$tempval" ; then APR_BUILD="apr-build" APR_CFLAGS="-I ${tempval}/include" APR_CLEAN="apr-clean" APR_DIR=${tempval} APR_INCDIR="${tempval}/include" AC_MSG_RESULT(configuring apr...) tempret="0" JK_EXEC( [tempret], [${SHELL} ./configure --prefix=${APR_DIR} --with-installbuilddir=${APR_DIR}/instbuild --disable-shared ${APR_CONFIGURE_ARGS}], [apr], [${APR_DIR}]) if ${TEST} "${tempret}" = "0"; then AC_MSG_RESULT(apr configure ok) else AC_MSG_ERROR(apr configure failed with ${tempret}) fi JK_APR_LIBNAME(apr_libname,${APR_DIR}) APR_LDFLAGS="${APR_DIR}/lib/${apr_libname}" APR_LIBDIR="" use_apr=true COMMON_APR_OBJECTS="\${COMMON_APR_OBJECTS}" fi ;; esac ]) unset tempret unset tempval unset apr_libname ]) dnl -------------------------------------------------------------------------- dnl JK_APR_UTIL dnl Set the APR-UTIL source dir. dnl $1 => File which should be present dnl -------------------------------------------------------------------------- AC_DEFUN( [JK_APR_UTIL], [ tempval="" AC_ARG_WITH( [apr-util], [ --with-apr-util=DIR Location of APR-UTIL source dir ], [ case "${withval}" in ""|"yes"|"YES"|"true"|"TRUE") AC_MSG_ERROR(valid apr-util source dir location required) ;; "no"|"NO"|"false"|"FALSE") AC_MSG_ERROR(valid apr-util source dir location required) ;; *) tempval="${withval}" if ${TEST} ! -d ${tempval} ; then AC_MSG_ERROR(Not a directory: ${tempval}) fi if ${TEST} ! -f ${tempval}/$1; then AC_MSG_ERROR(can't locate ${tempval}/$1) fi if ${TEST} -z "${APR_BUILD}"; then AC_MSG_ERROR([--with-apr and --with-apr-util must be used together]) fi if ${TEST} ! -z "$tempval" ; then APR_UTIL_DIR=${tempval} APR_CFLAGS="${APR_CFLAGS} -I ${APR_UTIL_DIR}/include" APR_UTIL_INCDIR="${APR_UTIL_DIR}/include" AC_MSG_RESULT(configuring apr-util...) tempret="0" JK_EXEC( [tempret], [${SHELL} ./configure --prefix=${APR_UTIL_DIR} --with-apr=${APR_DIR}], [apr-util], [${APR_UTIL_DIR}]) if ${TEST} "${tempret}" = "0"; then AC_MSG_RESULT(apr-util configure ok) else AC_MSG_ERROR(apr-util configure failed with ${tempret}) fi JK_APR_UTIL_LIBNAME(apr_util_libname,${APR_UTIL_DIR}) APR_LDFLAGS="${APR_LDFLAGS} ${APR_UTIL_DIR}/lib/${apr_util_libname}" APR_UTIL_LIBDIR="" use_apr=true COMMON_APR_OBJECTS="\${COMMON_APR_OBJECTS}" fi ;; esac ]) unset tempret unset tempval unset apr_util_libname ]) dnl -------------------------------------------------------------------------- dnl JK_APR_INCDIR dnl Set the APR include dir. dnl $1 => File which should be present dnl -------------------------------------------------------------------------- AC_DEFUN( [JK_APR_INCDIR], [ tempval="" AC_ARG_WITH( [apr-include], [ --with-apr-include=DIR Location of APR include dir ], [ case "${withval}" in ""|"yes"|"YES"|"true"|"TRUE") ;; "no"|"NO"|"false"|"FALSE") AC_MSG_ERROR(valid apr include dir location required) ;; *) tempval="${withval}" if ${TEST} ! -d ${tempval} ; then AC_MSG_ERROR(Not a directory: ${tempval}) fi if ${TEST} ! -f ${tempval}/$1; then AC_MSG_ERROR(can't locate ${tempval}/$1) fi if ${TEST} ! -z "$tempval" ; then APR_BUILD="" APR_CFLAGS="-I${tempval}" APR_CLEAN="" APR_DIR="" APR_INCDIR=${tempval} COMMON_APR_OBJECTS="\${COMMON_APR_OBJECTS}" use_apr=true fi ;; esac ]) unset tempval ]) dnl -------------------------------------------------------------------------- dnl JK_APR_LIBDIR dnl Set the APR library dir. dnl -------------------------------------------------------------------------- AC_DEFUN( [JK_APR_LIBDIR], [ tempval="" AC_ARG_WITH( [apr-lib], [ --with-apr-lib=DIR Location of APR lib dir ], [ case "${withval}" in ""|"yes"|"YES"|"true"|"TRUE") ;; "no"|"NO"|"false"|"FALSE") AC_MSG_ERROR(valid apr lib dir location required) ;; *) tempval="${withval}" if ${TEST} ! -d ${tempval} ; then AC_MSG_ERROR(Not a directory: ${tempval}) fi if ${TEST} ! -z "$tempval" ; then APR_BUILD="" APR_CLEAN="" APR_DIR="" APR_LIBDIR=${tempval} APR_LDFLAGS="`apr-config --link-ld` -L${tempval}" COMMON_APR_OBJECTS="\${COMMON_APR_OBJECTS}" use_apr=true fi ;; esac ]) unset tempval ]) dnl -------------------------------------------------------------------------- dnl JK_APR_LIBNAME dnl Retrieve the complete name of the library. dnl $1 => Environment variable name for the returned value dnl $2 => APR sources directory dnl -------------------------------------------------------------------------- AC_DEFUN( [JK_APR_LIBNAME], [ AC_MSG_CHECKING([for apr APR_LIBNAME]) if ${TEST} ! -f "$2/apr-config" ; then AC_MSG_ERROR([cannot find apr-config file in $2]) fi jk_apr_get_tempval=`$2/apr-config --link-libtool 2> /dev/null` if ${TEST} -z "${jk_apr_get_tempval}" ; then AC_MSG_ERROR([$2/apr-config --link-libtool failed]) fi jk_apr_get_tempval=`basename ${jk_apr_get_tempval}` $1="${jk_apr_get_tempval}" AC_MSG_RESULT([${jk_apr_get_tempval}]) unset jk_apr_get_tempval ]) dnl -------------------------------------------------------------------------- dnl JK_APR_UTIL_LIBNAME dnl Retrieve the complete name of the library. dnl $1 => Environment variable name for the returned value dnl $2 => APR_UTIL sources directory dnl -------------------------------------------------------------------------- AC_DEFUN( [JK_APR_UTIL_LIBNAME], [ AC_MSG_CHECKING([for apr-util APR_UTIL_LIBNAME]) if ${TEST} ! -f "$2/apu-config" ; then AC_MSG_ERROR([cannot find apu-config file in $2]) fi jk_apu_get_tempval=`$2/apu-config --link-libtool 2> /dev/null` if ${TEST} -z "${jk_apu_get_tempval}" ; then AC_MSG_ERROR([$2/apu-config --link-libtool failed]) fi jk_apu_get_tempval=`basename ${jk_apu_get_tempval}` $1="${jk_apu_get_tempval}" AC_MSG_RESULT([${jk_apu_get_tempval}]) unset jk_apu_get_tempval ]) dnl vi:set sts=2 sw=2 autoindent: tomcat-connectors-1.2.41-src/HOWTO-RELEASE.txt0000644000000000000020000001721312316341447017043 0ustar rootbin Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. How to do a mod_jk 1.2 Release ============================== Check out a clean copy of tomcat/connectors from subversion to make sure you don't have any lingering configure or build files. This will make sure that the source distribution created is clean. We assume, that you checked out http://svn.apache.org/repos/asf/tomcat/jk/trunk to a directory named mod_jk. All further path names will be relative to this directory. If you haven't already, add your public PGP key to KEYS. Add a preliminary note about the new release to the docs -------------------------------------------------------- Candidate pages are: xdocs/index.xml xdocs/news/.xml We can't add a final release date though. Update version numbers as needed -------------------------------- Do a find for all the docs which include the previous version string and replace it with the new version. These are the docs I found which had to be updated: native/iis/README native/netscape/README xdocs/index.xml xdocs/news/.xml tools/dist/README.html tools/dist/binaries/windows/README.html Check version numbers in the files that are listed in the section "Update source for next version" below: native/STATUS.txt native/configure.ac native/common/jk_version.h native/iis/installer/isapi-redirector-win32-msi.ism xdocs/miscellaneous/changelog.xml In native/STATUS.txt the current version stays labeled as "in development" during release. It is updated with release date after release process is completed. Update the JK_VERISRELEASE define in native/common/jk_version.h, here is a svn diff that shows what I changed: Index: native/common/jk_version.h =================================================================== --- native/common/jk_version.h (revision 417260) +++ native/common/jk_version.h (working copy) @@ -32,7 +32,7 @@ #define JK_VERBETA 0 #define JK_BETASTRING "0" /* set JK_VERISRELEASE to 1 when release (do not forget to commit!) */ -#define JK_VERISRELEASE 0 +#define JK_VERISRELEASE 1 #define JK_VERRC 0 #define JK_RCSTRING "0" After updating revision numbers, commit your changes to subversion. Tag and branch tomcat-connectors in subversion ---------------------------------------------- Use the pattern below for branching and tagging the tomcat-connectors directory. TAG=JK_{MAJOR_REVISION}_{MINOR_REVISION}_{RELEASE} svn copy \ https://svn.apache.org/repos/asf/tomcat/jk/trunk/ \ https://svn.apache.org/repos/asf/tomcat/jk/tags/TAG/ Here is an example for mod_jk 1.2.29 svn copy \ https://svn.apache.org/repos/asf/tomcat/jk/trunk/ \ https://svn.apache.org/repos/asf/tomcat/jk/tags/JK_1.2.29/ Build the mod_jk 1.2 documentation ---------------------------------- cd xdocs ant Check the documentation carefully (produced in build/docs) and copy it to people.apache.org:/x1/www/tomcat.apache.org/connectors-doc Create the new source distribution ---------------------------------- A tool named jkrelease.sh in the directory tools creates a release tarball and a zip including signature files. Upload source distribution and documentation to www.apache.org ------------------------------------------------------------------- First update the KEYS on the server if you have added a new pgp key. scp KEYS to the /www/www.apache.org/dist/tomcat/tomcat-connectors directory on the people.apache.org server. scp tomcat-connectors-1.2.29-src.tar.gz* to /www/www.apache.org/dist/tomcat/tomcat-connectors/jk/source scp tomcat-connectors-1.2.29-src.zip* to /www/www.apache.org/dist/tomcat/tomcat-connectors/jk/source ssh to people.apache.org and cd to the /www/www.apache.org/dist/tomcat/tomcat-connectors/jk directory. Modify README.html and update it to the current version. Remove the symlinks for current if present and replace them with a soft link to the new source distribution files. ln -s source/tomcat-connectors-1.2.29-src.tar.gz tomcat-connectors-src-current.tar.gz ln -s source/tomcat-connectors-1.2.29-src.tar.gz.asc tomcat-connectors-src-current.tar.gz.asc ln -s source/tomcat-connectors-1.2.29-src.tar.zip tomcat-connectors-src-current.zip ln -s source/tomcat-connectors-1.2.29-src.zip.asc tomcat-connectors-src-current.zip.asc Make sure the group write bit is set on all files and directories in the jk directory. chmod -R g+w /www/www.apache.org/dist/tomcat/tomcat-connectors/jk Build binaries and upload distributions to www.apache.org -------------------------------------------------------------- Build mod_jk for a specific web server and OS. Package it as appropriate for the OS and sign the archive using PGP. Please include the ASF License, the generated docs, and the tools. Please name the distribuiton as follows: tomcat-connectors-{version}-{os-version-cpu}-{web server-version}.(tar.gz|zip) scp the binary distribution and pgp signature file to the appropriate binaries/{os} directory. Make sure the group write bit is on for all files you upload. Update source for next version ------------------------------ native/STATUS.txt: Add release date for released version and status "in development" for new version. native/configure.ac: Update version in AC_INIT macro. native/common/jk_version.h: Update variables JK_VERMAJOR, JK_VERMINOR, JK_VERFIX, JK_VERSTRING, and JK_VERISRELEASE. native/iis/installer/isapi-redirector-win32-msi.ism: Update ProductVersion. xdocs/miscellaneous/changelog.xml: Start a new section for the new version. Remove old release distributions from www.apache.org ---------------------------------------------------- Verify that the old versions of the source and binary distributions are available at /www/archive.apache.org/dist/tomcat/tomcat-connectors/jk . Copy old source distributions and binaries as needed, then remove the old source and binary distributions. Arrange the downloads_tomcat-connectors.cgi ------------------------------------------- Check tomcat-site out: svn co https://svn.apache.org/repos/asf/tomcat/site site-tomcat Arrange the file: xdocs/download-connectors.xml, updating all occurrences of the version number to the just released version. Update xdocs/index.xml to reflect the new release of Tomcat Connectors. Run ant from the site-tomcat directory to regenerate the corresponding html file: docs/site/download-connectors.html Commit it after checking carefully the changes. Connect to people.apache.org and update the tomcat.apache.org site image, the site tomcat.apache.org should reflect the change after a while: cd /x1/www/tomcat.apache.org/site/downloads svn update downloads_tomcat-connectors.html Announcements ------------- The release distribution directories are mirrored so that the releases can be downloaded from multiple sites. Please wait 24 hours before sending out the announcement so that the mirrors get a chance to get the new release distributions. Send an email announcement to announce@tomcat.apache.org, users@tomcat.apache.org, dev@tomcat.apache.org and announce@apache.org. tomcat-connectors-1.2.41-src/NOTICE0000644000000000000020000000041512451224326015220 0ustar rootbinApache Tomcat Connectors Copyright 2002-2015 The Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). This software contains code derived from UNIX V7, Copyright(C) Caldera International Inc. tomcat-connectors-1.2.41-src/native/0000755000000000000020000000000012555256563015617 5ustar rootbintomcat-connectors-1.2.41-src/native/apache-2.0/0000755000000000000020000000000012555256552017333 5ustar rootbintomcat-connectors-1.2.41-src/native/apache-2.0/mod_jk.dsp0000644000000000000020000002541311660226064021302 0ustar rootbin# Microsoft Developer Studio Project File - Name="mod_jk" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=mod_jk - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "mod_jk.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 "mod_jk.mak" CFG="mod_jk - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "mod_jk - Win32 Release httpd 2.0" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "mod_jk - Win32 Debug httpd 2.0" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "mod_jk - Win32 Release httpd 2.2" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "mod_jk - Win32 Debug httpd 2.2" (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)" == "mod_jk - Win32 Release httpd 2.0" # 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 /Zi /O2 /Oy- /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c # ADD CPP /nologo /MD /W3 /Zi /O2 /Oy- /I "..\common" /I "$(APACHE2_HOME)\include" /I "$(APACHE2_HOME)\srclib\apr\include" /I "$(APACHE2_HOME)\srclib\apr-util\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_APR" /Fd"Release/mod_jk_src" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /fo"Release/mod_jk.res" /I "..\common" /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /dll /machine:I386 # ADD LINK32 libhttpd.lib libapr.lib libaprutil.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /base:"0x6A6B0000" /subsystem:windows /dll /debug /machine:I386 /out:"Release/mod_jk.so" /libpath:"$(APACHE2_HOME)\Release" /libpath:"$(APACHE2_HOME)\srclib\apr\Release" /libpath:"$(APACHE2_HOME)\srclib\apr-util\Release" /libpath:"$(APACHE2_HOME)\lib" /opt:ref !ELSEIF "$(CFG)" == "mod_jk - Win32 Debug httpd 2.0" # 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 /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c # ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "..\common" /I "$(APACHE2_HOME)\include" /I "$(APACHE2_HOME)\srclib\apr\include" /I "$(APACHE2_HOME)\srclib\apr-util\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_APR" /Fd"Debug/mod_jk_src" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /fo"Debug/mod_jk.res" /I "..\common" /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 libhttpd.lib libapr.lib libaprutil.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /base:"0x6A6B0000" /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_jk.so" /libpath:"$(APACHE2_HOME)/Debug" /libpath:"$(APACHE2_HOME)\srclib\apr\Debug" /libpath:"$(APACHE2_HOME)\srclib\apr-util\Debug" /libpath:"$(APACHE2_HOME)\lib" !ELSEIF "$(CFG)" == "mod_jk - Win32 Release httpd 2.2" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release22" # PROP BASE Intermediate_Dir "Release22" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release22" # PROP Intermediate_Dir "Release22" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MD /W3 /Zi /O2 /Oy- /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c # ADD CPP /nologo /MD /W3 /Zi /O2 /Oy- /I "..\common" /I "$(APACHE2_HOME)\include" /I "$(APACHE2_HOME)\srclib\apr\include" /I "$(APACHE2_HOME)\srclib\apr-util\include" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_APR" /Fd"Release22/mod_jk_src" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /fo"Release22/mod_jk.res" /I "..\common" /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib advapi32.lib /nologo /dll /machine:I386 # ADD LINK32 libhttpd.lib libapr-1.lib libaprutil-1.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /base:"0x6A6B0000" /subsystem:windows /dll /debug /machine:I386 /out:"Release22/mod_jk.so" /libpath:"$(APACHE2_HOME)\Release" /libpath:"$(APACHE2_HOME)\srclib\apr\Release" /libpath:"$(APACHE2_HOME)\srclib\apr-util\Release" /libpath:"$(APACHE2_HOME)\lib" /opt:ref !ELSEIF "$(CFG)" == "mod_jk - Win32 Debug httpd 2.2" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug22" # PROP BASE Intermediate_Dir "Debug22" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug22" # PROP Intermediate_Dir "Debug22" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FD /c # ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "..\common" /I "$(APACHE2_HOME)\include" /I "$(APACHE2_HOME)\srclib\apr\include" /I "$(APACHE2_HOME)\srclib\apr-util\include" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "HAVE_APR" /Fd"Debug22/mod_jk_src" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /fo"Debug22/mod_jk.res" /I "..\common" /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 libhttpd.lib libapr-1.lib libaprutil-1.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /base:"0x6A6B0000" /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug22/mod_jk.so" /libpath:"$(APACHE2_HOME)/Debug" /libpath:"$(APACHE2_HOME)\srclib\apr\Debug" /libpath:"$(APACHE2_HOME)\srclib\apr-util\Debug" /libpath:"$(APACHE2_HOME)\lib" !ENDIF # Begin Target # Name "mod_jk - Win32 Release httpd 2.0" # Name "mod_jk - Win32 Debug httpd 2.0" # Name "mod_jk - Win32 Release httpd 2.2" # Name "mod_jk - Win32 Debug httpd 2.2" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\common\jk_ajp12_worker.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp13.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp13_worker.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp14.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp14_worker.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp_common.c # End Source File # Begin Source File SOURCE=..\common\jk_connect.c # End Source File # Begin Source File SOURCE=..\common\jk_context.c # End Source File # Begin Source File SOURCE=..\common\jk_lb_worker.c # End Source File # Begin Source File SOURCE=..\common\jk_map.c # End Source File # Begin Source File SOURCE=..\common\jk_md5.c # End Source File # Begin Source File SOURCE=..\common\jk_msg_buff.c # End Source File # Begin Source File SOURCE=..\common\jk_pool.c # End Source File # Begin Source File SOURCE=..\common\jk_shm.c # End Source File # Begin Source File SOURCE=..\common\jk_sockbuf.c # End Source File # Begin Source File SOURCE=..\common\jk_status.c # End Source File # Begin Source File SOURCE=..\common\jk_uri_worker_map.c # End Source File # Begin Source File SOURCE=..\common\jk_url.c # End Source File # Begin Source File SOURCE=..\common\jk_util.c # End Source File # Begin Source File SOURCE=..\common\jk_worker.c # End Source File # Begin Source File SOURCE=.\mod_jk.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=..\common\jk_ajp12_worker.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp13.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp13_worker.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp14.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp14_worker.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp23_worker.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp_common.h # End Source File # Begin Source File SOURCE=..\common\jk_connect.h # End Source File # Begin Source File SOURCE=..\common\jk_context.h # End Source File # Begin Source File SOURCE=..\common\jk_global.h # End Source File # Begin Source File SOURCE=..\common\jk_lb_worker.h # End Source File # Begin Source File SOURCE=..\common\jk_logger.h # End Source File # Begin Source File SOURCE=..\common\jk_map.h # End Source File # Begin Source File SOURCE=..\common\jk_md5.h # End Source File # Begin Source File SOURCE=..\common\jk_msg_buff.h # End Source File # Begin Source File SOURCE=..\common\jk_mt.h # End Source File # Begin Source File SOURCE=..\common\jk_pool.h # End Source File # Begin Source File SOURCE=..\common\jk_service.h # End Source File # Begin Source File SOURCE=..\common\jk_shm.h # End Source File # Begin Source File SOURCE=..\common\jk_sockbuf.h # End Source File # Begin Source File SOURCE=..\common\jk_status.h # End Source File # Begin Source File SOURCE=..\common\jk_uri_worker_map.h # End Source File # Begin Source File SOURCE=..\common\jk_url.h # End Source File # Begin Source File SOURCE=..\common\jk_util.h # End Source File # Begin Source File SOURCE=..\common\jk_worker.h # End Source File # 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.rc # End Source File # End Group # End Target # End Project tomcat-connectors-1.2.41-src/native/apache-2.0/bldjk.qclsrc0000644000000000000020000002250511660660436021632 0ustar rootbinPGM CRTCMOD MODULE(MOD_JK/MOD_JK) + SRCSTMF('/home/apache/jk/native/apache-2.0/mod_jk.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('mod_jk.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_AJP_COM) + SRCSTMF('/home/apache/jk/native/common/jk_ajp_common.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_ajp_common.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_AJP12_W) + SRCSTMF('/home/apache/jk/native/common/jk_ajp12_worker.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_ajp12_worker.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_AJP13) + SRCSTMF('/home/apache/jk/native/common/jk_ajp13.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_ajp13.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_AJP13_W) + SRCSTMF('/home/apache/jk/native/common/jk_ajp13_worker.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_ajp13_worker.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_AJP14) + SRCSTMF('/home/apache/jk/native/common/jk_ajp14.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_ajp14.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_AJP14_W) + SRCSTMF('/home/apache/jk/native/common/jk_ajp14_worker.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_ajp14_worker.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_CONNECT) + SRCSTMF('/home/apache/jk/native/common/jk_connect.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT' 'USE_SO_RCVTIMEO' + 'USE_SO_SNDTIMEO' ) + TEXT('jk_connect.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_CONTEXT) + SRCSTMF('/home/apache/jk/native/common/jk_context.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_context.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_LB_WORK) + SRCSTMF('/home/apache/jk/native/common/jk_lb_worker.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_lb_worker.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_MAP) + SRCSTMF('/home/apache/jk/native/common/jk_map.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_map.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_MD5) + SRCSTMF('/home/apache/jk/native/common/jk_md5.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_md5.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_MSG_BUF) + SRCSTMF('/home/apache/jk/native/common/jk_msg_buff.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_msg_buff.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_POOL) + SRCSTMF('/home/apache/jk/native/common/jk_pool.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_pool.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_SOCKBUF) + SRCSTMF('/home/apache/jk/native/common/jk_sockbuf.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_sockbuf.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_URI_W_M) + SRCSTMF('/home/apache/jk/native/common/jk_uri_worker_map.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_uri_worker_map.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_URL) + SRCSTMF('/home/apache/jk/native/common/jk_url.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_url.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_UTIL) + SRCSTMF('/home/apache/jk/native/common/jk_util.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_util.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_WORKER) + SRCSTMF('/home/apache/jk/native/common/jk_worker.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_worker.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_STATUS) + SRCSTMF('/home/apache/jk/native/common/jk_status.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_status.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_SHM) + SRCSTMF('/home/apache/jk/native/common/jk_shm.c') + DEFINE('AS400' 'HAVE_APR' '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_shm.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALE) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTSRVPGM SRVPGM(MOD_JK/MOD_JK) + MODULE(MOD_JK/MOD_JK + MOD_JK/JK_AJP_COM MOD_JK/JK_AJP12_W + MOD_JK/JK_AJP13 MOD_JK/JK_AJP13_W + MOD_JK/JK_AJP14 MOD_JK/JK_AJP14_W + MOD_JK/JK_CONNECT MOD_JK/JK_CONTEXT + MOD_JK/JK_LB_WORK + MOD_JK/JK_MAP MOD_JK/JK_MD5 + MOD_JK/JK_MSG_BUF MOD_JK/JK_POOL + MOD_JK/JK_SOCKBUF MOD_JK/JK_URI_W_M + MOD_JK/JK_URL + MOD_JK/JK_UTIL MOD_JK/JK_WORKER + MOD_JK/JK_STATUS MOD_JK/JK_SHM) + EXPORT(*SRCFILE) + BNDDIR() + TGTRLS(*CURRENT) + SRCFILE(MOD_JK/QSRVSRC) + SRCMBR(MOD_JK) + USRPRF(*USER) + BNDSRVPGM(QHTTPSVR/QZSRAPR QHTTPSVR/QZSRCORE + QHTTPSVR/QZSRXMLP QHTTPSVR/QZSRSDBM) + TEXT('Apache Tomcat mod_jk connector module') ENDPGM tomcat-connectors-1.2.41-src/native/apache-2.0/NWGNUmakefile0000644000000000000020000001431711660656133021653 0ustar rootbin# # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # # NetWare Makefile for mod_jk (uses build system of Apache 2.x - gnu make) # created by Guenter Knauf # # # Declare the sub-directories to be built here # SUBDIRS = \ $(EOLIST) # # Get the 'head' of the build environment. This includes default targets and # paths to tools # include $(AP_WORK)/build/NWGNUhead.inc # # build this level's files # # Make sure all needed macro's are defined # JKCOMMON = ../common # # These directories will be at the beginning of the include list, followed by # INCDIRS # XINCDIRS += \ $(JKCOMMON) \ $(APR)/include \ $(APRUTIL)/include \ $(AP_WORK)/include \ $(NWOS) \ $(EOLIST) # # These flags will come after CFLAGS # XCFLAGS += \ $(EOLIST) # # These defines will come after DEFINES # XDEFINES += \ -D__NOVELL_LIBC__ \ -D_POSIX_SOURCE \ $(EOLIST) # # These flags will be added to the link.opt file # XLFLAGS += \ $(EOLIST) # # These values will be appended to the correct variables based on the value of # RELEASE # ifeq "$(RELEASE)" "debug" XINCDIRS += \ $(EOLIST) XCFLAGS += \ $(EOLIST) XDEFINES += \ $(EOLIST) XLFLAGS += \ $(EOLIST) endif ifeq "$(RELEASE)" "noopt" XINCDIRS += \ $(EOLIST) XCFLAGS += \ $(EOLIST) XDEFINES += \ $(EOLIST) XLFLAGS += \ $(EOLIST) endif ifeq "$(RELEASE)" "release" XINCDIRS += \ $(EOLIST) XCFLAGS += \ $(EOLIST) XDEFINES += \ $(EOLIST) XLFLAGS += \ $(EOLIST) endif # # These are used by the link target if an NLM is being generated # This is used by the link 'name' directive to name the nlm. If left blank # TARGET_nlm (see below) will be used. # NLM_NAME = mod_jk # # This is used by the link '-desc ' directive. # If left blank, NLM_NAME will be used. # NLM_DESCRIPTION = Apache $(VERSION_STR) plugin for Tomcat $(JK_VERSION_STR) # # This is used by the link '-copy ' directive. # If left blank, the ASF copyright defined in NWGNUtail.inc will be used. # NLM_COPYRIGHT = # # This is used by the '-threadname' directive. If left blank, # NLM_NAME Thread will be used. # NLM_THREAD_NAME = JK Module # # If this is specified, it will override VERSION value in # $(AP_WORK)\build\NWGNUenvironment.inc # NLM_VERSION = $(JK_VERSION) # # If this is specified, it will override the default of 64K # NLM_STACK_SIZE = 49152 # # If this is specified it will be used by the link '-entry' directive # NLM_ENTRY_SYM = _LibCPrelude # # If this is specified it will be used by the link '-exit' directive # NLM_EXIT_SYM = _LibCPostlude # # If this is specified it will be used by the link '-check' directive # NLM_CHECK_SYM = # # If these are specified it will be used by the link '-flags' directive # NLM_FLAGS = AUTOUNLOAD, PSEUDOPREEMPTION # # If this is specified it will be linked in with the XDCData option in the def # file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled # by setting APACHE_UNIPROC in the environment # XDCDATA = # # If there is an NLM target, put it here # TARGET_nlm = \ $(OBJDIR)/$(NLM_NAME).nlm \ $(EOLIST) # # If there is an LIB target, put it here # TARGET_lib = \ $(EOLIST) # # These are the OBJ files needed to create the NLM target above. # Paths must all use the '/' character # FILES_nlm_objs = \ $(OBJDIR)/jk_nwmain.o \ $(OBJDIR)/jk_ajp12_worker.o \ $(OBJDIR)/jk_ajp13.o \ $(OBJDIR)/jk_ajp13_worker.o \ $(OBJDIR)/jk_ajp14.o \ $(OBJDIR)/jk_ajp14_worker.o \ $(OBJDIR)/jk_ajp_common.o \ $(OBJDIR)/jk_connect.o \ $(OBJDIR)/jk_context.o \ $(OBJDIR)/jk_lb_worker.o \ $(OBJDIR)/jk_map.o \ $(OBJDIR)/jk_md5.o \ $(OBJDIR)/jk_msg_buff.o \ $(OBJDIR)/jk_pool.o \ $(OBJDIR)/jk_shm.o \ $(OBJDIR)/jk_sockbuf.o \ $(OBJDIR)/jk_status.o \ $(OBJDIR)/jk_uri_worker_map.o \ $(OBJDIR)/jk_url.o \ $(OBJDIR)/jk_util.o \ $(OBJDIR)/jk_worker.o \ $(OBJDIR)/mod_jk.o \ $(EOLIST) # # These are the LIB files needed to create the NLM target above. # These will be added as a library command in the link.opt file. # FILES_nlm_libs = \ $(NOVELLLIBC)/imports/libcpre.o \ $(EOLIST) # # These are the modules that the above NLM target depends on to load. # These will be added as a module command in the link.opt file. # FILES_nlm_modules = \ aprlib \ libc \ $(EOLIST) # # If the nlm has a msg file, put it's path here # FILE_nlm_msg = # # If the nlm has a hlp file put it's path here # FILE_nlm_hlp = # # If this is specified, it will override $(NWOS)\copyright.txt. # FILE_nlm_copyright = # # Any additional imports go here # FILES_nlm_Ximports = \ @aprlib.imp \ @httpd.imp \ @libc.imp \ @ws2nlm.imp \ $(EOLIST) # # Any symbols exported to here # FILES_nlm_exports = \ jk_module \ $(EOLIST) # # These are the OBJ files needed to create the LIB target above. # Paths must all use the '/' character # FILES_lib_objs = \ $(EOLIST) # # implement targets and dependancies (leave this section alone) # libs :: $(OBJDIR) $(TARGET_lib) nlms :: libs $(TARGET_nlm) # # Updated this target to create necessary directories and copy files to the # correct place. (See $(AP_WORK)\build\NWGNUhead.inc for examples) # install :: nlms FORCE copy $(OBJDIR)\*.nlm $(INSTALL)\Apache2\modules\*.* # # Any specialized rules here # vpath %.c $(JKCOMMON) $(OBJDIR)/version.inc: $(JKCOMMON)/jk_version.h $(OBJDIR) @echo Creating $@ @awk -f ../../support/get_ver.awk $< > $@ # # Include the version info retrieved from jk_version.h # -include $(OBJDIR)/version.inc # # Include the 'tail' makefile that has targets that depend on variables defined # in this makefile # include $(AP_WORK)/build/NWGNUtail.inc tomcat-connectors-1.2.41-src/native/apache-2.0/mod_jk.c0000644000000000000020000044006012470732025020734 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Apache 2 plugin for Tomcat * * Author: Gal Shachor * * Henri Gomez * * Version: $Revision: 1660504 $ * ***************************************************************************/ /* * mod_jk: keeps all servlet related ramblings together. */ #include "ap_config.h" #include "apr_lib.h" #include "apr_date.h" #include "apr_file_info.h" #include "apr_file_io.h" #include "httpd.h" #include "http_config.h" #include "http_request.h" #include "http_core.h" #include "http_protocol.h" #include "http_main.h" #include "http_log.h" #include "util_script.h" #include "ap_mpm.h" #if defined(AS400) && !defined(AS400_UTF8) #include "ap_charset.h" #include "util_charset.h" /* ap_hdrs_from_ascii */ #endif /* deprecated with apr 0.9.3 */ #include "apr_version.h" #if (APR_MAJOR_VERSION == 0) && \ (APR_MINOR_VERSION <= 9) && \ (APR_PATCH_VERSION < 3) #define apr_filepath_name_get apr_filename_of_pathname #endif #include "apr_strings.h" /* Yes; sorta sucks - with luck we will clean this up before httpd-2.2 * ships, leaving AP_NEED_SET_MUTEX_PERMS def'd as 1 or 0 on all platforms. */ #ifdef AP_NEED_SET_MUTEX_PERMS # define JK_NEED_SET_MUTEX_PERMS AP_NEED_SET_MUTEX_PERMS #else /* A special case for httpd-2.0 */ # if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE) && !defined(AS400) # define JK_NEED_SET_MUTEX_PERMS 1 # else # define JK_NEED_SET_MUTEX_PERMS 0 # endif #endif #if JK_NEED_SET_MUTEX_PERMS #include "unixd.h" /* for unixd_set_global_mutex_perms */ #endif /* * jk_ include files */ #ifdef NETWARE #define __sys_types_h__ #define __sys_socket_h__ #define __netdb_h__ #define __netinet_in_h__ #define __arpa_inet_h__ #define __sys_timeval_h__ #endif #include "jk_global.h" #include "jk_ajp13.h" #include "jk_logger.h" #include "jk_map.h" #include "jk_pool.h" #include "jk_service.h" #include "jk_uri_worker_map.h" #include "jk_util.h" #include "jk_worker.h" #include "jk_shm.h" #include "jk_url.h" #define JK_LOG_DEF_FILE ("logs/mod_jk.log") #define JK_SHM_DEF_FILE ("logs/jk-runtime-status") #define JK_ENV_REMOTE_ADDR ("JK_REMOTE_ADDR") #define JK_ENV_REMOTE_PORT ("JK_REMOTE_PORT") #define JK_ENV_REMOTE_HOST ("JK_REMOTE_HOST") #define JK_ENV_REMOTE_USER ("JK_REMOTE_USER") #define JK_ENV_AUTH_TYPE ("JK_AUTH_TYPE") #define JK_ENV_LOCAL_NAME ("JK_LOCAL_NAME") #define JK_ENV_LOCAL_ADDR ("JK_LOCAL_ADDR") #define JK_ENV_LOCAL_PORT ("JK_LOCAL_PORT") #define JK_ENV_IGNORE_CL ("JK_IGNORE_CL") #define JK_ENV_HTTPS ("HTTPS") #define JK_ENV_SSL_PROTOCOL ("SSL_PROTOCOL") #define JK_ENV_CERTS ("SSL_CLIENT_CERT") #define JK_ENV_CIPHER ("SSL_CIPHER") #define JK_ENV_SESSION ("SSL_SESSION_ID") #define JK_ENV_KEY_SIZE ("SSL_CIPHER_USEKEYSIZE") #define JK_ENV_CERTCHAIN_PREFIX ("SSL_CLIENT_CERT_CHAIN_") #define JK_ENV_REPLY_TIMEOUT ("JK_REPLY_TIMEOUT") #define JK_ENV_STICKY_IGNORE ("JK_STICKY_IGNORE") #define JK_ENV_STATELESS ("JK_STATELESS") #define JK_ENV_ROUTE ("JK_ROUTE") #define JK_ENV_WORKER_NAME ("JK_WORKER_NAME") #define JK_NOTE_WORKER_NAME ("JK_WORKER_NAME") #define JK_NOTE_WORKER_TYPE ("JK_WORKER_TYPE") #define JK_NOTE_REQUEST_DURATION ("JK_REQUEST_DURATION") #define JK_NOTE_WORKER_ROUTE ("JK_WORKER_ROUTE") #define JK_HANDLER ("jakarta-servlet") #define JK_MAGIC_TYPE ("application/x-jakarta-servlet") #define NULL_FOR_EMPTY(x) ((x && !strlen(x)) ? NULL : x) #define STRNULL_FOR_NULL(x) ((x) ? (x) : "(null)") #define JK_LOG_LOCK_KEY ("jk_log_lock_key") #define JKLOG_MARK __FILE__,__LINE__ /* * If you are not using SSL, comment out the following line. It will make * apache run faster. * * Personally, I (DM), think this may be a lie. */ #define ADD_SSL_INFO /* Needed for Apache 2.3/2.4 per-module log config */ #ifdef APLOG_USE_MODULE APLOG_USE_MODULE(jk); #endif /* module MODULE_VAR_EXPORT jk_module; */ AP_MODULE_DECLARE_DATA module jk_module; /* * Environment variable forward object */ typedef struct { int has_default; char *name; char *value; } envvar_item; /* * Configuration object for the mod_jk module. */ typedef struct { /* * Log stuff */ char *log_file; int log_level; jk_logger_t *log; /* * Mount stuff */ char *mount_file; int mount_file_reload; jk_map_t *uri_to_context; int mountcopy; jk_uri_worker_map_t *uw_map; int was_initialized; /* * Automatic context path apache alias */ char *alias_dir; /* * Request Logging */ char *stamp_format_string; char *format_string; apr_array_header_t *format; /* * Setting target worker via environment */ char *worker_indicator; /* * Configurable environment variables to overwrite * request information using meta data send by a * proxy in front of us. */ char *remote_addr_indicator; char *remote_port_indicator; char *remote_host_indicator; char *remote_user_indicator; char *auth_type_indicator; char *local_name_indicator; char *local_addr_indicator; char *local_port_indicator; /* * Configurable environment variable to force * ignoring a request Content-Length header * (useful to make mod_deflate request inflation * compatible with mod_jk). */ char *ignore_cl_indicator; /* * SSL Support */ int ssl_enable; char *https_indicator; char *ssl_protocol_indicator; char *certs_indicator; char *cipher_indicator; char *session_indicator; /* Servlet API 2.3 requirement */ char *key_size_indicator; /* Servlet API 2.3 requirement */ char *certchain_prefix; /* Client certificate chain prefix */ /* * Jk Options */ int options; int exclude_options; int strip_session; char *strip_session_name; /* * Environment variables support */ int envvars_has_own; apr_table_t *envvars; apr_table_t *envvars_def; apr_array_header_t *envvar_items; server_rec *s; } jk_server_conf_t; /* * Request specific configuration */ struct jk_request_conf { rule_extension_t *rule_extensions; int jk_handled; }; typedef struct jk_request_conf jk_request_conf_t; struct apache_private_data { jk_pool_t p; int read_body_started; request_rec *r; }; typedef struct apache_private_data apache_private_data_t; static server_rec *main_server = NULL; static jk_logger_t *main_log = NULL; static apr_hash_t *jk_log_fps = NULL; static jk_worker_env_t worker_env; static apr_global_mutex_t *jk_log_lock = NULL; static char *jk_shm_file = NULL; static int jk_shm_size = 0; static int jk_shm_size_set = 0; static volatile int jk_watchdog_interval = 0; static volatile int jk_watchdog_running = 0; /* * Worker stuff */ static jk_map_t *jk_worker_properties = NULL; static char *jk_worker_file = NULL; static int jk_mount_copy_all = JK_FALSE; static int JK_METHOD ws_start_response(jk_ws_service_t *s, int status, const char *reason, const char *const *header_names, const char *const *header_values, unsigned num_of_headers); static int JK_METHOD ws_read(jk_ws_service_t *s, void *b, unsigned len, unsigned *actually_read); static int init_jk(apr_pool_t * pconf, jk_server_conf_t * conf, server_rec * s); static int JK_METHOD ws_write(jk_ws_service_t *s, const void *b, unsigned l); static void JK_METHOD ws_add_log_items(jk_ws_service_t *s, const char *const *log_names, const char *const *log_values, unsigned num_of_log_items); static void * JK_METHOD ws_next_vhost(void *d); static void JK_METHOD ws_vhost_to_text(void *d, char *buf, size_t len); static jk_uri_worker_map_t * JK_METHOD ws_vhost_to_uw_map(void *d); /* ========================================================================= */ /* JK Service step callbacks */ /* ========================================================================= */ static int JK_METHOD ws_start_response(jk_ws_service_t *s, int status, const char *reason, const char *const *header_names, const char *const *header_values, unsigned num_of_headers) { unsigned h; apache_private_data_t *p = s->ws_private; request_rec *r = p->r; /* If we use proxy error pages, still pass * through context headers needed for special status codes. */ if (s->extension.use_server_error_pages && status >= s->extension.use_server_error_pages) { if (status == HTTP_UNAUTHORIZED) { int found = JK_FALSE; for (h = 0; h < num_of_headers; h++) { if (!strcasecmp(header_names[h], "WWW-Authenticate")) { char *tmp = apr_pstrdup(r->pool, header_values[h]); apr_table_set(r->err_headers_out, "WWW-Authenticate", tmp); found = JK_TRUE; } } if (found == JK_FALSE) { jk_server_conf_t *xconf = (jk_server_conf_t *) ap_get_module_config(r->server->module_config, &jk_module); jk_log(xconf->log, JK_LOG_INFO, "origin server sent 401 without" " WWW-Authenticate header"); } } return JK_TRUE; } /* If there is no reason given (or an empty one), * we'll try to guess a good one. */ if (!reason || *reason == '\0') { /* We ask Apache httpd about a good reason phrase. */ reason = ap_get_status_line(status); /* Unfortunately it returns with a 500 reason phrase, * whenever it does not know about the given status code, * e.g. in the case of custom status codes. */ if (status != 500 && !strncmp(reason, "500 ", 4)) { reason = "Unknown Reason"; } else { /* Apache httpd returns a full status line, * but we only want a reason phrase, so skip * the prepended status code. */ reason = reason + 4; } } r->status = status; r->status_line = apr_psprintf(r->pool, "%d %s", status, reason); for (h = 0; h < num_of_headers; h++) { if (!strcasecmp(header_names[h], "Content-type")) { char *tmp = apr_pstrdup(r->pool, header_values[h]); ap_content_type_tolower(tmp); /* It should be done like this in Apache 2.0 */ /* This way, Apache 2.0 will be able to set the output filter */ /* and it make jk useable with deflate using */ /* AddOutputFilterByType DEFLATE text/html */ ap_set_content_type(r, tmp); } else if (!strcasecmp(header_names[h], "Location")) { #if defined(AS400) && !defined(AS400_UTF8) /* Fix escapes in Location Header URL */ ap_fixup_escapes((char *)header_values[h], strlen(header_values[h]), ap_hdrs_from_ascii); #endif apr_table_set(r->headers_out, header_names[h], header_values[h]); } else if (!strcasecmp(header_names[h], "Content-Length")) { ap_set_content_length(r, apr_atoi64(header_values[h])); } else if (!strcasecmp(header_names[h], "Transfer-Encoding")) { apr_table_set(r->headers_out, header_names[h], header_values[h]); } else if (!strcasecmp(header_names[h], "Last-Modified")) { /* * If the script gave us a Last-Modified header, we can't just * pass it on blindly because of restrictions on future values. */ ap_update_mtime(r, apr_date_parse_http(header_values[h])); ap_set_last_modified(r); } else { apr_table_add(r->headers_out, header_names[h], header_values[h]); } } /* this NOP function was removed in apache 2.0 alpha14 */ /* ap_send_http_header(r); */ s->response_started = JK_TRUE; return JK_TRUE; } /* * 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. * * Think of this function as a method of the apache1.3-specific subclass of * the jk_ws_service class. Think of the *s param as a "this" or "self" * pointer. */ static int JK_METHOD ws_read(jk_ws_service_t *s, void *b, unsigned len, unsigned *actually_read) { if (s && s->ws_private && b && actually_read) { apache_private_data_t *p = s->ws_private; if (!p->read_body_started) { if (ap_should_client_block(p->r)) { p->read_body_started = JK_TRUE; } } if (p->read_body_started) { #if defined(AS400) && !defined(AS400_UTF8) int long rv = OK; if (rv = ap_change_request_body_xlate(p->r, 65535, 65535)) { /* turn off request body translation */ ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_CRIT, 0, NULL, "mod_jk: Error on ap_change_request_body_xlate, rc=%d", rv); return JK_FALSE; } #else long rv; #endif if ((rv = ap_get_client_block(p->r, b, len)) < 0) { *actually_read = 0; } else { *actually_read = (unsigned)rv; } return JK_TRUE; } } return JK_FALSE; } static void JK_METHOD ws_flush(jk_ws_service_t *s) { #if ! (defined(AS400) && !defined(AS400_UTF8)) if (s && s->ws_private) { apache_private_data_t *p = s->ws_private; ap_rflush(p->r); } #endif } static void JK_METHOD ws_done(jk_ws_service_t *s) { #if ! (defined(AS400) && !defined(AS400_UTF8)) if (s && s->ws_private) { apache_private_data_t *p = s->ws_private; ap_finalize_request_protocol(p->r); } #endif } /* * Write a chunk of response data back to the browser. If the headers * haven't yet been sent over, send over default header values (Status = * 200, basically). * * Write len bytes from buffer b. * * Think of this function as a method of the apache1.3-specific subclass of * the jk_ws_service class. Think of the *s param as a "this" or "self" * pointer. */ static int JK_METHOD ws_write(jk_ws_service_t *s, const void *b, unsigned int l) { #if defined(AS400) && !defined(AS400_UTF8) int rc; #endif if (s && s->ws_private && b) { apache_private_data_t *p = s->ws_private; if (l) { /* BUFF *bf = p->r->connection->client; */ int r = 0; int ll = l; const char *bb = (const char *)b; if (!s->response_started) { if (main_log) jk_log(main_log, JK_LOG_INFO, "Write without start, starting with defaults"); if (!s->start_response(s, 200, NULL, NULL, NULL, 0)) { return JK_FALSE; } } if (p->r->header_only) { #if ! (defined(AS400) && !defined(AS400_UTF8)) ap_rflush(p->r); #endif return JK_TRUE; } #if defined(AS400) && !defined(AS400_UTF8) /* turn off response body translation */ rc = ap_change_response_body_xlate(p->r, 65535, 65535); if (rc) { ap_log_error(APLOG_MARK, APLOG_STARTUP | APLOG_CRIT, 0, NULL, "mod_jk: Error on ap_change_response_body_xlate, rc=%d", rc); return JK_FALSE; } #endif while (ll > 0 && !p->r->connection->aborted) { r = ap_rwrite(bb, ll, p->r); if (JK_IS_DEBUG_LEVEL(main_log)) jk_log(main_log, JK_LOG_DEBUG, "written %d out of %d", r, ll); if (r < 0) return JK_FALSE; ll -= r; bb += r; } if (ll && p->r->connection->aborted) { /* Fail if there is something left to send and * the connection was aborted by the client */ return JK_FALSE; } } return JK_TRUE; } return JK_FALSE; } static void JK_METHOD ws_add_log_items(jk_ws_service_t *s, const char *const *log_names, const char *const *log_values, unsigned num_of_log_items) { unsigned h; apache_private_data_t *p = s->ws_private; request_rec *r = p->r; for (h = 0; h < num_of_log_items; h++) { if (log_names[h] && log_values[h]) { apr_table_set(r->notes, log_names[h], log_values[h]); } } } static void * JK_METHOD ws_next_vhost(void *d) { server_rec *s = (server_rec *)d; if (s == NULL) return main_server; return s->next; } static void JK_METHOD ws_vhost_to_text(void *d, char *buf, size_t len) { server_rec *s = (server_rec *)d; size_t used = 0; if (s->server_hostname) { used += strlen(s->server_hostname); } if (!s->is_virtual) { if (s->port) used += strlen(":XXXXX"); } else if (s->addrs) { used += strlen(" ["); if (s->addrs->virthost) used += strlen(s->addrs->virthost); if (s->addrs->host_port) used += strlen(":XXXXX"); used += strlen("]"); } if (len < used && len > strlen("XXX")) { strcpy(buf, "XXX"); return; } used = 0; if (s->server_hostname) { strcpy(buf + used, s->server_hostname); used += strlen(s->server_hostname); } if (!s->is_virtual) { if (s->port) { sprintf(buf + used, ":%hu", s->port); used = strlen(buf); } } else if (s->addrs) { strcpy(buf + used, " ["); used += strlen(" ["); if (s->addrs->virthost) { strcpy(buf + used, s->addrs->virthost); used += strlen(s->addrs->virthost); } if (s->addrs->host_port) { sprintf(buf + used, ":%hu", s->addrs->host_port); used = strlen(buf); } strcpy(buf + used, "]"); used += strlen("]"); } } static jk_uri_worker_map_t * JK_METHOD ws_vhost_to_uw_map(void *d) { server_rec *s = (server_rec *)d; jk_server_conf_t *conf = NULL; if (s == NULL) return NULL; conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); return conf->uw_map; } /* ========================================================================= */ /* Utility functions */ /* ========================================================================= */ static void dump_options(server_rec *srv, apr_pool_t *p) { char server_name[80]; jk_server_conf_t *conf = (jk_server_conf_t *)ap_get_module_config(srv->module_config, &jk_module); int options = conf->options; ws_vhost_to_text(srv, server_name, 80); if (options & JK_OPT_FWDURICOMPAT) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardURICompat", server_name, JK_OPT_DEFAULT & JK_OPT_FWDURICOMPAT ? " (default)" : ""); if (options & JK_OPT_FWDURICOMPATUNPARSED) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardURICompatUnparsed", server_name, JK_OPT_DEFAULT & JK_OPT_FWDURICOMPATUNPARSED ? " (default)" : ""); if (options & JK_OPT_FWDURIESCAPED) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardURIEscaped", server_name, JK_OPT_DEFAULT & JK_OPT_FWDURIESCAPED ? " (default)" : ""); if (options & JK_OPT_FWDURIPROXY) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardURIProxy", server_name, JK_OPT_DEFAULT & JK_OPT_FWDURIPROXY ? " (default)" : ""); if (options & JK_OPT_FWDDIRS) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardDirectories", server_name, JK_OPT_DEFAULT & JK_OPT_FWDDIRS ? " (default)" : ""); if (options & JK_OPT_FWDLOCAL) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardLocalAddress", server_name, JK_OPT_DEFAULT & JK_OPT_FWDLOCAL ? " (default)" : ""); if (options & JK_OPT_FWDPHYSICAL) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardPhysicalAddress", server_name, JK_OPT_DEFAULT & JK_OPT_FWDPHYSICAL ? " (default)" : ""); if (options & JK_OPT_FWDCERTCHAIN) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardSSLCertChain", server_name, JK_OPT_DEFAULT & JK_OPT_FWDCERTCHAIN ? " (default)" : ""); if (options & JK_OPT_FWDKEYSIZE) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardKeySize", server_name, JK_OPT_DEFAULT & JK_OPT_FWDKEYSIZE ? " (default)" : ""); if (options & JK_OPT_FLUSHPACKETS) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "FlushPackets", server_name, JK_OPT_DEFAULT & JK_OPT_FLUSHPACKETS ? " (default)" : ""); if (options & JK_OPT_FLUSHEADER) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "FlushHeader", server_name, JK_OPT_DEFAULT & JK_OPT_FLUSHEADER ? " (default)" : ""); if (options & JK_OPT_DISABLEREUSE) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "DisableReuse", server_name, JK_OPT_DEFAULT & JK_OPT_DISABLEREUSE ? " (default)" : ""); if (options & JK_OPT_REJECTUNSAFE) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "RejectUnsafeURI", server_name, JK_OPT_DEFAULT & JK_OPT_REJECTUNSAFE ? " (default)" : ""); if (options & JK_OPT_COLLAPSEALL) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "CollapseSlashesAll", server_name, JK_OPT_DEFAULT & JK_OPT_COLLAPSEALL ? " (default)" : ""); if (options & JK_OPT_COLLAPSENONE) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "CollapseSlashesNone", server_name, JK_OPT_DEFAULT & JK_OPT_COLLAPSENONE ? " (default)" : ""); if (options & JK_OPT_COLLAPSEUNMOUNT) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "CollapseSlashesUnmount", server_name, JK_OPT_DEFAULT & JK_OPT_COLLAPSEUNMOUNT ? " (default)" : ""); } /* ========================================================================= */ /* Log something to Jk log file then exit */ static void jk_error_exit(const char *file, int line, int level, const server_rec * s, apr_pool_t * p, const char *fmt, ...) { va_list ap; char *res; char *ch; va_start(ap, fmt); res = apr_pvsprintf(s->process->pool, fmt, ap); va_end(ap); /* Replace all format characters in the resulting message */ /* because we feed the message to ap_log_error(). */ ch = res; while (*ch) { if (*ch == '%') { *ch = '#'; } ch++; } #if (MODULE_MAGIC_NUMBER_MAJOR >= 20100606) ap_log_error(file, line, APLOG_MODULE_INDEX, level, 0, s, "%s", res); #else ap_log_error(file, line, level, 0, s, "%s", res); #endif if ( s ) { #if (MODULE_MAGIC_NUMBER_MAJOR >= 20100606) ap_log_error(file, line, APLOG_MODULE_INDEX, level, 0, NULL, "%s", res); #else ap_log_error(file, line, level, 0, NULL, "%s", res); #endif } /* Exit process */ exit(1); } static jk_uint64_t get_content_length(request_rec * r) { if (r->main == NULL || r->main == r) { char *lenp = (char *)apr_table_get(r->headers_in, "Content-Length"); if (lenp) { jk_uint64_t rc = 0; if (sscanf(lenp, "%" JK_UINT64_T_FMT, &rc) > 0 && rc > 0) { return rc; } } } return 0; } /* Retrieve string value from env var, use default if env var does not exist. */ static const char *get_env_string(request_rec *r, const char *def, char *env, int null_for_empty) { char *value = (char *)apr_table_get(r->subprocess_env, env); if (value) return null_for_empty ? NULL_FOR_EMPTY(value) : value; return null_for_empty ? NULL_FOR_EMPTY(def) : def; } /* Retrieve integer value from env var, use default if env var does not exist. */ static int get_env_int(request_rec *r, int def, char *env) { char *value = (char *)apr_table_get(r->subprocess_env, env); if (value) return atoi(value); return def; } static int init_ws_service(apache_private_data_t * private_data, jk_ws_service_t *s, jk_server_conf_t * conf) { int size; request_rec *r = private_data->r; char *ssl_temp = NULL; const char *reply_timeout = NULL; const char *sticky_ignore = NULL; const char *stateless = NULL; const char *route = NULL; rule_extension_t *e; jk_request_conf_t *rconf; /* Copy in function pointers (which are really methods) */ s->start_response = ws_start_response; s->read = ws_read; s->write = ws_write; s->flush = ws_flush; s->done = ws_done; s->add_log_items = ws_add_log_items; s->next_vhost = ws_next_vhost; s->vhost_to_text = ws_vhost_to_text; s->vhost_to_uw_map = ws_vhost_to_uw_map; s->auth_type = get_env_string(r, r->ap_auth_type, conf->auth_type_indicator, 1); s->remote_user = get_env_string(r, r->user, conf->remote_user_indicator, 1); s->protocol = r->protocol; s->remote_host = (char *)ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_HOST, NULL); s->remote_host = get_env_string(r, s->remote_host, conf->remote_host_indicator, 1); if (conf->options & JK_OPT_FWDLOCAL) { s->remote_addr = r->connection->local_ip; /* We don't know the client port of the backend connection. */ s->remote_port = "0"; } else { #if (MODULE_MAGIC_NUMBER_MAJOR >= 20111130) if (conf->options & JK_OPT_FWDPHYSICAL) { s->remote_addr = r->connection->client_ip; s->remote_port = apr_itoa(r->pool, r->connection->client_addr->port); } else { s->remote_addr = r->useragent_ip; s->remote_port = apr_itoa(r->pool, r->useragent_addr->port); } #else s->remote_addr = r->connection->remote_ip; s->remote_port = apr_itoa(r->pool, r->connection->remote_addr->port); #endif } s->remote_addr = get_env_string(r, s->remote_addr, conf->remote_addr_indicator, 1); s->remote_port = get_env_string(r, s->remote_port, conf->remote_port_indicator, 1); if (conf->options & JK_OPT_FLUSHPACKETS) s->flush_packets = 1; if (conf->options & JK_OPT_FLUSHEADER) s->flush_header = 1; rconf = (jk_request_conf_t *)ap_get_module_config(r->request_config, &jk_module); e = rconf->rule_extensions; if (e) { s->extension.reply_timeout = e->reply_timeout; s->extension.sticky_ignore = e->sticky_ignore; s->extension.stateless = e->stateless; s->extension.use_server_error_pages = e->use_server_error_pages; if (e->activation) { s->extension.activation = apr_palloc(r->pool, e->activation_size * sizeof(int)); memcpy(s->extension.activation, e->activation, e->activation_size * sizeof(int)); } if (e->fail_on_status_size > 0) { s->extension.fail_on_status_size = e->fail_on_status_size; s->extension.fail_on_status = apr_palloc(r->pool, e->fail_on_status_size * sizeof(int)); memcpy(s->extension.fail_on_status, e->fail_on_status, e->fail_on_status_size * sizeof(int)); } if (e->session_cookie) { s->extension.session_cookie = apr_pstrdup(r->pool, e->session_cookie); } if (e->session_path) { s->extension.session_path = apr_pstrdup(r->pool, e->session_path); } if (e->set_session_cookie) { s->extension.set_session_cookie = e->set_session_cookie; } if (e->session_cookie_path) { s->extension.session_cookie_path = apr_pstrdup(r->pool, e->session_cookie_path); } } reply_timeout = apr_table_get(r->subprocess_env, JK_ENV_REPLY_TIMEOUT); if (reply_timeout) { int r = atoi(reply_timeout); if (r >= 0) s->extension.reply_timeout = r; } sticky_ignore = apr_table_get(r->subprocess_env, JK_ENV_STICKY_IGNORE); if (sticky_ignore) { if (*sticky_ignore == '\0') { s->extension.sticky_ignore = JK_TRUE; } else { int r = atoi(sticky_ignore); if (r) { s->extension.sticky_ignore = JK_TRUE; } else { s->extension.sticky_ignore = JK_FALSE; } } } stateless = apr_table_get(r->subprocess_env, JK_ENV_STATELESS); if (stateless) { if (*stateless == '\0') { s->extension.stateless = JK_TRUE; } else { int r = atoi(stateless); if (r) { s->extension.stateless = JK_TRUE; } else { s->extension.stateless = JK_FALSE; } } } if (conf->options & JK_OPT_DISABLEREUSE) s->disable_reuse = 1; /* get route if known */ route = apr_table_get(r->subprocess_env, JK_ENV_ROUTE); if (route && *route) { s->route = route; } /* get server name */ s->server_name = get_env_string(r, (char *)ap_get_server_name(r), conf->local_name_indicator, 0); /* get the local IP address */ s->local_addr = get_env_string(r, r->connection->local_ip, conf->local_addr_indicator, 0); /* get the real port (otherwise redirect failed) */ /* XXX: use apache API for getting server port * * Pre 1.2.7 versions used: * s->server_port = r->connection->local_addr->port; */ s->server_port = get_env_int(r, ap_get_server_port(r), conf->local_port_indicator); #if ((AP_MODULE_MAGIC_AT_LEAST(20051115,4)) && !defined(API_COMPATIBILITY)) || (MODULE_MAGIC_NUMBER_MAJOR >= 20060905) s->server_software = (char *)ap_get_server_description(); #else s->server_software = (char *)ap_get_server_version(); #endif s->method = (char *)r->method; s->content_length = get_content_length(r); s->is_chunked = r->read_chunked; if (s->content_length > 0 && get_env_string(r, NULL, conf->ignore_cl_indicator, 0) != NULL) { s->content_length = 0; s->is_chunked = 1; } s->no_more_chunks = 0; #if defined(AS400) && !defined(AS400_UTF8) /* Get the query string that is not translated to EBCDIC */ s->query_string = ap_get_original_query_string(r); #else s->query_string = r->args; #endif /* * The 2.2 servlet spec errata says the uri from * HttpServletRequest.getRequestURI() should remain encoded. * [http://java.sun.com/products/servlet/errata_042700.html] * * We use JkOptions to determine which method to be used * * ap_escape_uri is the latest recommanded but require * some java decoding (in TC 3.3 rc2) * * unparsed_uri is used for strict compliance with spec and * old Tomcat (3.2.3 for example) * * uri is use for compatibilty with mod_rewrite with old Tomcats */ switch (conf->options & JK_OPT_FWDURIMASK) { case JK_OPT_FWDURICOMPATUNPARSED: s->req_uri = r->unparsed_uri; if (s->req_uri != NULL) { char *query_str = strchr(s->req_uri, '?'); if (query_str != NULL) { *query_str = 0; } } break; case JK_OPT_FWDURICOMPAT: s->req_uri = r->uri; break; case JK_OPT_FWDURIPROXY: size = 3 * (int)strlen(r->uri) + 1; s->req_uri = apr_palloc(r->pool, size); jk_canonenc(r->uri, s->req_uri, size); break; case JK_OPT_FWDURIESCAPED: s->req_uri = ap_escape_uri(r->pool, r->uri); break; default: return JK_FALSE; } if (conf->ssl_enable || conf->envvars) { ap_add_common_vars(r); if (conf->ssl_enable) { ssl_temp = (char *)apr_table_get(r->subprocess_env, conf->https_indicator); if (ssl_temp && !strcasecmp(ssl_temp, "on")) { s->is_ssl = JK_TRUE; s->ssl_cert = (char *)apr_table_get(r->subprocess_env, conf->certs_indicator); if (conf->options & JK_OPT_FWDCERTCHAIN) { const apr_array_header_t *t = apr_table_elts(r->subprocess_env); if (t && t->nelts) { int i; const apr_table_entry_t *elts = (const apr_table_entry_t *) t->elts; apr_array_header_t *certs = apr_array_make(r->pool, 1, sizeof(char *)); *(const char **)apr_array_push(certs) = s->ssl_cert; for (i = 0; i < t->nelts; i++) { if (!elts[i].key) continue; if (!strncasecmp(elts[i].key, conf->certchain_prefix, strlen(conf->certchain_prefix))) *(const char **)apr_array_push(certs) = elts[i].val; } s->ssl_cert = apr_array_pstrcat(r->pool, certs, '\0'); } } if (s->ssl_cert) { s->ssl_cert_len = (unsigned int)strlen(s->ssl_cert); if (JK_IS_DEBUG_LEVEL(conf->log)) { jk_log(conf->log, JK_LOG_DEBUG, "SSL client certificate (%d bytes): %s", s->ssl_cert_len, s->ssl_cert); } } s->ssl_protocol = (char *)apr_table_get(r->subprocess_env, conf->ssl_protocol_indicator); /* Servlet 2.3 API */ s->ssl_cipher = (char *)apr_table_get(r->subprocess_env, conf->cipher_indicator); s->ssl_session = (char *)apr_table_get(r->subprocess_env, conf->session_indicator); if (conf->options & JK_OPT_FWDKEYSIZE) { /* Servlet 2.3 API */ ssl_temp = (char *)apr_table_get(r->subprocess_env, conf-> key_size_indicator); if (ssl_temp) s->ssl_key_size = atoi(ssl_temp); } } } if (conf->envvars) { const apr_array_header_t *t = conf->envvar_items; if (t && t->nelts) { int i; int j = 0; envvar_item *elts = (envvar_item *) t->elts; s->attributes_names = apr_palloc(r->pool, sizeof(char *) * t->nelts); s->attributes_values = apr_palloc(r->pool, sizeof(char *) * t->nelts); for (i = 0; i < t->nelts; i++) { s->attributes_names[i - j] = elts[i].name; s->attributes_values[i - j] = (char *)apr_table_get(r->subprocess_env, elts[i].name); if (!s->attributes_values[i - j]) { if (elts[i].has_default) { s->attributes_values[i - j] = elts[i].value; } else { s->attributes_values[i - j] = ""; s->attributes_names[i - j] = ""; j++; } } } s->num_attributes = t->nelts - j; } } } if (r->headers_in && apr_table_elts(r->headers_in)) { int need_content_length_header = (!s->is_chunked && s->content_length == 0) ? JK_TRUE : JK_FALSE; const apr_array_header_t *t = apr_table_elts(r->headers_in); if (t && t->nelts) { int i; int off = 0; apr_table_entry_t *elts = (apr_table_entry_t *) t->elts; s->num_headers = t->nelts; /* allocate an extra header slot in case we need to add a content-length header */ s->headers_names = apr_palloc(r->pool, sizeof(char *) * (t->nelts + 1)); s->headers_values = apr_palloc(r->pool, sizeof(char *) * (t->nelts + 1)); if (!s->headers_names || !s->headers_values) return JK_FALSE; for (i = 0; i < t->nelts; i++) { char *hname = apr_pstrdup(r->pool, elts[i].key); if (!strcasecmp(hname, "content-length")) { if (need_content_length_header) { need_content_length_header = JK_FALSE; } else if (s->is_chunked) { s->num_headers--; off++; continue; } } s->headers_values[i - off] = apr_pstrdup(r->pool, elts[i].val); s->headers_names[i - off] = hname; } /* Add a content-length = 0 header if needed. * Ajp13 assumes an absent content-length header means an unknown, * but non-zero length body. */ if (need_content_length_header) { s->headers_names[s->num_headers] = "content-length"; s->headers_values[s->num_headers] = "0"; s->num_headers++; } } /* Add a content-length = 0 header if needed. */ else if (need_content_length_header) { s->headers_names = apr_palloc(r->pool, sizeof(char *)); s->headers_values = apr_palloc(r->pool, sizeof(char *)); if (!s->headers_names || !s->headers_values) return JK_FALSE; s->headers_names[0] = "content-length"; s->headers_values[0] = "0"; s->num_headers++; } } s->uw_map = conf->uw_map; /* Dump all connection param so we can trace what's going to * the remote tomcat */ if (JK_IS_DEBUG_LEVEL(conf->log)) { jk_log(conf->log, JK_LOG_DEBUG, "Service protocol=%s method=%s ssl=%s host=%s addr=%s name=%s port=%d auth=%s user=%s laddr=%s raddr=%s uaddr=%s uri=%s", STRNULL_FOR_NULL(s->protocol), STRNULL_FOR_NULL(s->method), s->is_ssl ? "true" : "false", STRNULL_FOR_NULL(s->remote_host), STRNULL_FOR_NULL(s->remote_addr), STRNULL_FOR_NULL(s->server_name), s->server_port, STRNULL_FOR_NULL(s->auth_type), STRNULL_FOR_NULL(s->remote_user), STRNULL_FOR_NULL(r->connection->local_ip), #if (MODULE_MAGIC_NUMBER_MAJOR >= 20111130) STRNULL_FOR_NULL(r->connection->client_ip), STRNULL_FOR_NULL(r->useragent_ip), #else STRNULL_FOR_NULL(r->connection->remote_ip), STRNULL_FOR_NULL(r->connection->remote_ip), #endif STRNULL_FOR_NULL(s->req_uri)); } return JK_TRUE; } /* * The JK module command processors * * The below are all installed so that Apache calls them while it is * processing its config files. This allows configuration info to be * copied into a jk_server_conf_t object, which is then used for request * filtering/processing. * * See jk_cmds definition below for explanations of these options. */ /* * JkMountCopy directive handling * * JkMountCopy On/Off/All */ static const char *jk_set_mountcopy(cmd_parms * cmd, void *dummy, const char *mount_copy) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); if (! strcasecmp(mount_copy, "all")) { const char *err_string = ap_check_cmd_context(cmd, GLOBAL_ONLY); if (err_string != NULL) { return err_string; } jk_mount_copy_all = JK_TRUE; } else if (strcasecmp(mount_copy, "on") && strcasecmp(mount_copy, "off")) { return "JkMountCopy must be All, On or Off"; } else { conf->mountcopy = strcasecmp(mount_copy, "off") ? JK_TRUE : JK_FALSE; } return NULL; } /* * JkMount directive handling * * JkMount URI(context) worker */ static const char *jk_mount_context(cmd_parms * cmd, void *dummy, const char *context, const char *worker) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); const char *c, *w; if (worker != NULL && cmd->path == NULL ) { c = context; w = worker; } else if (worker == NULL && cmd->path != NULL) { c = cmd->path; w = context; } else { if (worker == NULL) return "JkMount needs a path when not defined in a location"; else return "JkMount can not have a path when defined in a location"; } if (c[0] != '/') return "JkMount context should start with /"; if (!conf->uri_to_context) { if (!jk_map_alloc(&(conf->uri_to_context))) { return "JkMount Memory error"; } } /* * Add the new worker to the alias map. */ jk_map_put(conf->uri_to_context, c, w, NULL); return NULL; } /* * JkUnMount directive handling * * JkUnMount URI(context) worker */ static const char *jk_unmount_context(cmd_parms * cmd, void *dummy, const char *context, const char *worker) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); char *uri; const char *c, *w; if (worker != NULL && cmd->path == NULL ) { c = context; w = worker; } else if (worker == NULL && cmd->path != NULL) { c = cmd->path; w = context; } else { if (worker == NULL) return "JkUnMount needs a path when not defined in a location"; else return "JkUnMount can not have a path when defined in a location"; } if (c[0] != '/') return "JkUnMount context should start with /"; uri = apr_pstrcat(cmd->temp_pool, "!", c, NULL); if (!conf->uri_to_context) { if (!jk_map_alloc(&(conf->uri_to_context))) { return "JkUnMount Memory error"; } } /* * Add the new worker to the alias map. */ jk_map_put(conf->uri_to_context, uri, w, NULL); return NULL; } /* * JkWorkersFile Directive Handling * * JkWorkersFile file */ static const char *jk_set_worker_file(cmd_parms * cmd, void *dummy, const char *worker_file) { const char *err_string = ap_check_cmd_context(cmd, GLOBAL_ONLY); if (err_string != NULL) { return err_string; } if (jk_worker_file != NULL) return "JkWorkersFile only allowed once"; /* we need an absolute path (ap_server_root_relative does the ap_pstrdup) */ jk_worker_file = ap_server_root_relative(cmd->pool, worker_file); if (jk_worker_file == NULL) return "JkWorkersFile file name invalid"; if (jk_file_exists(jk_worker_file) != JK_TRUE) return "JkWorkersFile: Can't find the workers file specified"; return NULL; } /* * JkMountFile Directive Handling * * JkMountFile file */ static const char *jk_set_mount_file(cmd_parms * cmd, void *dummy, const char *mount_file) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); /* we need an absolute path (ap_server_root_relative does the ap_pstrdup) */ conf->mount_file = ap_server_root_relative(cmd->pool, mount_file); if (conf->mount_file == NULL) return "JkMountFile file name invalid"; if (jk_file_exists(conf->mount_file) != JK_TRUE) return "JkMountFile: Can't find the mount file specified"; if (!conf->uri_to_context) { if (!jk_map_alloc(&(conf->uri_to_context))) { return "JkMountFile Memory error"; } } return NULL; } /* * JkMountFileReload Directive Handling * * JkMountFileReload seconds */ static const char *jk_set_mount_file_reload(cmd_parms * cmd, void *dummy, const char *mount_file_reload) { server_rec *s = cmd->server; int interval; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); interval = atoi(mount_file_reload); if (interval < 0) { interval = 0; } conf->mount_file_reload = interval; return NULL; } /* * JkWatchdogInterval Directive Handling * * JkWatchdogInterval seconds */ static const char *jk_set_watchdog_interval(cmd_parms * cmd, void *dummy, const char *watchdog_interval) { const char *err_string = ap_check_cmd_context(cmd, GLOBAL_ONLY); if (err_string != NULL) { return err_string; } #if APR_HAS_THREADS jk_watchdog_interval = atoi(watchdog_interval); if (jk_watchdog_interval < 0) { jk_watchdog_interval = 0; } return NULL; #else return "JkWatchdogInterval: APR was compiled without threading support. Cannot create watchdog thread"; #endif } /* * JkLogFile Directive Handling * * JkLogFile file */ static const char *jk_set_log_file(cmd_parms * cmd, void *dummy, const char *log_file) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); /* we need an absolute path */ if (*log_file != '|') conf->log_file = ap_server_root_relative(cmd->pool, log_file); else conf->log_file = apr_pstrdup(cmd->pool, log_file); if (conf->log_file == NULL) return "JkLogFile file name invalid"; return NULL; } /* * JkShmFile Directive Handling * * JkShmFile file */ static const char *jk_set_shm_file(cmd_parms * cmd, void *dummy, const char *shm_file) { const char *err_string = ap_check_cmd_context(cmd, GLOBAL_ONLY); if (err_string != NULL) { return err_string; } /* we need an absolute path */ jk_shm_file = ap_server_root_relative(cmd->pool, shm_file); if (jk_shm_file == NULL) return "JkShmFile file name invalid"; return NULL; } /* * JkShmSize Directive Handling * * JkShmSize size in kilobytes */ static const char *jk_set_shm_size(cmd_parms * cmd, void *dummy, const char *shm_size) { int sz = 0; const char *err_string = ap_check_cmd_context(cmd, GLOBAL_ONLY); if (err_string != NULL) { return err_string; } sz = atoi(shm_size) * 1024; if (sz < JK_SHM_MIN_SIZE) sz = JK_SHM_MIN_SIZE; else sz = JK_SHM_ALIGN(sz); jk_shm_size = sz; if (jk_shm_size) jk_shm_size_set = 1; return NULL; } /* * JkLogLevel Directive Handling * * JkLogLevel debug/info/error/emerg */ static const char *jk_set_log_level(cmd_parms * cmd, void *dummy, const char *log_level) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->log_level = jk_parse_log_level(log_level); return NULL; } /* * JkLogStampFormat Directive Handling * * JkLogStampFormat "[%a %b %d %H:%M:%S %Y] " */ static const char *jk_set_log_fmt(cmd_parms * cmd, void *dummy, const char *log_format) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->stamp_format_string = apr_pstrdup(cmd->pool, log_format); return NULL; } /* * JkAutoAlias Directive Handling * * JkAutoAlias application directory */ static const char *jk_set_auto_alias(cmd_parms * cmd, void *dummy, const char *directory) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->alias_dir = apr_pstrdup(cmd->pool, directory); if (conf->alias_dir == NULL) return "JkAutoAlias directory invalid"; return NULL; } /* * JkStripSession directive handling * * JkStripSession On/Off [session path identifier] */ static const char *jk_set_strip_session(cmd_parms * cmd, void *dummy, const char *flag, const char *name) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); if (strcasecmp(flag, "on") && strcasecmp(flag, "off")) { return "JkStripSession must be On or Off"; } else { conf->strip_session = strcasecmp(flag, "off") ? JK_TRUE : JK_FALSE; } /* Check for optional path value */ if (name) conf->strip_session_name = apr_pstrdup(cmd->pool, name); else conf->strip_session_name = apr_pstrdup(cmd->pool, JK_PATH_SESSION_IDENTIFIER); return NULL; } /***************************************************************** * * Actually logging. */ typedef const char *(*item_key_func) (request_rec *, char *); typedef struct { item_key_func func; char *arg; } request_log_format_item; static const char *process_item(request_rec * r, request_log_format_item * item) { const char *cp; cp = (*item->func) (r, item->arg); return cp ? cp : "-"; } static int request_log_transaction(request_rec * r) { request_log_format_item *items; char *str, *s; int i; int len = 0; const char **strs; int *strl; jk_server_conf_t *conf; jk_request_conf_t *rconf; apr_array_header_t *format; conf = (jk_server_conf_t *) ap_get_module_config(r->server->module_config, &jk_module); format = conf->format; if (format == NULL) { return DECLINED; } rconf = (jk_request_conf_t *)ap_get_module_config(r->request_config, &jk_module); if (rconf == NULL || rconf->jk_handled == JK_FALSE) { return DECLINED; } strs = apr_palloc(r->pool, sizeof(char *) * (format->nelts)); strl = apr_palloc(r->pool, sizeof(int) * (format->nelts)); items = (request_log_format_item *) format->elts; for (i = 0; i < format->nelts; ++i) { strs[i] = process_item(r, &items[i]); } for (i = 0; i < format->nelts; ++i) { len += strl[i] = (int)strlen(strs[i]); } str = apr_palloc(r->pool, len + 1); for (i = 0, s = str; i < format->nelts; ++i) { memcpy(s, strs[i], strl[i]); s += strl[i]; } *s = 0; jk_log(conf->log, JK_LOG_REQUEST, "%s", str); return OK; } /***************************************************************** * * Parsing the log format string */ static char *format_integer(apr_pool_t * p, int i) { return apr_psprintf(p, "%d", i); } static char *pfmt(apr_pool_t * p, int i) { if (i <= 0) { return "-"; } else { return format_integer(p, i); } } static const char *constant_item(request_rec * dummy, char *stuff) { return stuff; } static const char *log_worker_name(request_rec * r, char *a) { return apr_table_get(r->notes, JK_NOTE_WORKER_NAME); } static const char *log_worker_route(request_rec * r, char *a) { return apr_table_get(r->notes, JK_NOTE_WORKER_ROUTE); } static const char *log_request_duration(request_rec * r, char *a) { return apr_table_get(r->notes, JK_NOTE_REQUEST_DURATION); } static const char *log_request_line(request_rec * r, char *a) { /* NOTE: If the original request contained a password, we * re-write the request line here to contain XXXXXX instead: * (note the truncation before the protocol string for HTTP/0.9 requests) * (note also that r->the_request contains the unmodified request) */ return (r->parsed_uri.password) ? apr_pstrcat(r->pool, r->method, " ", apr_uri_unparse(r->pool, &r-> parsed_uri, 0), r-> assbackwards ? NULL : " ", r->protocol, NULL) : r->the_request; } /* These next two routines use the canonical name:port so that log * parsers don't need to duplicate all the vhost parsing crud. */ static const char *log_virtual_host(request_rec * r, char *a) { return r->server->server_hostname; } static const char *log_server_port(request_rec * r, char *a) { return apr_psprintf(r->pool, "%u", r->server->port ? r->server-> port : ap_default_port(r)); } /* This respects the setting of UseCanonicalName so that * the dynamic mass virtual hosting trick works better. */ static const char *log_server_name(request_rec * r, char *a) { return ap_get_server_name(r); } static const char *log_request_uri(request_rec * r, char *a) { return r->uri; } static const char *log_request_method(request_rec * r, char *a) { return r->method; } static const char *log_request_protocol(request_rec * r, char *a) { return r->protocol; } static const char *log_request_query(request_rec * r, char *a) { return (r->args != NULL) ? apr_pstrcat(r->pool, "?", r->args, NULL) : ""; } static const char *log_status(request_rec * r, char *a) { return pfmt(r->pool, r->status); } static const char *clf_log_bytes_sent(request_rec * r, char *a) { if (!r->sent_bodyct) { return "-"; } else { return apr_off_t_toa(r->pool, r->bytes_sent); } } static const char *log_bytes_sent(request_rec * r, char *a) { if (!r->sent_bodyct) { return "0"; } else { return apr_psprintf(r->pool, "%" APR_OFF_T_FMT, r->bytes_sent); } } static struct log_item_list { char ch; item_key_func func; } log_item_keys[] = { { 'T', log_request_duration }, { 'r', log_request_line }, { 'U', log_request_uri }, { 's', log_status }, { 'b', clf_log_bytes_sent }, { 'B', log_bytes_sent }, { 'V', log_server_name }, { 'v', log_virtual_host }, { 'p', log_server_port }, { 'H', log_request_protocol }, { 'm', log_request_method }, { 'q', log_request_query }, { 'w', log_worker_name }, { 'R', log_worker_route}, { '\0', NULL } }; static struct log_item_list *find_log_func(char k) { int i; for (i = 0; log_item_keys[i].ch; ++i) if (k == log_item_keys[i].ch) { return &log_item_keys[i]; } return NULL; } static char *parse_request_log_misc_string(apr_pool_t * p, request_log_format_item * it, const char **sa) { const char *s; char *d; it->func = constant_item; s = *sa; while (*s && *s != '%') { s++; } /* * This might allocate a few chars extra if there's a backslash * escape in the format string. */ it->arg = apr_palloc(p, s - *sa + 1); d = it->arg; s = *sa; while (*s && *s != '%') { if (*s != '\\') { *d++ = *s++; } else { s++; switch (*s) { case '\\': *d++ = '\\'; s++; break; case 'n': *d++ = '\n'; s++; break; case 't': *d++ = '\t'; s++; break; default: /* copy verbatim */ *d++ = '\\'; /* * Allow the loop to deal with this *s in the normal * fashion so that it handles end of string etc. * properly. */ break; } } } *d = '\0'; *sa = s; return NULL; } static char *parse_request_log_item(apr_pool_t * p, request_log_format_item * it, const char **sa) { const char *s = *sa; struct log_item_list *l; if (*s != '%') { return parse_request_log_misc_string(p, it, sa); } ++s; it->arg = ""; /* For safety's sake... */ l = find_log_func(*s++); if (!l) { char dummy[2]; dummy[0] = s[-1]; dummy[1] = '\0'; return apr_pstrcat(p, "Unrecognized JkRequestLogFormat directive %", dummy, NULL); } it->func = l->func; *sa = s; return NULL; } static apr_array_header_t *parse_request_log_string(apr_pool_t * p, const char *s, const char **err) { apr_array_header_t *a = apr_array_make(p, 0, sizeof(request_log_format_item)); char *res; while (*s) { if ((res = parse_request_log_item(p, (request_log_format_item *) apr_array_push(a), &s))) { *err = res; return NULL; } } return a; } /* * JkRequestLogFormat Directive Handling * * JkRequestLogFormat format string * * %b - Bytes sent, excluding HTTP headers. In CLF format * %B - Bytes sent, excluding HTTP headers. * %H - The request protocol * %m - The request method * %p - The canonical Port of the server serving the request * %q - The query string (prepended with a ? if a query string exists, * otherwise an empty string) * %r - First line of request * %s - request HTTP status code * %T - Requset duration, elapsed time to handle request in seconds '.' micro seconds * %U - The URL path requested, not including any query string. * %v - The canonical ServerName of the server serving the request. * %V - The server name according to the UseCanonicalName setting. * %w - Tomcat worker name */ static const char *jk_set_request_log_format(cmd_parms * cmd, void *dummy, const char *format) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->format_string = apr_pstrdup(cmd->pool, format); return NULL; } /* * JkWorkerIndicator Directive Handling * * JkWorkerIndicator JkWorker */ static const char *jk_set_worker_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->worker_indicator = apr_pstrdup(cmd->pool, indicator); return NULL; } /* * Directives Handling for setting various environment names * used to overwrite the following request information: * - remote_addr * - remote_port * - remote_host * - remote_user * - auth_type * - server_name * - server_port */ static const char *jk_set_remote_addr_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->remote_addr_indicator = apr_pstrdup(cmd->pool, indicator); return NULL; } static const char *jk_set_remote_port_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->remote_port_indicator = apr_pstrdup(cmd->pool, indicator); return NULL; } static const char *jk_set_remote_host_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->remote_host_indicator = apr_pstrdup(cmd->pool, indicator); return NULL; } static const char *jk_set_remote_user_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->remote_user_indicator = apr_pstrdup(cmd->pool, indicator); return NULL; } static const char *jk_set_auth_type_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->auth_type_indicator = apr_pstrdup(cmd->pool, indicator); return NULL; } static const char *jk_set_local_name_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->local_name_indicator = apr_pstrdup(cmd->pool, indicator); return NULL; } static const char *jk_set_local_addr_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->local_addr_indicator = apr_pstrdup(cmd->pool, indicator); return NULL; } static const char *jk_set_local_port_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->local_port_indicator = apr_pstrdup(cmd->pool, indicator); return NULL; } static const char *jk_set_ignore_cl_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->ignore_cl_indicator = apr_pstrdup(cmd->pool, indicator); return NULL; } /* * JkExtractSSL Directive Handling * * JkExtractSSL On/Off */ static const char *jk_set_enable_ssl(cmd_parms * cmd, void *dummy, int flag) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); /* Set up our value */ conf->ssl_enable = flag ? JK_TRUE : JK_FALSE; return NULL; } /* * JkHTTPSIndicator Directive Handling * * JkHTTPSIndicator HTTPS */ static const char *jk_set_https_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->https_indicator = apr_pstrdup(cmd->pool, indicator); return NULL; } /* * JkSSLPROTOCOLIndicator Directive Handling * * JkSSLPROTOCOLIndicator SSL_PROTOCOL */ static const char *jk_set_ssl_protocol_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->ssl_protocol_indicator = apr_pstrdup(cmd->pool, indicator); return NULL; } /* * JkCERTSIndicator Directive Handling * * JkCERTSIndicator SSL_CLIENT_CERT */ static const char *jk_set_certs_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->certs_indicator = apr_pstrdup(cmd->pool, indicator); return NULL; } /* * JkCIPHERIndicator Directive Handling * * JkCIPHERIndicator SSL_CIPHER */ static const char *jk_set_cipher_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->cipher_indicator = apr_pstrdup(cmd->pool, indicator); return NULL; } /* * JkCERTCHAINPrefix Directive Handling * * JkCERTCHAINPrefix SSL_CLIENT_CERT_CHAIN_ */ static const char *jk_set_certchain_prefix(cmd_parms * cmd, void *dummy, const char *prefix) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->certchain_prefix = apr_pstrdup(cmd->pool, prefix); return NULL; } /* * JkSESSIONIndicator Directive Handling * * JkSESSIONIndicator SSL_SESSION_ID */ static const char *jk_set_session_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->session_indicator = apr_pstrdup(cmd->pool, indicator); return NULL; } /* * JkKEYSIZEIndicator Directive Handling * * JkKEYSIZEIndicator SSL_CIPHER_USEKEYSIZE */ static const char *jk_set_key_size_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->key_size_indicator = apr_pstrdup(cmd->pool, indicator); return NULL; } /* * JkOptions Directive Handling * * * +ForwardSSLKeySize => Forward SSL Key Size, to follow 2.3 specs but may broke old TC 3.2 * -ForwardSSLKeySize => Don't Forward SSL Key Size, will make mod_jk works with all TC release * ForwardURICompat => Forward URI normally, less spec compliant but mod_rewrite compatible (old TC) * ForwardURICompatUnparsed => Forward URI as unparsed, spec compliant but broke mod_rewrite (old TC) * ForwardURIEscaped => Forward URI escaped and Tomcat (3.3 rc2) stuff will do the decoding part * ForwardDirectories => Forward all directory requests with no index files to Tomcat * +ForwardSSLCertChain => Forward SSL Cert Chain * -ForwardSSLCertChain => Don't Forward SSL Cert Chain (default) */ static const char *jk_set_options(cmd_parms * cmd, void *dummy, const char *line) { int opt = 0; int mask = 0; char action; char *w; server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); while (line[0] != 0) { w = ap_getword_conf(cmd->pool, &line); action = 0; if (*w == '+' || *w == '-') { action = *(w++); } mask = 0; if (action == '-' && (!strncasecmp(w, "ForwardURI", strlen("ForwardURI")) || !strncasecmp(w, "CollapseSlashes", strlen("CollapseSlashes")))) return apr_pstrcat(cmd->pool, "JkOptions: Illegal option '-", w, "': option can not be disabled", NULL); if (!strcasecmp(w, "ForwardURICompat")) { opt = JK_OPT_FWDURICOMPAT; mask = JK_OPT_FWDURIMASK; } else if (!strcasecmp(w, "ForwardURICompatUnparsed")) { opt = JK_OPT_FWDURICOMPATUNPARSED; mask = JK_OPT_FWDURIMASK; } else if (!strcasecmp(w, "ForwardURIEscaped")) { opt = JK_OPT_FWDURIESCAPED; mask = JK_OPT_FWDURIMASK; } else if (!strcasecmp(w, "ForwardURIProxy")) { opt = JK_OPT_FWDURIPROXY; mask = JK_OPT_FWDURIMASK; } else if (!strcasecmp(w, "CollapseSlashesAll")) { opt = JK_OPT_COLLAPSEALL; mask = JK_OPT_COLLAPSEMASK; } else if (!strcasecmp(w, "CollapseSlashesNone")) { opt = JK_OPT_COLLAPSENONE; mask = JK_OPT_COLLAPSEMASK; } else if (!strcasecmp(w, "CollapseSlashesUnmount")) { opt = JK_OPT_COLLAPSEUNMOUNT; mask = JK_OPT_COLLAPSEMASK; } else if (!strcasecmp(w, "ForwardDirectories")) { opt = JK_OPT_FWDDIRS; } else if (!strcasecmp(w, "ForwardLocalAddress")) { opt = JK_OPT_FWDLOCAL; mask = JK_OPT_FWDADDRMASK; } else if (!strcasecmp(w, "ForwardPhysicalAddress")) { opt = JK_OPT_FWDPHYSICAL; mask = JK_OPT_FWDADDRMASK; } else if (!strcasecmp(w, "FlushPackets")) { opt = JK_OPT_FLUSHPACKETS; } else if (!strcasecmp(w, "FlushHeader")) { opt = JK_OPT_FLUSHEADER; } else if (!strcasecmp(w, "DisableReuse")) { opt = JK_OPT_DISABLEREUSE; } else if (!strcasecmp(w, "ForwardSSLCertChain")) { opt = JK_OPT_FWDCERTCHAIN; } else if (!strcasecmp(w, "ForwardKeySize")) { opt = JK_OPT_FWDKEYSIZE; } else if (!strcasecmp(w, "RejectUnsafeURI")) { opt = JK_OPT_REJECTUNSAFE; } else return apr_pstrcat(cmd->pool, "JkOptions: Illegal option '", w, "'", NULL); conf->options &= ~mask; if (action == '-') { conf->exclude_options |= opt; } else if (action == '+') { conf->options |= opt; } else { /* for now +Opt == Opt */ conf->options |= opt; } } return NULL; } /* * JkEnvVar Directive Handling * * JkEnvVar MYOWNDIR */ static const char *jk_add_env_var(cmd_parms * cmd, void *dummy, const char *env_name, const char *default_value) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->envvars_has_own = JK_TRUE; if (!conf->envvars) { conf->envvars = apr_table_make(cmd->pool, 0); conf->envvars_def = apr_table_make(cmd->pool, 0); conf->envvar_items = apr_array_make(cmd->pool, 0, sizeof(envvar_item)); } /* env_name is mandatory, default_value is optional. * No value means send the attribute only, if the env var is set during runtime. */ apr_table_setn(conf->envvars, env_name, default_value ? default_value : ""); apr_table_setn(conf->envvars_def, env_name, default_value ? "1" : "0"); return NULL; } /* * JkWorkerProperty Directive Handling * * JkWorkerProperty name=value */ static const char *jk_set_worker_property(cmd_parms * cmd, void *dummy, const char *line) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); const char *err_string = ap_check_cmd_context(cmd, GLOBAL_ONLY); if (err_string != NULL) { return err_string; } if (!jk_worker_properties) jk_map_alloc(&jk_worker_properties); if (jk_map_read_property(jk_worker_properties, NULL, line, JK_MAP_HANDLE_DUPLICATES, conf->log) == JK_FALSE) return apr_pstrcat(cmd->temp_pool, "Invalid JkWorkerProperty ", line, NULL); return NULL; } static const command_rec jk_cmds[] = { /* * JkWorkersFile specifies a full path to the location of the worker * properties file. * * This file defines the different workers used by apache to redirect * servlet requests. */ AP_INIT_TAKE1("JkWorkersFile", jk_set_worker_file, NULL, RSRC_CONF, "The name of a worker file for the Tomcat servlet containers"), /* * JkMountFile specifies a full path to the location of the * uriworker properties file. * * This file defines the different mapping for workers used by apache * to redirect servlet requests. */ AP_INIT_TAKE1("JkMountFile", jk_set_mount_file, NULL, RSRC_CONF, "The name of a mount file for the Tomcat servlet uri mapping"), /* * JkMountFileReload specifies the reload check interval for the * uriworker properties file. * * Default value is: JK_URIMAP_DEF_RELOAD */ AP_INIT_TAKE1("JkMountFileReload", jk_set_mount_file_reload, NULL, RSRC_CONF, "The reload check interval of the mount file"), /* * JkWatchdogInterval specifies the maintain interval for the * watchdog thread. * * Default value is: 0 meaning watchdog thread will not be created */ AP_INIT_TAKE1("JkWatchdogInterval", jk_set_watchdog_interval, NULL, RSRC_CONF, "The maintain interval of the watchdog thread"), /* * JkMount mounts a url prefix to a worker (the worker need to be * defined in the worker properties file. */ AP_INIT_TAKE12("JkMount", jk_mount_context, NULL, RSRC_CONF|ACCESS_CONF, "A mount point from a context to a Tomcat worker"), /* * JkUnMount unmounts a url prefix to a worker (the worker need to be * defined in the worker properties file. */ AP_INIT_TAKE12("JkUnMount", jk_unmount_context, NULL, RSRC_CONF|ACCESS_CONF, "A no mount point from a context to a Tomcat worker"), /* * JkMountCopy specifies if mod_jk should copy the mount points * from the main server to the virtual servers. */ AP_INIT_TAKE1("JkMountCopy", jk_set_mountcopy, NULL, RSRC_CONF, "Should the base server mounts be copied to the virtual server"), /* * JkStripSession specifies if mod_jk should strip the ;jsessionid * from the unmapped urls */ AP_INIT_TAKE12("JkStripSession", jk_set_strip_session, NULL, RSRC_CONF, "Should the server strip the jsessionid from unmapped URLs"), /* * JkLogFile & JkLogLevel specifies to where should the plugin log * its information and how much. * JkLogStampFormat specify the time-stamp to be used on log */ AP_INIT_TAKE1("JkLogFile", jk_set_log_file, NULL, RSRC_CONF, "Full path to the Tomcat module log file"), AP_INIT_TAKE1("JkShmFile", jk_set_shm_file, NULL, RSRC_CONF, "Full path to the Tomcat module shared memory file"), AP_INIT_TAKE1("JkShmSize", jk_set_shm_size, NULL, RSRC_CONF, "Size of the shared memory file in KBytes"), AP_INIT_TAKE1("JkLogLevel", jk_set_log_level, NULL, RSRC_CONF, "The Tomcat module log level, can be debug, " "info, error or emerg"), AP_INIT_TAKE1("JkLogStampFormat", jk_set_log_fmt, NULL, RSRC_CONF, "The Tomcat module log format, follow strftime syntax"), AP_INIT_TAKE1("JkRequestLogFormat", jk_set_request_log_format, NULL, RSRC_CONF, "The mod_jk module request log format string"), /* * Automatically Alias webapp context directories into the Apache * document space. */ AP_INIT_TAKE1("JkAutoAlias", jk_set_auto_alias, NULL, RSRC_CONF, "The mod_jk module automatic context apache alias directory"), /* * Enable worker name to be set in an environment variable. * This way one can use LocationMatch together with mod_env, * mod_setenvif and mod_rewrite to set the target worker. * Use this in combination with SetHandler jakarta-servlet to * make mod_jk the handler for the request. * */ AP_INIT_TAKE1("JkWorkerIndicator", jk_set_worker_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains the worker name"), /* * Environment variables used to overwrite the following * request information which gets forwarded: * - remote_addr * - remote_port * - remote_host * - remote_user * - auth_type * - server_name * - server_port */ AP_INIT_TAKE1("JkRemoteAddrIndicator", jk_set_remote_addr_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains the remote address"), AP_INIT_TAKE1("JkRemotePortIndicator", jk_set_remote_port_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains the remote port"), AP_INIT_TAKE1("JkRemoteHostIndicator", jk_set_remote_host_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains the remote host name"), AP_INIT_TAKE1("JkRemoteUserIndicator", jk_set_remote_user_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains the remote user name"), AP_INIT_TAKE1("JkAuthTypeIndicator", jk_set_auth_type_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains the type of authentication"), AP_INIT_TAKE1("JkLocalNameIndicator", jk_set_local_name_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains the local name"), AP_INIT_TAKE1("JkLocalAddrIndicator", jk_set_local_addr_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains the local IP address"), AP_INIT_TAKE1("JkLocalPortIndicator", jk_set_local_port_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains the local port"), AP_INIT_TAKE1("JkIgnoreCLIndicator", jk_set_ignore_cl_indicator, NULL, RSRC_CONF, "Name of the Apache environment that forces to ignore a request " "Content-Length header"), /* * Apache has multiple SSL modules (for example apache_ssl, stronghold * IHS ...). Each of these can have a different SSL environment names * The following properties let the administrator specify the envoiroment * variables names. * * HTTPS - indication for SSL * CERTS - Base64-Der-encoded client certificates. * CIPHER - A string specifing the ciphers suite in use. * KEYSIZE - Size of Key used in dialogue (#bits are secure) * SESSION - A string specifing the current SSL session. */ AP_INIT_TAKE1("JkHTTPSIndicator", jk_set_https_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains SSL indication"), AP_INIT_TAKE1("JkSSLPROTOCOLIndicator", jk_set_ssl_protocol_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains the SSL protocol name"), AP_INIT_TAKE1("JkCERTSIndicator", jk_set_certs_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains SSL client certificates"), AP_INIT_TAKE1("JkCIPHERIndicator", jk_set_cipher_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains SSL client cipher"), AP_INIT_TAKE1("JkSESSIONIndicator", jk_set_session_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains SSL session"), AP_INIT_TAKE1("JkKEYSIZEIndicator", jk_set_key_size_indicator, NULL, RSRC_CONF, "Name of the Apache environment that contains SSL key size in use"), AP_INIT_TAKE1("JkCERTCHAINPrefix", jk_set_certchain_prefix, NULL, RSRC_CONF, "Name of the Apache environment (prefix) that contains SSL client chain certificates"), AP_INIT_FLAG("JkExtractSSL", jk_set_enable_ssl, NULL, RSRC_CONF, "Turns on SSL processing and information gathering by mod_jk"), /* * Options to tune mod_jk configuration * for now we understand : * +ForwardSSLKeySize => Forward SSL Key Size, to follow 2.3 specs but may broke old TC 3.2 * -ForwardSSLKeySize => Don't Forward SSL Key Size, will make mod_jk works with all TC release * ForwardURICompat => Forward URI normally, less spec compliant but mod_rewrite compatible (old TC) * ForwardURICompatUnparsed => Forward URI as unparsed, spec compliant but broke mod_rewrite (old TC) * ForwardURIEscaped => Forward URI escaped and Tomcat (3.3 rc2) stuff will do the decoding part * +ForwardSSLCertChain => Forward SSL certificate chain * -ForwardSSLCertChain => Don't forward SSL certificate chain */ AP_INIT_RAW_ARGS("JkOptions", jk_set_options, NULL, RSRC_CONF, "Set one of more options to configure the mod_jk module"), /* * JkEnvVar let user defines envs var passed from WebServer to * Servlet Engine */ AP_INIT_TAKE12("JkEnvVar", jk_add_env_var, NULL, RSRC_CONF, "Adds a name of environment variable and an optional value " "that should be sent to servlet-engine"), AP_INIT_RAW_ARGS("JkWorkerProperty", jk_set_worker_property, NULL, RSRC_CONF, "Set workers.properties formated directive"), {NULL} }; /* ========================================================================= */ /* The JK module handlers */ /* ========================================================================= */ /** Util - cleanup for all processes. */ static apr_status_t jk_cleanup_proc(void *data) { /* If the main log is piped, we need to make sure * it is no longer used. The external log process * (e.g. rotatelogs) will be gone now and the pipe will * block, once the buffer gets full. NULLing * jklogfp makes logging switch to error log. */ jk_logger_t *l = (jk_logger_t *)data; if (l && l->logger_private) { jk_file_logger_t *p = l->logger_private; if (p && p->is_piped == JK_TRUE) { p->jklogfp = NULL; p->is_piped = JK_FALSE; } } jk_shm_close(l); return APR_SUCCESS; } /** Util - cleanup for child processes. */ static apr_status_t jk_cleanup_child(void *data) { /* If the main log is piped, we need to make sure * it is no longer used. The external log process * (e.g. rotatelogs) will be gone now and the pipe will * block, once the buffer gets full. NULLing * jklogfp makes logging switch to error log. */ jk_logger_t *l = (jk_logger_t *)data; if (l && l->logger_private) { jk_file_logger_t *p = l->logger_private; if (p && p->is_piped == JK_TRUE) { p->jklogfp = NULL; p->is_piped = JK_FALSE; } } /* Force the watchdog thread exit */ if (jk_watchdog_interval > 0) { jk_watchdog_interval = 0; while (jk_watchdog_running) apr_sleep(apr_time_from_sec(1)); } wc_shutdown(l); return jk_cleanup_proc(data); } /** Main service method, called to forward a request to tomcat */ static int jk_handler(request_rec * r) { const char *worker_name; jk_server_conf_t *xconf; jk_request_conf_t *rconf; int rc, dmt = 1; int worker_name_extension = JK_FALSE; /* We do DIR_MAGIC_TYPE here to make sure TC gets all requests, even * if they are directory requests, in case there are no static files * visible to Apache and/or DirectoryIndex was not used. This is only * used when JkOptions has ForwardDirectories set. */ /* Not for me, try next handler */ if (strcmp(r->handler, JK_HANDLER) && (dmt = strcmp(r->handler, DIR_MAGIC_TYPE))) return DECLINED; xconf = (jk_server_conf_t *) ap_get_module_config(r->server->module_config, &jk_module); JK_TRACE_ENTER(xconf->log); if (apr_table_get(r->subprocess_env, "no-jk")) { if (JK_IS_DEBUG_LEVEL(xconf->log)) jk_log(xconf->log, JK_LOG_DEBUG, "Into handler no-jk env var detected for uri=%s, declined", r->uri); JK_TRACE_EXIT(xconf->log); return DECLINED; } /* Was the option to forward directories to Tomcat set? */ if (!dmt && !(xconf->options & JK_OPT_FWDDIRS)) { JK_TRACE_EXIT(xconf->log); return DECLINED; } worker_name = apr_table_get(r->notes, JK_NOTE_WORKER_NAME); if (worker_name == NULL) { /* we may be here because of a manual directive ( that overrides translate and sets the handler directly ). We still need to know the worker. */ worker_name = apr_table_get(r->subprocess_env, xconf->worker_indicator); if (worker_name) { /* The JkWorkerIndicator environment variable has * been used to explicitely set the worker without JkMount. * This is useful in combination with LocationMatch or mod_rewrite. */ if (JK_IS_DEBUG_LEVEL(xconf->log)) jk_log(xconf->log, JK_LOG_DEBUG, "Retrieved worker (%s) from env %s for %s", worker_name, xconf->worker_indicator, r->uri); if (ap_strchr_c(worker_name, ';')) { rule_extension_t *e = apr_palloc(r->pool, sizeof(rule_extension_t)); char *w = apr_pstrdup(r->pool, worker_name); worker_name_extension = JK_TRUE; parse_rule_extensions(w, e, xconf->log); worker_name = w; rconf = (jk_request_conf_t *)ap_get_module_config(r->request_config, &jk_module); rconf->rule_extensions = e; } } else if (worker_env.num_of_workers == 1) { /** We have a single worker ( the common case ). ( lb is a bit special, it should count as a single worker but I'm not sure how ). We also have a manual config directive that explicitely give control to us. */ worker_name = worker_env.worker_list[0]; if (JK_IS_DEBUG_LEVEL(xconf->log)) jk_log(xconf->log, JK_LOG_DEBUG, "Single worker (%s) configuration for %s", worker_name, r->uri); } else { if (!xconf->uw_map) { if (JK_IS_DEBUG_LEVEL(xconf->log)) jk_log(xconf->log, JK_LOG_DEBUG, "missing uri map for %s:%s", xconf->s->server_hostname ? xconf->s->server_hostname : "_default_", r->uri); } else { rule_extension_t *e; worker_name = map_uri_to_worker_ext(xconf->uw_map, r->uri, NULL, &e, NULL, xconf->log); rconf = (jk_request_conf_t *)ap_get_module_config(r->request_config, &jk_module); rconf->rule_extensions = e; } if (worker_name == NULL && worker_env.num_of_workers) { worker_name = worker_env.worker_list[0]; if (JK_IS_DEBUG_LEVEL(xconf->log)) jk_log(xconf->log, JK_LOG_DEBUG, "Using first worker (%s) from %d workers for %s", worker_name, worker_env.num_of_workers, r->uri); } } if (worker_name) apr_table_setn(r->notes, JK_NOTE_WORKER_NAME, worker_name); } if (JK_IS_DEBUG_LEVEL(xconf->log)) jk_log(xconf->log, JK_LOG_DEBUG, "Into handler %s worker=%s" " r->proxyreq=%d", r->handler, STRNULL_FOR_NULL(worker_name), r->proxyreq); rconf = (jk_request_conf_t *)ap_get_module_config(r->request_config, &jk_module); rconf->jk_handled = JK_TRUE; /* If this is a proxy request, we'll notify an error */ if (r->proxyreq) { jk_log(xconf->log, JK_LOG_INFO, "Proxy request for worker=%s" " is not allowed", STRNULL_FOR_NULL(worker_name)); JK_TRACE_EXIT(xconf->log); return HTTP_INTERNAL_SERVER_ERROR; } /* Set up r->read_chunked flags for chunked encoding, if present */ if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != APR_SUCCESS) { JK_TRACE_EXIT(xconf->log); return rc; } if (worker_name) { jk_worker_t *worker = wc_get_worker_for_name(worker_name, xconf->log); /* If the remote client has aborted, just ignore the request */ if (r->connection->aborted) { jk_log(xconf->log, JK_LOG_INFO, "Client connection aborted for" " worker=%s", worker_name); JK_TRACE_EXIT(xconf->log); return OK; } if (worker) { long micro, seconds; char *duration = NULL; apr_time_t rd; apr_time_t request_begin = 0; int is_error = HTTP_INTERNAL_SERVER_ERROR; int rc = JK_FALSE; apache_private_data_t private_data; jk_ws_service_t s; jk_pool_atom_t buf[SMALL_POOL_SIZE]; jk_open_pool(&private_data.p, buf, sizeof(buf)); private_data.read_body_started = JK_FALSE; private_data.r = r; if (worker_name_extension == JK_TRUE) { extension_fix(&private_data.p, worker_name, rconf->rule_extensions, xconf->log); } /* Maintain will be done by watchdog thread */ if (!jk_watchdog_interval) wc_maintain(xconf->log); jk_init_ws_service(&s); s.ws_private = &private_data; s.pool = &private_data.p; apr_table_setn(r->notes, JK_NOTE_WORKER_TYPE, wc_get_name_for_type(worker->type, xconf->log)); request_begin = apr_time_now(); if (init_ws_service(&private_data, &s, xconf)) { jk_endpoint_t *end = NULL; /* Use per/thread pool ( or "context" ) to reuse the endpoint. It's a bit faster, but I don't know how to deal with load balancing - but it's usefull for JNI */ /* worker->get_endpoint might fail if we are out of memory so check */ /* and handle it */ if (worker->get_endpoint(worker, &end, xconf->log)) { rc = end->service(end, &s, xconf->log, &is_error); end->done(&end, xconf->log); if (s.content_read < s.content_length || (s.is_chunked && !s.no_more_chunks)) { /* * If the servlet engine didn't consume all of the * request data, consume and discard all further * characters left to read from client */ char *buff = apr_palloc(r->pool, 2048); int consumed = 0; if (buff != NULL) { int rd; while ((rd = ap_get_client_block(r, buff, 2048)) > 0) { s.content_read += rd; consumed += rd; } } if (JK_IS_DEBUG_LEVEL(xconf->log)) { jk_log(xconf->log, JK_LOG_DEBUG, "Consumed %d bytes of remaining request data for worker=%s", consumed, STRNULL_FOR_NULL(worker_name)); } } } else { /* this means we couldn't get an endpoint */ jk_log(xconf->log, JK_LOG_ERROR, "Could not get endpoint" " for worker=%s", worker_name); rc = 0; /* just to make sure that we know we've failed */ is_error = HTTP_SERVICE_UNAVAILABLE; } } else { jk_log(xconf->log, JK_LOG_ERROR, "Could not init service" " for worker=%s", worker_name); jk_close_pool(&private_data.p); JK_TRACE_EXIT(xconf->log); return HTTP_INTERNAL_SERVER_ERROR; } rd = apr_time_now() - request_begin; seconds = (long)apr_time_sec(rd); micro = (long)(rd - apr_time_from_sec(seconds)); duration = apr_psprintf(r->pool, "%.1ld.%.6ld", seconds, micro); apr_table_setn(r->notes, JK_NOTE_REQUEST_DURATION, duration); if (s.route && *s.route) apr_table_set(r->notes, JK_NOTE_WORKER_ROUTE, s.route); jk_close_pool(&private_data.p); if (rc > 0) { if (s.extension.use_server_error_pages && s.http_response_status >= s.extension.use_server_error_pages) { if (JK_IS_DEBUG_LEVEL(xconf->log)) jk_log(xconf->log, JK_LOG_DEBUG, "Forwarding status=%d" " for worker=%s", s.http_response_status, worker_name); JK_TRACE_EXIT(xconf->log); return s.http_response_status; } /* If tomcat returned no body and the status is not OK, let apache handle the error code */ if (!r->sent_bodyct && r->status >= HTTP_BAD_REQUEST) { jk_log(xconf->log, JK_LOG_INFO, "No body with status=%d" " for worker=%s", r->status, worker_name); JK_TRACE_EXIT(xconf->log); return r->status; } if (JK_IS_DEBUG_LEVEL(xconf->log)) jk_log(xconf->log, JK_LOG_DEBUG, "Service finished" " with status=%d for worker=%s", r->status, worker_name); JK_TRACE_EXIT(xconf->log); return OK; /* NOT r->status, even if it has changed. */ } else if (rc == JK_CLIENT_ERROR) { if (is_error != HTTP_REQUEST_ENTITY_TOO_LARGE) r->connection->aborted = 1; jk_log(xconf->log, JK_LOG_INFO, "Aborting connection" " for worker=%s", worker_name); JK_TRACE_EXIT(xconf->log); return is_error; } else { jk_log(xconf->log, JK_LOG_INFO, "Service error=%d" " for worker=%s", rc, worker_name); JK_TRACE_EXIT(xconf->log); return is_error; } } else { jk_log(xconf->log, JK_LOG_INFO, "Could not find a worker" " for worker name=%s", worker_name); JK_TRACE_EXIT(xconf->log); return HTTP_INTERNAL_SERVER_ERROR; } } rconf->jk_handled = JK_FALSE; JK_TRACE_EXIT(xconf->log); return DECLINED; } /** Standard apache hook, cleanup jk */ static apr_status_t jk_apr_pool_cleanup(void *data) { server_rec *s = data; if (jk_worker_properties) { jk_map_free(&jk_worker_properties); jk_worker_properties = NULL; jk_worker_file = NULL; jk_mount_copy_all = JK_FALSE; } while (NULL != s) { jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); if (conf && conf->was_initialized == JK_TRUE) { /* On pool cleanup pass NULL for the jk_logger to prevent segmentation faults on Windows because we can't guarantee what order pools get cleaned up between APR implementations. */ wc_close(NULL); if (conf->uri_to_context) { jk_map_free(&conf->uri_to_context); /* We cannot have allocated uw_map * unless we've allocated uri_to_context */ if (conf->uw_map) uri_worker_map_free(&conf->uw_map, NULL); } conf->was_initialized = JK_FALSE; } s = s->next; } return APR_SUCCESS; } /** Create default jk_config. XXX This is mostly server-independent, all servers are using something similar - should go to common. */ static void *create_jk_config(apr_pool_t * p, server_rec * s) { jk_server_conf_t *c = (jk_server_conf_t *) apr_pcalloc(p, sizeof(jk_server_conf_t)); c->was_initialized = JK_FALSE; if (s->is_virtual) { c->mountcopy = JK_UNSET; c->mount_file_reload = JK_UNSET; c->log_level = JK_UNSET; c->ssl_enable = JK_UNSET; c->strip_session = JK_UNSET; } else { if (!jk_map_alloc(&(c->uri_to_context))) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "Memory error"); } c->mountcopy = JK_FALSE; c->mount_file_reload = JK_URIMAP_DEF_RELOAD; c->log_level = JK_LOG_DEF_LEVEL; c->options = JK_OPT_DEFAULT; c->worker_indicator = JK_ENV_WORKER_NAME; /* * Configurable environment variables to overwrite * request information using meta data send by a * proxy in front of us. */ c->remote_addr_indicator = JK_ENV_REMOTE_ADDR; c->remote_port_indicator = JK_ENV_REMOTE_PORT; c->remote_host_indicator = JK_ENV_REMOTE_HOST; c->remote_user_indicator = JK_ENV_REMOTE_USER; c->auth_type_indicator = JK_ENV_AUTH_TYPE; c->local_name_indicator = JK_ENV_LOCAL_NAME; c->local_addr_indicator = JK_ENV_LOCAL_ADDR; c->local_port_indicator = JK_ENV_LOCAL_PORT; c->ignore_cl_indicator = JK_ENV_IGNORE_CL; /* * By default we will try to gather SSL info. * Disable this functionality through JkExtractSSL */ c->ssl_enable = JK_TRUE; /* * The defaults ssl indicators match those in mod_ssl (seems * to be in more use). */ c->https_indicator = JK_ENV_HTTPS; c->ssl_protocol_indicator = JK_ENV_SSL_PROTOCOL; c->certs_indicator = JK_ENV_CERTS; c->cipher_indicator = JK_ENV_CIPHER; c->certchain_prefix = JK_ENV_CERTCHAIN_PREFIX; c->session_indicator = JK_ENV_SESSION; c->key_size_indicator = JK_ENV_KEY_SIZE; c->strip_session = JK_FALSE; } c->envvars_has_own = JK_FALSE; c->s = s; apr_pool_cleanup_register(p, s, jk_apr_pool_cleanup, apr_pool_cleanup_null); return c; } /* * Utility - copy items from apr table src to dst, * for keys that exist in src but not in dst. */ static void merge_apr_table(apr_table_t *src, apr_table_t *dst) { int i; const apr_array_header_t *arr; const apr_table_entry_t *elts; arr = apr_table_elts(src); elts = (const apr_table_entry_t *)arr->elts; for (i = 0; i < arr->nelts; ++i) { if (!apr_table_get(dst, elts[i].key)) { apr_table_setn(dst, elts[i].key, elts[i].val); } } } /** Standard apache callback, merge jk options specified in context or . */ static void *merge_jk_config(apr_pool_t * p, void *basev, void *overridesv) { jk_server_conf_t *base = (jk_server_conf_t *) basev; jk_server_conf_t *overrides = (jk_server_conf_t *) overridesv; int mask = 0; if (!overrides->log_file) overrides->log_file = base->log_file; if (overrides->log_level == JK_UNSET) overrides->log_level = base->log_level; if (!overrides->stamp_format_string) overrides->stamp_format_string = base->stamp_format_string; if (!overrides->format_string) overrides->format_string = base->format_string; if (!overrides->worker_indicator) overrides->worker_indicator = base->worker_indicator; if (!overrides->remote_addr_indicator) overrides->remote_addr_indicator = base->remote_addr_indicator; if (!overrides->remote_port_indicator) overrides->remote_port_indicator = base->remote_port_indicator; if (!overrides->remote_host_indicator) overrides->remote_host_indicator = base->remote_host_indicator; if (!overrides->remote_user_indicator) overrides->remote_user_indicator = base->remote_user_indicator; if (!overrides->auth_type_indicator) overrides->auth_type_indicator = base->auth_type_indicator; if (!overrides->local_name_indicator) overrides->local_name_indicator = base->local_name_indicator; if (!overrides->local_port_indicator) overrides->local_port_indicator = base->local_port_indicator; if (!overrides->ignore_cl_indicator) overrides->ignore_cl_indicator = base->ignore_cl_indicator; if (overrides->ssl_enable == JK_UNSET) overrides->ssl_enable = base->ssl_enable; if (!overrides->https_indicator) overrides->https_indicator = base->https_indicator; if (!overrides->ssl_protocol_indicator) overrides->ssl_protocol_indicator = base->ssl_protocol_indicator; if (!overrides->certs_indicator) overrides->certs_indicator = base->certs_indicator; if (!overrides->cipher_indicator) overrides->cipher_indicator = base->cipher_indicator; if (!overrides->certchain_prefix) overrides->certchain_prefix = base->certchain_prefix; if (!overrides->session_indicator) overrides->session_indicator = base->session_indicator; if (!overrides->key_size_indicator) overrides->key_size_indicator = base->key_size_indicator; /* Don't simply accumulate bits in the JK_OPT_FWDURIMASK or * JK_OPT_COLLAPSEMASK region, because those are multi-bit values. */ if (overrides->options & JK_OPT_FWDURIMASK) mask |= JK_OPT_FWDURIMASK; if (overrides->options & JK_OPT_COLLAPSEMASK) mask |= JK_OPT_COLLAPSEMASK; overrides->options |= (base->options & ~base->exclude_options) & ~mask; if (base->envvars) { if (overrides->envvars && overrides->envvars_has_own) { /* merge_apr_table() preserves existing entries in overrides table */ merge_apr_table(base->envvars, overrides->envvars); merge_apr_table(base->envvars_def, overrides->envvars_def); } else { overrides->envvars = base->envvars; overrides->envvars_def = base->envvars_def; overrides->envvar_items = base->envvar_items; } } if (overrides->mountcopy == JK_UNSET && jk_mount_copy_all == JK_TRUE) { overrides->mountcopy = JK_TRUE; } if (overrides->uri_to_context && overrides->mountcopy == JK_TRUE) { /* jk_map_copy() preserves existing entries in overrides map */ if (jk_map_copy(base->uri_to_context, overrides->uri_to_context) == JK_FALSE) { jk_error_exit(JKLOG_MARK, APLOG_EMERG, overrides->s, p, "Memory error"); } if (!overrides->mount_file) overrides->mount_file = base->mount_file; } if (overrides->mountcopy == JK_TRUE) { if (!overrides->alias_dir) overrides->alias_dir = base->alias_dir; } if (overrides->mount_file_reload == JK_UNSET) overrides->mount_file_reload = base->mount_file_reload; if (overrides->strip_session == JK_UNSET) { overrides->strip_session = base->strip_session; overrides->strip_session_name = base->strip_session_name; } return overrides; } static int JK_METHOD jk_log_to_file(jk_logger_t *l, int level, int used, char *what) { if (l && (l->level <= level || level == JK_LOG_REQUEST_LEVEL) && l->logger_private && what && used > 0) { jk_file_logger_t *p = l->logger_private; if (p->jklogfp) { apr_status_t rv; apr_size_t wrote; #if defined(WIN32) what[used++] = '\r'; #endif what[used++] = '\n'; wrote = used; rv = apr_global_mutex_lock(jk_log_lock); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, "apr_global_mutex_lock(jk_log_lock) failed"); /* XXX: Maybe this should be fatal? */ } rv = apr_file_write(p->jklogfp, what, &wrote); if (rv != APR_SUCCESS) { char error[256]; apr_strerror(rv, error, 254); ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "mod_jk: jk_log_to_file %.*s failed: %s", used, what, error); } rv = apr_global_mutex_unlock(jk_log_lock); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rv, NULL, "apr_global_mutex_unlock(jk_log_lock) failed"); /* XXX: Maybe this should be fatal? */ } } else { /* Can't use mod_jk log any more, log to error log instead. * Choose APLOG_ERR, since we already checked above, that if * the mod_jk log file would still be open, we would have * actually logged the message there */ ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "%.*s", used, what); } return JK_TRUE; } return JK_FALSE; } /* ** +-------------------------------------------------------+ ** | | ** | jk logfile support | ** | | ** +-------------------------------------------------------+ */ static apr_status_t jklog_cleanup(void *d) { /* hgomez@20070425 */ /* Clean up pointer content */ if (d != NULL) *(jk_logger_t **)d = NULL; return APR_SUCCESS; } static int open_jklog(server_rec * s, apr_pool_t * p) { jk_server_conf_t *conf; const char *fname; apr_status_t rc; apr_file_t *jklogfp; piped_log *pl; jk_logger_t *jkl; jk_file_logger_t *flp; int jklog_flags = (APR_WRITE | APR_APPEND | APR_CREATE); apr_fileperms_t jklog_mode = (APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD); conf = ap_get_module_config(s->module_config, &jk_module); if (conf->log_file == NULL) { conf->log_file = ap_server_root_relative(p, JK_LOG_DEF_FILE); if (conf->log_file) ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, "No JkLogFile defined in httpd.conf. " "Using default %s", conf->log_file); } if (*(conf->log_file) == '\0') { ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s, "mod_jk: Invalid JkLogFile EMPTY"); conf->log = main_log; return 0; } jklogfp = apr_hash_get(jk_log_fps, conf->log_file, APR_HASH_KEY_STRING); if (!jklogfp) { if (*conf->log_file == '|') { if ((pl = ap_open_piped_log(p, conf->log_file + 1)) == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "mod_jk: could not open reliable pipe " "to jk log %s", conf->log_file + 1); return -1; } jklogfp = (void *)ap_piped_log_write_fd(pl); } else { fname = ap_server_root_relative(p, conf->log_file); if (!fname) { ap_log_error(APLOG_MARK, APLOG_ERR, APR_EBADPATH, s, "mod_jk: Invalid JkLog " "path %s", conf->log_file); return -1; } if ((rc = apr_file_open(&jklogfp, fname, jklog_flags, jklog_mode, p)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, rc, s, "mod_jk: could not open JkLog " "file %s", fname); return -1; } } apr_file_inherit_set(jklogfp); apr_hash_set(jk_log_fps, conf->log_file, APR_HASH_KEY_STRING, jklogfp); } jkl = (jk_logger_t *)apr_palloc(p, sizeof(jk_logger_t)); flp = (jk_file_logger_t *) apr_palloc(p, sizeof(jk_file_logger_t)); if (jkl && flp) { jkl->log = jk_log_to_file; jkl->level = conf->log_level; jkl->logger_private = flp; flp->jklogfp = jklogfp; if (*conf->log_file == '|') flp->is_piped = JK_TRUE; else flp->is_piped = JK_FALSE; conf->log = jkl; jk_set_time_fmt(conf->log, conf->stamp_format_string); if (main_log == NULL) { main_log = conf->log; /* hgomez@20070425 */ /* Shouldn't we clean both conf->log and main_log ? */ /* Also should we pass pointer (ie: main_log) or handle (*main_log) ? */ apr_pool_cleanup_register(p, &main_log, jklog_cleanup, apr_pool_cleanup_null); } return 0; } return -1; } #if APR_HAS_THREADS static void * APR_THREAD_FUNC jk_watchdog_func(apr_thread_t *thd, void *data) { int i; jk_server_conf_t *conf = (jk_server_conf_t *)data; if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Watchdog thread initialized with %d second interval", jk_watchdog_interval); for (;;) { for (i = 0; i < (jk_watchdog_interval * 10); i++) { /* apr_sleep() uses microseconds */ apr_sleep((apr_time_t)(100000)); if (!jk_watchdog_interval) break; } if (!jk_watchdog_interval) break; if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Watchdog thread running"); jk_watchdog_running = 1; wc_maintain(conf->log); if (!jk_watchdog_interval) break; } jk_watchdog_running = 0; return NULL; } #endif /** Standard apache callback, initialize jk. */ static void jk_child_init(apr_pool_t * pconf, server_rec * s) { jk_server_conf_t *conf; apr_status_t rv; int rc; apr_thread_t *wdt; conf = ap_get_module_config(s->module_config, &jk_module); rv = apr_global_mutex_child_init(&jk_log_lock, NULL, pconf); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, "mod_jk: could not init JK log lock in child"); } JK_TRACE_ENTER(conf->log); if (jk_watchdog_interval) { #if APR_HAS_THREADS rv = apr_thread_create(&wdt, NULL, jk_watchdog_func, conf, pconf); if (rv != APR_SUCCESS) { jk_log(conf->log, JK_LOG_ERROR, "Could not init watchdog thread, error=%d", rv); jk_watchdog_interval = 0; } apr_thread_detach(wdt); #endif } if ((rc = jk_shm_attach(jk_shm_file, jk_shm_size, conf->log)) == 0) { apr_pool_cleanup_register(pconf, conf->log, jk_cleanup_child, apr_pool_cleanup_null); } else { jk_log(conf->log, JK_LOG_ERROR, "Attaching shm:%s errno=%d", jk_shm_name(), rc); } if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Initialized %s", JK_FULL_EXPOSED_VERSION); JK_TRACE_EXIT(conf->log); } /** Initialize jk, using worker.properties. We also use apache commands ( JkWorker, etc), but this use is deprecated, as we'll try to concentrate all config in workers.properties, urimap.properties, and ajp14 autoconf. Apache config will only be used for manual override, using SetHandler and normal apache directives ( but minimal jk-specific stuff ) */ static int init_jk(apr_pool_t * pconf, jk_server_conf_t * conf, server_rec * s) { int rc; int is_threaded; int mpm_threads = 1; if (!jk_worker_properties) jk_map_alloc(&jk_worker_properties); jk_map_put(jk_worker_properties, "ServerRoot", ap_server_root, NULL); /* Set default connection cache size for multi-threaded MPMs */ if (ap_mpm_query(AP_MPMQ_IS_THREADED, &is_threaded) == APR_SUCCESS && is_threaded != AP_MPMQ_NOT_SUPPORTED) { if (ap_mpm_query(AP_MPMQ_MAX_THREADS, &mpm_threads) != APR_SUCCESS) mpm_threads = 1; } if (mpm_threads > 1) { #if _MT_CODE /* _MT_CODE */ if (JK_IS_DEBUG_LEVEL(conf->log)) { #if !defined(WIN32) && !defined(NETWARE) #if USE_FLOCK_LK jk_log(conf->log, JK_LOG_DEBUG, "Using flock() for locking."); #else jk_log(conf->log, JK_LOG_DEBUG, "Using fcntl() for locking."); #endif /* USE_FLOCK_LK */ #else /* WIN32 */ jk_log(conf->log, JK_LOG_DEBUG, "Not using locking."); #endif } #else /* !_MT_CODE */ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "Cannot run prefork mod_jk on threaded server."); return JK_FALSE; #endif } if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Setting default connection pool max size to %d", mpm_threads); jk_set_worker_def_cache_size(mpm_threads); if ((jk_worker_file != NULL) && !jk_map_read_properties(jk_worker_properties, NULL, jk_worker_file, NULL, JK_MAP_HANDLE_DUPLICATES, conf->log)) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "Error in reading worker properties from '%s'", jk_worker_file); return JK_FALSE; } if (jk_map_resolve_references(jk_worker_properties, "worker.", 1, 1, conf->log) == JK_FALSE) { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "Error in resolving configuration references"); return JK_FALSE; } #if !defined(WIN32) && !defined(NETWARE) if (!jk_shm_file) { jk_shm_file = ap_server_root_relative(pconf, JK_SHM_DEF_FILE); if (jk_shm_file) ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, "No JkShmFile defined in httpd.conf. " "Using default %s", jk_shm_file); } #endif if (jk_shm_size == 0) { jk_shm_size = jk_shm_calculate_size(jk_worker_properties, conf->log); } else if (jk_shm_size_set) { jk_log(conf->log, JK_LOG_WARNING, "The optimal shared memory size can now be determined automatically."); jk_log(conf->log, JK_LOG_WARNING, "You can remove the JkShmSize directive if you want to use the optimal size."); } if ((rc = jk_shm_open(jk_shm_file, jk_shm_size, conf->log)) == 0) { apr_pool_cleanup_register(pconf, conf->log, jk_cleanup_proc, apr_pool_cleanup_null); } else { jk_log(conf->log, JK_LOG_ERROR, "Initializing shm:%s errno=%d. Load balancing workers will not function properly.", jk_shm_name(), rc); } /* we add the URI->WORKER MAP since workers using AJP14 will feed it */ worker_env.uri_to_worker = conf->uw_map; worker_env.virtual = "*"; /* for now */ #if ((AP_MODULE_MAGIC_AT_LEAST(20051115,4)) && !defined(API_COMPATIBILITY)) || (MODULE_MAGIC_NUMBER_MAJOR >= 20060905) worker_env.server_name = (char *)ap_get_server_description(); #else worker_env.server_name = (char *)ap_get_server_version(); #endif worker_env.pool = pconf; if (wc_open(jk_worker_properties, &worker_env, conf->log)) { ap_add_version_component(pconf, JK_EXPOSED_VERSION); jk_log(conf->log, JK_LOG_INFO, "%s initialized", JK_FULL_EXPOSED_VERSION); } else { ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "Error in creating the workers." " Please consult your mod_jk log file '%s'.", conf->log_file); return JK_FALSE; } return JK_TRUE; } static int jk_post_config(apr_pool_t * pconf, apr_pool_t * plog, apr_pool_t * ptemp, server_rec * s) { apr_status_t rv; jk_server_conf_t *conf; server_rec *srv = s; const char *err_string = NULL; int remain; void *data = NULL; remain = jk_check_buffer_size(); if (remain < 0) { ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s, "mod_jk: JK_MAX_ATTRIBUTE_NAME_LEN in jk_util.c is too small, " "increase by %d", -1 * remain); return HTTP_INTERNAL_SERVER_ERROR; } apr_pool_userdata_get(&data, JK_LOG_LOCK_KEY, s->process->pool); if (data == NULL) { /* create the jk log lockfiles in the parent */ if ((rv = apr_global_mutex_create(&jk_log_lock, NULL, APR_LOCK_DEFAULT, s->process->pool)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, "mod_jk: could not create jk_log_lock"); return HTTP_INTERNAL_SERVER_ERROR; } #if JK_NEED_SET_MUTEX_PERMS #if (MODULE_MAGIC_NUMBER_MAJOR >= 20090208) rv = ap_unixd_set_global_mutex_perms(jk_log_lock); #else rv = unixd_set_global_mutex_perms(jk_log_lock); #endif if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s, "mod_jk: Could not set permissions on " "jk_log_lock; check User and Group directives"); return HTTP_INTERNAL_SERVER_ERROR; } #endif apr_pool_userdata_set((const void *)jk_log_lock, JK_LOG_LOCK_KEY, apr_pool_cleanup_null, s->process->pool); } else { jk_log_lock = (apr_global_mutex_t *)data; } main_server = s; jk_log_fps = apr_hash_make(pconf); if (!s->is_virtual) { conf = (jk_server_conf_t *)ap_get_module_config(s->module_config, &jk_module); if (conf->was_initialized == JK_FALSE) { /* step through the servers and open each jk logfile * and do additional post config initialization. */ for (; srv; srv = srv->next) { jk_server_conf_t *sconf = (jk_server_conf_t *)ap_get_module_config(srv->module_config, &jk_module); /* * If a virtual server contains no JK directive, httpd shares * the config structure. But we don't want to share some settings * by default, especially the JkMount rules. * Therefore we check, if this config structure really belongs to this * vhost, otherwise we create a new one and merge. */ if (sconf && sconf->s != srv) { jk_server_conf_t *srvconf = (jk_server_conf_t *)create_jk_config(pconf, srv); sconf = (jk_server_conf_t *)merge_jk_config(pconf, sconf, srvconf); ap_set_module_config(srv->module_config, &jk_module, sconf); } if (sconf && sconf->was_initialized == JK_FALSE) { sconf->was_initialized = JK_TRUE; if (open_jklog(srv, pconf)) return HTTP_INTERNAL_SERVER_ERROR; sconf->options &= ~sconf->exclude_options; dump_options(srv, pconf); if (sconf->uri_to_context) { if (!uri_worker_map_alloc(&(sconf->uw_map), sconf->uri_to_context, sconf->log)) jk_error_exit(JKLOG_MARK, APLOG_EMERG, srv, srv->process->pool, "Memory error"); if (sconf->options & JK_OPT_REJECTUNSAFE) sconf->uw_map->reject_unsafe = 1; else sconf->uw_map->reject_unsafe = 0; if (sconf->mount_file) { sconf->uw_map->fname = sconf->mount_file; sconf->uw_map->reload = sconf->mount_file_reload; uri_worker_map_switch(sconf->uw_map, sconf->log); uri_worker_map_load(sconf->uw_map, sconf->log); } switch (sconf->options & JK_OPT_COLLAPSEMASK) { case JK_OPT_COLLAPSEALL: sconf->uw_map->collapse_slashes = JK_COLLAPSE_ALL; break; case JK_OPT_COLLAPSENONE: sconf->uw_map->collapse_slashes = JK_COLLAPSE_NONE; break; case JK_OPT_COLLAPSEUNMOUNT: sconf->uw_map->collapse_slashes = JK_COLLAPSE_UNMOUNT; break; default: ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, "Collapse slashes value %d ignored, setting to %d", sconf->options & JK_OPT_COLLAPSEMASK, JK_COLLAPSE_DEFAULT); sconf->uw_map->collapse_slashes = JK_COLLAPSE_DEFAULT; } } else { if (sconf->mountcopy == JK_TRUE) { sconf->uw_map = conf->uw_map; } } if (sconf->format_string) { sconf->format = parse_request_log_string(pconf, sconf->format_string, &err_string); if (sconf->format == NULL) ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "JkRequestLogFormat format array NULL"); } if (sconf->envvars && sconf->envvars_has_own) { int i; const apr_array_header_t *arr; const apr_table_entry_t *elts; envvar_item *item; const char *envvar_def; arr = apr_table_elts(sconf->envvars); if (arr) { elts = (const apr_table_entry_t *)arr->elts; for (i = 0; i < arr->nelts; ++i) { item = (envvar_item *)apr_array_push(sconf->envvar_items); if (!item) return HTTP_INTERNAL_SERVER_ERROR; item->name = elts[i].key; envvar_def = apr_table_get(sconf->envvars_def, elts[i].key); if (envvar_def && !strcmp("1", envvar_def) ) { item->value = elts[i].val; item->has_default = 1; } else { item->value = ""; item->has_default = 0; } } } } } } conf->was_initialized = JK_TRUE; if (init_jk(pconf, conf, s) == JK_FALSE) return HTTP_INTERNAL_SERVER_ERROR; if (conf->uw_map) { uri_worker_map_ext(conf->uw_map, conf->log); uri_worker_map_switch(conf->uw_map, conf->log); } for (srv = s; srv; srv = srv->next) { jk_server_conf_t *sconf = (jk_server_conf_t *)ap_get_module_config(srv->module_config, &jk_module); if (conf->uw_map != sconf->uw_map && sconf->uw_map) { uri_worker_map_ext(sconf->uw_map, sconf->log); uri_worker_map_switch(sconf->uw_map, sconf->log); } } } } return OK; } /** Use the internal mod_jk mappings to find if this is a request for * tomcat and what worker to use. */ static int jk_translate(request_rec * r) { jk_request_conf_t *rconf = apr_palloc(r->pool, sizeof(jk_request_conf_t)); rconf->jk_handled = JK_FALSE; rconf->rule_extensions = NULL; ap_set_module_config(r->request_config, &jk_module, rconf); if (!r->proxyreq) { jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(r->server-> module_config, &jk_module); if (conf) { const char *worker; if ((r->handler != NULL) && (!strcmp(r->handler, JK_HANDLER))) { /* Somebody already set the handler, probably manual config * or "native" configuration, no need for extra overhead */ if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Manually mapped, no need to call uri_to_worker"); return DECLINED; } if (apr_table_get(r->subprocess_env, "no-jk")) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Into translate no-jk env var detected for uri=%s, declined", r->uri); return DECLINED; } /* Special case to make sure that apache can serve a directory listing if there are no matches for the DirectoryIndex and Tomcat webapps are mapped into apache using JkAutoAlias. */ if (r->main != NULL && r->main->handler != NULL && (conf->alias_dir != NULL) && !strcmp(r->main->handler, DIR_MAGIC_TYPE)) { /* Append the request uri to the JkAutoAlias directory and determine if the file exists. */ char *clean_uri; apr_finfo_t finfo; finfo.filetype = APR_NOFILE; clean_uri = apr_pstrdup(r->pool, r->uri); ap_no2slash(clean_uri); /* Map uri to a context static file */ if (strlen(clean_uri) > 1) { char *context_path = NULL; context_path = apr_pstrcat(r->pool, conf->alias_dir, ap_os_escape_path(r->pool, clean_uri, 1), NULL); if (context_path != NULL) { apr_stat(&finfo, context_path, APR_FINFO_TYPE, r->pool); } } if (finfo.filetype != APR_REG) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "JkAutoAlias, no DirectoryIndex file for URI %s", r->uri); return DECLINED; } } if (!conf->uw_map) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "missing uri map for %s:%s", conf->s->server_hostname ? conf->s->server_hostname : "_default_", r->uri); return DECLINED; } else { rule_extension_t *e; worker = map_uri_to_worker_ext(conf->uw_map, r->uri, NULL, &e, NULL, conf->log); rconf->rule_extensions = e; ap_set_module_config(r->request_config, &jk_module, rconf); } if (worker) { r->handler = apr_pstrdup(r->pool, JK_HANDLER); apr_table_setn(r->notes, JK_NOTE_WORKER_NAME, worker); /* This could be a sub-request, possibly from mod_dir */ /* Also add the the HANDLER to the main request */ if (r->main) { r->main->handler = apr_pstrdup(r->main->pool, JK_HANDLER); apr_table_setn(r->main->notes, JK_NOTE_WORKER_NAME, worker); } return OK; } else if (conf->alias_dir != NULL) { char *clean_uri = apr_pstrdup(r->pool, r->uri); ap_no2slash(clean_uri); /* Automatically map uri to a context static file */ if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "check alias_dir: %s", conf->alias_dir); if (strlen(clean_uri) > 1) { /* Get the context directory name */ char *context_dir = NULL; char *context_path = NULL; char *child_dir = NULL; char *index = clean_uri; char *suffix = strchr(index + 1, '/'); if (suffix != NULL) { int size = (int)(suffix - index); context_dir = apr_pstrndup(r->pool, index, size); /* Get the context child directory name */ index = index + size + 1; suffix = strchr(index, '/'); if (suffix != NULL) { size = suffix - index; child_dir = apr_pstrndup(r->pool, index, size); } else { child_dir = index; } /* Deny access to WEB-INF and META-INF directories */ if (child_dir != NULL) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "AutoAlias child_dir: %s", child_dir); if (!strcasecmp(child_dir, "WEB-INF") || !strcasecmp(child_dir, "META-INF")) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "AutoAlias HTTP_NOT_FOUND for URI: %s", r->uri); return HTTP_NOT_FOUND; } } } else { context_dir = apr_pstrdup(r->pool, index); } context_path = apr_pstrcat(r->pool, conf->alias_dir, ap_os_escape_path(r->pool, context_dir, 1), NULL); if (context_path != NULL) { apr_finfo_t finfo; finfo.filetype = APR_NOFILE; apr_stat(&finfo, context_path, APR_FINFO_TYPE, r->pool); if (finfo.filetype == APR_DIR) { char *escurl = ap_os_escape_path(r->pool, clean_uri, 1); char *ret = apr_pstrcat(r->pool, conf->alias_dir, escurl, NULL); /* Add code to verify real path ap_os_canonical_name */ if (ret != NULL) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "AutoAlias OK for file: %s", ret); r->filename = ret; return OK; } } else { /* Deny access to war files in web app directory */ int size = (int)strlen(context_dir); if (size > 4 && !strcasecmp(context_dir + (size - 4), ".war")) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "AutoAlias HTTP_FORBIDDEN for URI: %s", r->uri); return HTTP_FORBIDDEN; } } } } } else { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "no match for %s found", r->uri); } } } return DECLINED; } /* bypass the directory_walk and file_walk for non-file requests */ static int jk_map_to_storage(request_rec * r) { jk_request_conf_t *rconf = ap_get_module_config(r->request_config, &jk_module); if (rconf == NULL) { rconf = apr_palloc(r->pool, sizeof(jk_request_conf_t)); rconf->jk_handled = JK_FALSE; rconf->rule_extensions = NULL; ap_set_module_config(r->request_config, &jk_module, rconf); } if (!r->proxyreq && !apr_table_get(r->notes, JK_NOTE_WORKER_NAME)) { jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(r->server-> module_config, &jk_module); if (conf) { const char *worker; if ((r->handler != NULL) && (!strcmp(r->handler, JK_HANDLER))) { /* Somebody already set the handler, probably manual config * or "native" configuration, no need for extra overhead */ if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Manually mapped, no need to call uri_to_worker"); return DECLINED; } if (apr_table_get(r->subprocess_env, "no-jk")) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Into map_to_storage no-jk env var detected for uri=%s, declined", r->uri); return DECLINED; } if (!conf->uw_map) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "missing uri map for %s:%s", conf->s->server_hostname ? conf->s->server_hostname : "_default_", r->uri); return DECLINED; } else { rule_extension_t *e; worker = map_uri_to_worker_ext(conf->uw_map, r->uri, NULL, &e, NULL, conf->log); rconf->rule_extensions = e; ap_set_module_config(r->request_config, &jk_module, rconf); } if (worker) { r->handler = apr_pstrdup(r->pool, JK_HANDLER); apr_table_setn(r->notes, JK_NOTE_WORKER_NAME, worker); /* This could be a sub-request, possibly from mod_dir */ if (r->main) apr_table_setn(r->main->notes, JK_NOTE_WORKER_NAME, worker); } else { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "no match for %s found", r->uri); if (conf->strip_session == JK_TRUE && conf->strip_session_name) { char *jsessionid; if (r->uri) { jsessionid = strstr(r->uri, conf->strip_session_name); if (jsessionid) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "removing session identifier [%s] for non servlet url [%s]", jsessionid, r->uri); *jsessionid = '\0'; } } if (r->filename) { jsessionid = strstr(r->filename, conf->strip_session_name); if (jsessionid) *jsessionid = '\0'; } return DECLINED; } } } } if (apr_table_get(r->notes, JK_NOTE_WORKER_NAME)) { /* First find just the name of the file, no directory */ r->filename = (char *)apr_filepath_name_get(r->uri); /* Only if sub-request for a directory, most likely from mod_dir */ if (r->main && r->main->filename && (!apr_filepath_name_get(r->main->filename) || !strlen(apr_filepath_name_get(r->main->filename)))) { /* The filename from the main request will be set to what should * be picked up, aliases included. Tomcat will need to know about * those aliases or things won't work for them. Normal files should * be fine. */ /* Need absolute path to stat */ if (apr_filepath_merge(&r->filename, r->main->filename, r->filename, APR_FILEPATH_SECUREROOT | APR_FILEPATH_TRUENAME, r->pool) != APR_SUCCESS) { return DECLINED; /* We should never get here, very bad */ } /* Stat the file so that mod_dir knows it's there */ apr_stat(&r->finfo, r->filename, APR_FINFO_TYPE, r->pool); } return OK; } return DECLINED; } static void jk_register_hooks(apr_pool_t * p) { ap_hook_post_config(jk_post_config, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_child_init(jk_child_init, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_translate_name(jk_translate, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_map_to_storage(jk_map_to_storage, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_handler(jk_handler, NULL, NULL, APR_HOOK_MIDDLE); ap_hook_log_transaction(request_log_transaction, NULL, NULL, APR_HOOK_MIDDLE); } module AP_MODULE_DECLARE_DATA jk_module = { STANDARD20_MODULE_STUFF, NULL, /* dir config creater */ NULL, /* dir merger --- default is to override */ create_jk_config, /* server config */ merge_jk_config, /* merge server config */ jk_cmds, /* command ap_table_t */ jk_register_hooks /* register hooks */ }; tomcat-connectors-1.2.41-src/native/apache-2.0/bldjk54.qclsrc0000644000000000000020000002415611660660436022007 0ustar rootbinPGM CRTCMOD MODULE(MOD_JK/MOD_JK) + SRCSTMF('/home/apache/jk/native/apache-2.0/mod_jk.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('mod_jk.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_AJP_COM) + SRCSTMF('/home/apache/jk/native/common/jk_ajp_common.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_ajp_common.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_AJP12_W) + SRCSTMF('/home/apache/jk/native/common/jk_ajp12_worker.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_ajp12_worker.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_AJP13) + SRCSTMF('/home/apache/jk/native/common/jk_ajp13.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' + 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_ajp13.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_AJP13_W) + SRCSTMF('/home/apache/jk/native/common/jk_ajp13_worker.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_ajp13_worker.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_AJP14) + SRCSTMF('/home/apache/jk/native/common/jk_ajp14.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_ajp14.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_AJP14_W) + SRCSTMF('/home/apache/jk/native/common/jk_ajp14_worker.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_ajp14_worker.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_CONNECT) + SRCSTMF('/home/apache/jk/native/common/jk_connect.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT' + 'USE_SO_RCVTIMEO' + 'USE_SO_SNDTIMEO' ) + TEXT('jk_connect.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_CONTEXT) + SRCSTMF('/home/apache/jk/native/common/jk_context.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_context.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_LB_WORK) + SRCSTMF('/home/apache/jk/native/common/jk_lb_worker.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_lb_worker.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_MAP) + SRCSTMF('/home/apache/jk/native/common/jk_map.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_map.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_MD5) + SRCSTMF('/home/apache/jk/native/common/jk_md5.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_md5.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_MSG_BUF) + SRCSTMF('/home/apache/jk/native/common/jk_msg_buff.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_msg_buff.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_POOL) + SRCSTMF('/home/apache/jk/native/common/jk_pool.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_pool.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_SOCKBUF) + SRCSTMF('/home/apache/jk/native/common/jk_sockbuf.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_sockbuf.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_URI_W_M) + SRCSTMF('/home/apache/jk/native/common/jk_uri_worker_map.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_uri_worker_map.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_URL) + SRCSTMF('/home/apache/jk/native/common/jk_url.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_url.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_UTIL) + SRCSTMF('/home/apache/jk/native/common/jk_util.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_util.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_WORKER) + SRCSTMF('/home/apache/jk/native/common/jk_worker.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_worker.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_STATUS) + SRCSTMF('/home/apache/jk/native/common/jk_status.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_status.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTCMOD MODULE(MOD_JK/JK_SHM) + SRCSTMF('/home/apache/jk/native/common/jk_shm.c') + DEFINE('AS400' 'AS400_UTF8' 'HAVE_APR' + '_XOPEN_SOURCE=520' 'USE_APACHE_MD5' '_REENTRANT') + TEXT('jk_shm.c') + OPTIMIZE(40) + LOCALETYPE(*LOCALEUTF) + SYSIFCOPT(*IFSIO) + LANGLVL(*EXTENDED) + TERASPACE(*YES) + TGTRLS(*CURRENT) + INCDIR('/home/apache/jk/native/common' '/QIBM/ProdData/HTTPA/Include') CRTSRVPGM SRVPGM(MOD_JK/MOD_JK) + MODULE(MOD_JK/MOD_JK + MOD_JK/JK_AJP_COM MOD_JK/JK_AJP12_W + MOD_JK/JK_AJP13 MOD_JK/JK_AJP13_W + MOD_JK/JK_AJP14 MOD_JK/JK_AJP14_W + MOD_JK/JK_CONNECT MOD_JK/JK_CONTEXT + MOD_JK/JK_LB_WORK + MOD_JK/JK_MAP MOD_JK/JK_MD5 + MOD_JK/JK_MSG_BUF MOD_JK/JK_POOL + MOD_JK/JK_SOCKBUF MOD_JK/JK_URI_W_M + MOD_JK/JK_URL + MOD_JK/JK_UTIL MOD_JK/JK_WORKER + MOD_JK/JK_STATUS MOD_JK/JK_SHM) + EXPORT(*SRCFILE) + BNDDIR() + TGTRLS(*CURRENT) + SRCFILE(MOD_JK/QSRVSRC) + SRCMBR(MOD_JK) + USRPRF(*USER) + BNDSRVPGM(QHTTPSVR/QZSRAPR QHTTPSVR/QZSRCORE + QHTTPSVR/QZSRXMLP QHTTPSVR/QZSRSDBM) + TEXT('Apache Tomcat mod_jk connector module') ENDPGM tomcat-connectors-1.2.41-src/native/apache-2.0/config.m40000644000000000000020000000246711443453113021036 0ustar rootbindnl -------------------------------------------------------- -*- autoconf -*- dnl Licensed to the Apache Software Foundation (ASF) under one or more dnl contributor license agreements. See the NOTICE file distributed with dnl this work for additional information regarding copyright ownership. dnl The ASF licenses this file to You under the Apache License, Version 2.0 dnl (the "License"); you may not use this file except in compliance with dnl the License. You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. AC_MSG_CHECKING(for mod_jk module) AC_ARG_WITH(mod_jk, [ --with-mod_jk Include the mod_jk (static).], [ modpath_current=modules/jk module=jk libname=lib_jk.la BUILTIN_LIBS="$BUILTIN_LIBS $modpath_current/$libname" cat >>$modpath_current/modules.mk</dev/null || true echo "buildconf: ${LIBTOOLIZE:-libtoolize} --automake --copy" ${LIBTOOLIZE:-libtoolize} --automake --copy echo "buildconf: aclocal" #aclocal --acdir=`aclocal --print-ac-dir` #aclocal --acdir=/usr/local/share/aclocal aclocal echo "buildconf: autoheader" autoheader echo "buildconf: automake -a --foreign --copy" automake -a --foreign --copy echo "buildconf: autoconf" autoconf rm -rf autom4te.cache tomcat-connectors-1.2.41-src/native/STATUS.txt0000644000000000000020000000500512555244512017372 0ustar rootbin Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. TOMCAT CONNECTORS (JK) STATUS: -*-text-*- Last modified at [$Date: 2015-07-26 21:55:38 +0100 (Sun, 26 Jul 2015) $] Release: 1.2.41 : in development 1.2.40 : released April 15, 2014 1.2.39 : released March 11, 2014 1.2.38 : not released 1.2.37 : released May 31, 2012 1.2.36 : released May 14, 2012 1.2.35 : released March 24, 2012 1.2.34 : not released 1.2.33 : released March 13, 2012 1.2.32 : released July 8, 2011 1.2.31 : released November 1, 2010 1.2.30 : released March 1, 2010 1.2.29 : released February 26, 2010, withdrawn February 27, 2010 1.2.28 : released March 22, 2009 1.2.27 : released October 28, 2008 1.2.26 : released December 21, 2007 1.2.25 : released August 7, 2007 1.2.24 : released July 27, 2007, withdrawn August 2, 2007 1.2.23 : released May 18, 2007 1.2.22 : released April 17, 2007 1.2.21 : released March 1, 2007 1.2.20 : released December 10, 2006 1.2.19 : released September 17, 2006 1.2.18 : released July, 2006 1.2.17 : not released 1.2.16 : not released 1.2.15 : released November 8, 2005 1.2.14 : released July 13, 2005 1.2.13 : released May 16, 2005 1.2.12 : released May 7, 2005 1.2.11 : released April 29, 2005 1.2.10 : released March 30, 2005 1.2.9 : not released 1.2.8 : released December 24, 2004 1.2.7 : not released 1.2.6 : released July 23, 2004 1.2.5 : released September 30, 2003 1.2.4 : released May 27, 2003 1.2.3 : released May 16, 2003 1.2.2 : released December 17, 2002 RELEASE SHOWSTOPPERS: RELEASE NON-SHOWSTOPPERS BUT WOULD BE REAL NICE TO WRAP THESE UP: STUFF FOR THE FUTURE: * enter mature phase ... ? tomcat-connectors-1.2.41-src/native/scripts/0000755000000000000020000000000012555256552017304 5ustar rootbintomcat-connectors-1.2.41-src/native/scripts/build/0000755000000000000020000000000012555256552020403 5ustar rootbintomcat-connectors-1.2.41-src/native/scripts/build/unix/0000755000000000000020000000000012555256562021367 5ustar rootbintomcat-connectors-1.2.41-src/native/scripts/build/unix/buildcheck.sh0000755000000000000020000000406311725744303024017 0ustar rootbin#! /bin/sh # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. echo "buildconf: checking installation..." # autoconf 2.59 or newer ac_version=`${AUTOCONF:-autoconf} --version 2>/dev/null|sed -e 's/^[^0-9]*//;s/[a-z]* *$//;q'` if test -z "$ac_version"; then echo "buildconf: autoconf not found." echo " You need autoconf version 2.59 or newer installed" echo " to build mod_jk from SVN." exit 1 fi IFS=.; set $ac_version; IFS=' ' if test "$1" = "2" -a "$2" -lt "59" || test "$1" -lt "2"; then echo "buildconf: autoconf version $ac_version found." echo " You need autoconf version 2.59 or newer installed" echo " to build mod_jk from SVN." exit 1 else echo "buildconf: autoconf version $ac_version (ok)" fi ac_version=`${LIBTOOL:-libtool} --version 2>/dev/null|sed -e 's/^[^0-9]*//;s/[a-z]* *$//;s/(.*//;q'` if test -z "$ac_version"; then echo "buildconf: libtool not found." echo " You need libtool version 1.4 or newer installed" echo " to build mod_jk from SVN." exit 1 fi IFS=.; set $ac_version; IFS=' ' if test "$1" = "1" -a "$2" -lt "4" || test "$1" -lt "1"; then echo "buildconf: libtool version $ac_version found." echo " You need libtool version 1.4 or newer installed" echo " to build mod_jk from SVN." exit 1 else echo "buildconf: libtool version $ac_version (ok)" fi exit 0 tomcat-connectors-1.2.41-src/native/scripts/build/unix/config.sub0000755000000000000020000010541212303362243023336 0ustar rootbin#! /bin/sh # Configuration validation subroutine script. # Copyright 1992-2014 Free Software Foundation, Inc. timestamp='2014-01-01' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # Please send patches with a ChangeLog entry to config-patches@gnu.org. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright 1992-2014 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze*) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 ;; -lynx*5) os=-lynxos5 ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | aarch64 | aarch64_be \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arceb \ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ | avr | avr32 \ | be32 | be64 \ | bfin \ | c4x | c8051 | clipper \ | d10v | d30v | dlx | dsp16xx \ | epiphany \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipsr5900 | mipsr5900el \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nds32 | nds32le | nds32be \ | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 \ | or1k | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ | pyramid \ | rl78 | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu \ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | we32k \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; c54x) basic_machine=tic54x-unknown ;; c55x) basic_machine=tic55x-unknown ;; c6x) basic_machine=tic6x-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; strongarm | thumb | xscale) basic_machine=arm-unknown ;; xgate) basic_machine=$basic_machine-unknown os=-none ;; xscaleeb) basic_machine=armeb-unknown ;; xscaleel) basic_machine=armel-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | aarch64-* | aarch64_be-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | be32-* | be64-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* \ | c8051-* | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | microblaze-* | microblazeel-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipsr5900-* | mipsr5900el-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nds32-* | nds32le-* | nds32be-* \ | nios-* | nios2-* | nios2eb-* | nios2el-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | open8-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ | pyramid-* \ | rl78-* | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \ | tahoe-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile*-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c54x-*) basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c55x-*) basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c6x-*) basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16 | cr16-*) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze*) basic_machine=microblaze-xilinx ;; mingw64) basic_machine=x86_64-pc os=-mingw64 ;; mingw32) basic_machine=i686-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc os=-msys ;; mvs) basic_machine=i370-ibm os=-mvs ;; nacl) basic_machine=le32-unknown os=-nacl ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; neo-tandem) basic_machine=neo-tandem ;; nse-tandem) basic_machine=nse-tandem ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos | rdos64) basic_machine=x86_64-pc os=-rdos ;; rdos32) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; strongarm-* | thumb-*) basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tile*) basic_machine=$basic_machine-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* | -plan9* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -bitrig* | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; c8051-*) os=-elf ;; hexagon-*) os=-elf ;; tic54x-*) os=-coff ;; tic55x-*) os=-coff ;; tic6x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or1k-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: tomcat-connectors-1.2.41-src/native/scripts/build/unix/missing0000755000000000000020000001533012555256562022770 0ustar rootbin#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2013-10-28.13; # UTC # Copyright (C) 1996-2013 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=http://www.perl.org/ flex_URL=http://flex.sourceforge.net/ gnu_software_URL=http://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: tomcat-connectors-1.2.41-src/native/scripts/build/unix/ltmain.sh0000644000000000000020000105204412555256557023221 0ustar rootbin # libtool (GNU libtool) 2.4.2 # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, # 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --no-quiet, --no-silent # print informational messages (default) # --no-warn don't display warning messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print more informational messages than default # --no-verbose don't print the extra informational messages # --version print version information # -h, --help, --help-all print short, long, or detailed help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. When passed as first option, # `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.4.2 Debian-2.4.2-1.7ubuntu1 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . # GNU libtool home page: . # General help using GNU software: . PROGRAM=libtool PACKAGE=libtool VERSION="2.4.2 Debian-2.4.2-1.7ubuntu1" TIMESTAMP="" package_revision=1.3337 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } # NLS nuisances: We save the old values to restore during execute mode. lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done LC_ALL=C LANGUAGE=C export LANGUAGE LC_ALL $lt_unset CDPATH # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" : ${CP="cp -f"} test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { func_dirname_result=`$ECHO "${1}" | $SED "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_dirname may be replaced by extended shell implementation # func_basename file func_basename () { func_basename_result=`$ECHO "${1}" | $SED "$basename"` } # func_basename may be replaced by extended shell implementation # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "${1}" | $SED -e "$basename"` } # func_dirname_and_basename may be replaced by extended shell implementation # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname may be replaced by extended shell implementation # These SED scripts presuppose an absolute path with a trailing slash. pathcar='s,^/\([^/]*\).*$,\1,' pathcdr='s,^/[^/]*,,' removedotparts=':dotsl s@/\./@/@g t dotsl s,/\.$,/,' collapseslashes='s@/\{1,\}@/@g' finalslash='s,/*$,/,' # func_normal_abspath PATH # Remove doubled-up and trailing slashes, "." path components, # and cancel out any ".." path components in PATH after making # it an absolute path. # value returned in "$func_normal_abspath_result" func_normal_abspath () { # Start from root dir and reassemble the path. func_normal_abspath_result= func_normal_abspath_tpath=$1 func_normal_abspath_altnamespace= case $func_normal_abspath_tpath in "") # Empty path, that just means $cwd. func_stripname '' '/' "`pwd`" func_normal_abspath_result=$func_stripname_result return ;; # The next three entries are used to spot a run of precisely # two leading slashes without using negated character classes; # we take advantage of case's first-match behaviour. ///*) # Unusual form of absolute path, do nothing. ;; //*) # Not necessarily an ordinary path; POSIX reserves leading '//' # and for example Cygwin uses it to access remote file shares # over CIFS/SMB, so we conserve a leading double slash if found. func_normal_abspath_altnamespace=/ ;; /*) # Absolute path, do nothing. ;; *) # Relative path, prepend $cwd. func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath ;; esac # Cancel out all the simple stuff to save iterations. We also want # the path to end with a slash for ease of parsing, so make sure # there is one (and only one) here. func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"` while :; do # Processed it all yet? if test "$func_normal_abspath_tpath" = / ; then # If we ascended to the root using ".." the result may be empty now. if test -z "$func_normal_abspath_result" ; then func_normal_abspath_result=/ fi break fi func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcar"` func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \ -e "$pathcdr"` # Figure out what to do with it case $func_normal_abspath_tcomponent in "") # Trailing empty path component, ignore it. ;; ..) # Parent dir; strip last assembled component from result. func_dirname "$func_normal_abspath_result" func_normal_abspath_result=$func_dirname_result ;; *) # Actual path component, append it. func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent ;; esac done # Restore leading double-slash if one was found on entry. func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result } # func_relative_path SRCDIR DSTDIR # generates a relative path from SRCDIR to DSTDIR, with a trailing # slash if non-empty, suitable for immediately appending a filename # without needing to append a separator. # value returned in "$func_relative_path_result" func_relative_path () { func_relative_path_result= func_normal_abspath "$1" func_relative_path_tlibdir=$func_normal_abspath_result func_normal_abspath "$2" func_relative_path_tbindir=$func_normal_abspath_result # Ascend the tree starting from libdir while :; do # check if we have found a prefix of bindir case $func_relative_path_tbindir in $func_relative_path_tlibdir) # found an exact match func_relative_path_tcancelled= break ;; $func_relative_path_tlibdir*) # found a matching prefix func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir" func_relative_path_tcancelled=$func_stripname_result if test -z "$func_relative_path_result"; then func_relative_path_result=. fi break ;; *) func_dirname $func_relative_path_tlibdir func_relative_path_tlibdir=${func_dirname_result} if test "x$func_relative_path_tlibdir" = x ; then # Have to descend all the way to the root! func_relative_path_result=../$func_relative_path_result func_relative_path_tcancelled=$func_relative_path_tbindir break fi func_relative_path_result=../$func_relative_path_result ;; esac done # Now calculate path; take care to avoid doubling-up slashes. func_stripname '' '/' "$func_relative_path_result" func_relative_path_result=$func_stripname_result func_stripname '/' '/' "$func_relative_path_tcancelled" if test "x$func_stripname_result" != x ; then func_relative_path_result=${func_relative_path_result}/${func_stripname_result} fi # Normalisation. If bindir is libdir, return empty string, # else relative path ending with a slash; either way, target # file name can be directly appended. if test ! -z "$func_relative_path_result"; then func_stripname './' '' "$func_relative_path_result/" func_relative_path_result=$func_stripname_result fi } # The name of this program: func_dirname_and_basename "$progpath" progname=$func_basename_result # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=${PATH_SEPARATOR-:} for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution that turns a string into a regex matching for the # string literally. sed_make_literal_regex='s,[].[^$\\*\/],\\&,g' # Sed substitution that converts a w32 file name or path # which contains forward slashes, into one that contains # (escaped) backslashes. A very naive implementation. lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname: ${opt_mode+$opt_mode: }$*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"` done my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "$my_tmpdir" } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "$1" | $SED \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_tr_sh # Turn $1 into a string suitable for a shell variable name. # Result is stored in $func_tr_sh_result. All characters # not in the set a-zA-Z0-9_ are replaced with '_'. Further, # if $1 begins with a digit, a '_' is prepended as well. func_tr_sh () { case $1 in [0-9]* | *[!a-zA-Z0-9_]*) func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'` ;; * ) func_tr_sh_result=$1 ;; esac } # func_version # Echo version message to standard output and exit. func_version () { $opt_debug $SED -n '/(C)/!b go :more /\./!{ N s/\n# / / b more } :go /^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $opt_debug $SED -n '/^# Usage:/,/^# *.*--help/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" echo $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help [NOEXIT] # Echo long help message to standard output and exit, # unless 'noexit' is passed as argument. func_help () { $opt_debug $SED -n '/^# Usage:/,/# Report bugs to/ { :print s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/ p d } /^# .* home page:/b print /^# General help using/b print ' < "$progpath" ret=$? if test -z "$1"; then exit $ret fi } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { $opt_debug func_error "missing argument for $1." exit_cmd=exit } # func_split_short_opt shortopt # Set func_split_short_opt_name and func_split_short_opt_arg shell # variables after splitting SHORTOPT after the 2nd character. func_split_short_opt () { my_sed_short_opt='1s/^\(..\).*$/\1/;q' my_sed_short_rest='1s/^..\(.*\)$/\1/;q' func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"` func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"` } # func_split_short_opt may be replaced by extended shell implementation # func_split_long_opt longopt # Set func_split_long_opt_name and func_split_long_opt_arg shell # variables after splitting LONGOPT at the `=' sign. func_split_long_opt () { my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^--[^=]*=//' func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"` func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"` } # func_split_long_opt may be replaced by extended shell implementation exit_cmd=: magic="%%%MAGIC variable%%%" magic_exe="%%%MAGIC EXE variable%%%" # Global variables. nonopt= preserve_args= lo2o="s/\\.lo\$/.${objext}/" o2lo="s/\\.${objext}\$/.lo/" extracted_archives= extracted_serial=0 # If this variable is set in any of the actions, the command in it # will be execed at the end. This prevents here-documents from being # left over by shells. exec_cmd= # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "${1}=\$${1}\${2}" } # func_append may be replaced by extended shell implementation # func_append_quoted var value # Quote VALUE and append to the end of shell variable VAR, separated # by a space. func_append_quoted () { func_quote_for_eval "${2}" eval "${1}=\$${1}\\ \$func_quote_for_eval_result" } # func_append_quoted may be replaced by extended shell implementation # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "${@}"` } # func_arith may be replaced by extended shell implementation # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len` } # func_len may be replaced by extended shell implementation # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"` } # func_lo2o may be replaced by extended shell implementation # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'` } # func_xform may be replaced by extended shell implementation # func_fatal_configuration arg... # Echo program name prefixed message to standard error, followed by # a configuration failure hint, and exit. func_fatal_configuration () { func_error ${1+"$@"} func_error "See the $PACKAGE documentation for more information." func_fatal_error "Fatal configuration error." } # func_config # Display the configuration for all the tags in this script. func_config () { re_begincf='^# ### BEGIN LIBTOOL' re_endcf='^# ### END LIBTOOL' # Default configuration. $SED "1,/$re_begincf CONFIG/d;/$re_endcf CONFIG/,\$d" < "$progpath" # Now print the configurations for the tags. for tagname in $taglist; do $SED -n "/$re_begincf TAG CONFIG: $tagname\$/,/$re_endcf TAG CONFIG: $tagname\$/p" < "$progpath" done exit $? } # func_features # Display the features supported by this script. func_features () { echo "host: $host" if test "$build_libtool_libs" = yes; then echo "enable shared libraries" else echo "disable shared libraries" fi if test "$build_old_libs" = yes; then echo "enable static libraries" else echo "disable static libraries" fi exit $? } # func_enable_tag tagname # Verify that TAGNAME is valid, and either flag an error and exit, or # enable the TAGNAME tag. We also add TAGNAME to the global $taglist # variable here. func_enable_tag () { # Global variable: tagname="$1" re_begincf="^# ### BEGIN LIBTOOL TAG CONFIG: $tagname\$" re_endcf="^# ### END LIBTOOL TAG CONFIG: $tagname\$" sed_extractcf="/$re_begincf/,/$re_endcf/p" # Validate tagname. case $tagname in *[!-_A-Za-z0-9,/]*) func_fatal_error "invalid tag name: $tagname" ;; esac # Don't test for the "default" C tag, as we know it's # there but not specially marked. case $tagname in CC) ;; *) if $GREP "$re_begincf" "$progpath" >/dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Option defaults: opt_debug=: opt_dry_run=false opt_config=false opt_preserve_dup_deps=false opt_features=false opt_finish=false opt_help=false opt_help_all=false opt_silent=: opt_warning=: opt_verbose=: opt_silent=false opt_verbose=false # Parse options once, thoroughly. This comes as soon as possible in the # script to make things like `--version' happen as quickly as we can. { # this just eases exit handling while test $# -gt 0; do opt="$1" shift case $opt in --debug|-x) opt_debug='set -x' func_echo "enabling shell trace mode" $opt_debug ;; --dry-run|--dryrun|-n) opt_dry_run=: ;; --config) opt_config=: func_config ;; --dlopen|-dlopen) optarg="$1" opt_dlopen="${opt_dlopen+$opt_dlopen }$optarg" shift ;; --preserve-dup-deps) opt_preserve_dup_deps=: ;; --features) opt_features=: func_features ;; --finish) opt_finish=: set dummy --mode finish ${1+"$@"}; shift ;; --help) opt_help=: ;; --help-all) opt_help_all=: opt_help=': help-all' ;; --mode) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_mode="$optarg" case $optarg in # Valid mode arguments: clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac shift ;; --no-silent|--no-quiet) opt_silent=false func_append preserve_args " $opt" ;; --no-warning|--no-warn) opt_warning=false func_append preserve_args " $opt" ;; --no-verbose) opt_verbose=false func_append preserve_args " $opt" ;; --silent|--quiet) opt_silent=: func_append preserve_args " $opt" opt_verbose=false ;; --verbose|-v) opt_verbose=: func_append preserve_args " $opt" opt_silent=false ;; --tag) test $# = 0 && func_missing_arg $opt && break optarg="$1" opt_tag="$optarg" func_append preserve_args " $opt $optarg" func_enable_tag "$optarg" shift ;; -\?|-h) func_usage ;; --help) func_help ;; --version) func_version ;; # Separate optargs to long options: --*=*) func_split_long_opt "$opt" set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"} shift ;; # Separate non-argument short options: -\?*|-h*|-n*|-v*) func_split_short_opt "$opt" set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"} shift ;; --) break ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) set dummy "$opt" ${1+"$@"}; shift; break ;; esac done # Validate options: # save first non-option argument if test "$#" -gt 0; then nonopt="$opt" shift fi # preserve --debug test "$opt_debug" = : || func_append preserve_args " --debug" case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps ;; esac $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$opt_dlopen" && test "$opt_mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$opt_mode' for more information." } # Bail if the options were screwed $exit_cmd $EXIT_FAILURE } ## ----------- ## ## Main. ## ## ----------- ## # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_resolve_sysroot PATH # Replace a leading = in PATH with a sysroot. Store the result into # func_resolve_sysroot_result func_resolve_sysroot () { func_resolve_sysroot_result=$1 case $func_resolve_sysroot_result in =*) func_stripname '=' '' "$func_resolve_sysroot_result" func_resolve_sysroot_result=$lt_sysroot$func_stripname_result ;; esac } # func_replace_sysroot PATH # If PATH begins with the sysroot, replace it with = and # store the result into func_replace_sysroot_result. func_replace_sysroot () { case "$lt_sysroot:$1" in ?*:"$lt_sysroot"*) func_stripname "$lt_sysroot" '' "$1" func_replace_sysroot_result="=$func_stripname_result" ;; *) # Including no sysroot. func_replace_sysroot_result=$1 ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_append_quoted CC_quoted "$arg" done CC_expanded=`func_echo_all $CC` CC_quoted_expanded=`func_echo_all $CC_quoted` case "$@ " in " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \ " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T </dev/null` if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" | $SED -e "$lt_sed_naive_backslashify"` else func_convert_core_file_wine_to_w32_result= fi fi } # end: func_convert_core_file_wine_to_w32 # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and # $host is mingw, cygwin, or some other w32 environment. Relies on a correctly # configured wine environment available, with the winepath program in $build's # $PATH. Assumes ARG has no leading or trailing path separator characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. # Unconvertible file (directory) names in ARG are skipped; if no directory names # are convertible, then the result may be empty. func_convert_core_path_wine_to_w32 () { $opt_debug # unfortunately, winepath doesn't convert paths, only file names func_convert_core_path_wine_to_w32_result="" if test -n "$1"; then oldIFS=$IFS IFS=: for func_convert_core_path_wine_to_w32_f in $1; do IFS=$oldIFS func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f" if test -n "$func_convert_core_file_wine_to_w32_result" ; then if test -z "$func_convert_core_path_wine_to_w32_result"; then func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result" else func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result" fi fi done IFS=$oldIFS fi } # end: func_convert_core_path_wine_to_w32 # func_cygpath ARGS... # Wrapper around calling the cygpath program via LT_CYGPATH. This is used when # when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2) # $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or # (2), returns the Cygwin file name or path in func_cygpath_result (input # file name or path is assumed to be in w32 format, as previously converted # from $build's *nix or MSYS format). In case (3), returns the w32 file name # or path in func_cygpath_result (input file name or path is assumed to be in # Cygwin format). Returns an empty string on error. # # ARGS are passed to cygpath, with the last one being the file name or path to # be converted. # # Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH # environment variable; do not put it in $PATH. func_cygpath () { $opt_debug if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null` if test "$?" -ne 0; then # on failure, ensure result is empty func_cygpath_result= fi else func_cygpath_result= func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'" fi } #end: func_cygpath # func_convert_core_msys_to_w32 ARG # Convert file name or path ARG from MSYS format to w32 format. Return # result in func_convert_core_msys_to_w32_result. func_convert_core_msys_to_w32 () { $opt_debug # awkward: cmd appends spaces to result func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null | $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"` } #end: func_convert_core_msys_to_w32 # func_convert_file_check ARG1 ARG2 # Verify that ARG1 (a file name in $build format) was converted to $host # format in ARG2. Otherwise, emit an error message, but continue (resetting # func_to_host_file_result to ARG1). func_convert_file_check () { $opt_debug if test -z "$2" && test -n "$1" ; then func_error "Could not determine host file name corresponding to" func_error " \`$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_file_result="$1" fi } # end func_convert_file_check # func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH # Verify that FROM_PATH (a path in $build format) was converted to $host # format in TO_PATH. Otherwise, emit an error message, but continue, resetting # func_to_host_file_result to a simplistic fallback value (see below). func_convert_path_check () { $opt_debug if test -z "$4" && test -n "$3"; then func_error "Could not determine the host path corresponding to" func_error " \`$3'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This is a deliberately simplistic "conversion" and # should not be "improved". See libtool.info. if test "x$1" != "x$2"; then lt_replace_pathsep_chars="s|$1|$2|g" func_to_host_path_result=`echo "$3" | $SED -e "$lt_replace_pathsep_chars"` else func_to_host_path_result="$3" fi fi } # end func_convert_path_check # func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG # Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT # and appending REPL if ORIG matches BACKPAT. func_convert_path_front_back_pathsep () { $opt_debug case $4 in $1 ) func_to_host_path_result="$3$func_to_host_path_result" ;; esac case $4 in $2 ) func_append func_to_host_path_result "$3" ;; esac } # end func_convert_path_front_back_pathsep ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## # invoked via `$to_host_file_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # Result will be available in $func_to_host_file_result. # func_to_host_file ARG # Converts the file name ARG from $build format to $host format. Return result # in func_to_host_file_result. func_to_host_file () { $opt_debug $to_host_file_cmd "$1" } # end func_to_host_file # func_to_tool_file ARG LAZY # converts the file name ARG from $build format to toolchain format. Return # result in func_to_tool_file_result. If the conversion in use is listed # in (the comma separated) LAZY, no conversion takes place. func_to_tool_file () { $opt_debug case ,$2, in *,"$to_tool_file_cmd",*) func_to_tool_file_result=$1 ;; *) $to_tool_file_cmd "$1" func_to_tool_file_result=$func_to_host_file_result ;; esac } # end func_to_tool_file # func_convert_file_noop ARG # Copy ARG to func_to_host_file_result. func_convert_file_noop () { func_to_host_file_result="$1" } # end func_convert_file_noop # func_convert_file_msys_to_w32 ARG # Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_file_result. func_convert_file_msys_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_to_host_file_result="$func_convert_core_msys_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_w32 # func_convert_file_cygwin_to_w32 ARG # Convert file name ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_file_cygwin_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # because $build is cygwin, we call "the" cygpath in $PATH; no need to use # LT_CYGPATH in this case. func_to_host_file_result=`cygpath -m "$1"` fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_cygwin_to_w32 # func_convert_file_nix_to_w32 ARG # Convert file name ARG from *nix to w32 format. Requires a wine environment # and a working winepath. Returns result in func_to_host_file_result. func_convert_file_nix_to_w32 () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_file_wine_to_w32 "$1" func_to_host_file_result="$func_convert_core_file_wine_to_w32_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_w32 # func_convert_file_msys_to_cygwin ARG # Convert file name ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_file_msys_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then func_convert_core_msys_to_w32 "$1" func_cygpath -u "$func_convert_core_msys_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_msys_to_cygwin # func_convert_file_nix_to_cygwin ARG # Convert file name ARG from *nix to Cygwin format. Requires Cygwin installed # in a wine environment, working winepath, and LT_CYGPATH set. Returns result # in func_to_host_file_result. func_convert_file_nix_to_cygwin () { $opt_debug func_to_host_file_result="$1" if test -n "$1"; then # convert from *nix to w32, then use cygpath to convert from w32 to cygwin. func_convert_core_file_wine_to_w32 "$1" func_cygpath -u "$func_convert_core_file_wine_to_w32_result" func_to_host_file_result="$func_cygpath_result" fi func_convert_file_check "$1" "$func_to_host_file_result" } # end func_convert_file_nix_to_cygwin ############################################# # $build to $host PATH CONVERSION FUNCTIONS # ############################################# # invoked via `$to_host_path_cmd ARG' # # In each case, ARG is the path to be converted from $build to $host format. # The result will be available in $func_to_host_path_result. # # Path separators are also converted from $build format to $host format. If # ARG begins or ends with a path separator character, it is preserved (but # converted to $host format) on output. # # All path conversion functions are named using the following convention: # file name conversion function : func_convert_file_X_to_Y () # path conversion function : func_convert_path_X_to_Y () # where, for any given $build/$host combination the 'X_to_Y' value is the # same. If conversion functions are added for new $build/$host combinations, # the two new functions must follow this pattern, or func_init_to_host_path_cmd # will break. # func_init_to_host_path_cmd # Ensures that function "pointer" variable $to_host_path_cmd is set to the # appropriate value, based on the value of $to_host_file_cmd. to_host_path_cmd= func_init_to_host_path_cmd () { $opt_debug if test -z "$to_host_path_cmd"; then func_stripname 'func_convert_file_' '' "$to_host_file_cmd" to_host_path_cmd="func_convert_path_${func_stripname_result}" fi } # func_to_host_path ARG # Converts the path ARG from $build format to $host format. Return result # in func_to_host_path_result. func_to_host_path () { $opt_debug func_init_to_host_path_cmd $to_host_path_cmd "$1" } # end func_to_host_path # func_convert_path_noop ARG # Copy ARG to func_to_host_path_result. func_convert_path_noop () { func_to_host_path_result="$1" } # end func_convert_path_noop # func_convert_path_msys_to_w32 ARG # Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic # conversion to w32 is not available inside the cwrapper. Returns result in # func_to_host_path_result. func_convert_path_msys_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from ARG. MSYS # behavior is inconsistent here; cygpath turns them into '.;' and ';.'; # and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_msys_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_msys_to_w32 # func_convert_path_cygwin_to_w32 ARG # Convert path ARG from Cygwin to w32 format. Returns result in # func_to_host_file_result. func_convert_path_cygwin_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"` func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_cygwin_to_w32 # func_convert_path_nix_to_w32 ARG # Convert path ARG from *nix to w32 format. Requires a wine environment and # a working winepath. Returns result in func_to_host_file_result. func_convert_path_nix_to_w32 () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_to_host_path_result="$func_convert_core_path_wine_to_w32_result" func_convert_path_check : ";" \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" ";" "$1" fi } # end func_convert_path_nix_to_w32 # func_convert_path_msys_to_cygwin ARG # Convert path ARG from MSYS to Cygwin format. Requires LT_CYGPATH set. # Returns result in func_to_host_file_result. func_convert_path_msys_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # See func_convert_path_msys_to_w32: func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_msys_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_msys_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_msys_to_cygwin # func_convert_path_nix_to_cygwin ARG # Convert path ARG from *nix to Cygwin format. Requires Cygwin installed in a # a wine environment, working winepath, and LT_CYGPATH set. Returns result in # func_to_host_file_result. func_convert_path_nix_to_cygwin () { $opt_debug func_to_host_path_result="$1" if test -n "$1"; then # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_stripname : : "$1" func_to_host_path_tmp1=$func_stripname_result func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1" func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result" func_to_host_path_result="$func_cygpath_result" func_convert_path_check : : \ "$func_to_host_path_tmp1" "$func_to_host_path_result" func_convert_path_front_back_pathsep ":*" "*:" : "$1" fi } # end func_convert_path_nix_to_cygwin # func_mode_compile arg... func_mode_compile () { $opt_debug # Get the compilation command and the source file. base_compile= srcfile="$nonopt" # always keep a non-empty value in "srcfile" suppress_opt=yes suppress_output= arg_mode=normal libobj= later= pie_flag= for arg do case $arg_mode in arg ) # do not "continue". Instead, add this to base_compile lastarg="$arg" arg_mode=normal ;; target ) libobj="$arg" arg_mode=normal continue ;; normal ) # Accept any command-line options. case $arg in -o) test -n "$libobj" && \ func_fatal_error "you cannot specify \`-o' more than once" arg_mode=target continue ;; -pie | -fpie | -fPIE) func_append pie_flag " $arg" continue ;; -shared | -static | -prefer-pic | -prefer-non-pic) func_append later " $arg" continue ;; -no-suppress) suppress_opt=no continue ;; -Xcompiler) arg_mode=arg # the next one goes into the "base_compile" arg list continue # The current "srcfile" will either be retained or ;; # replaced later. I would guess that would be a bug. -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result lastarg= save_ifs="$IFS"; IFS=',' for arg in $args; do IFS="$save_ifs" func_append_quoted lastarg "$arg" done IFS="$save_ifs" func_stripname ' ' '' "$lastarg" lastarg=$func_stripname_result # Add the arguments to base_compile. func_append base_compile " $lastarg" continue ;; *) # Accept the current argument as the source file. # The previous "srcfile" becomes the current argument. # lastarg="$srcfile" srcfile="$arg" ;; esac # case $arg ;; esac # case $arg_mode # Aesthetically quote the previous argument. func_append_quoted base_compile "$lastarg" done # for arg case $arg_mode in arg) func_fatal_error "you must specify an argument for -Xcompile" ;; target) func_fatal_error "you must specify a target with \`-o'" ;; *) # Get the name of the library object. test -z "$libobj" && { func_basename "$srcfile" libobj="$func_basename_result" } ;; esac # Recognize several different file suffixes. # If the user specifies -o file.o, it is replaced with file.lo case $libobj in *.[cCFSifmso] | \ *.ada | *.adb | *.ads | *.asm | \ *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \ *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup) func_xform "$libobj" libobj=$func_xform_result ;; esac case $libobj in *.lo) func_lo2o "$libobj"; obj=$func_lo2o_result ;; *) func_fatal_error "cannot determine name of library object from \`$libobj'" ;; esac func_infer_tag $base_compile for arg in $later; do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no continue ;; -static) build_libtool_libs=no build_old_libs=yes continue ;; -prefer-pic) pic_mode=yes continue ;; -prefer-non-pic) pic_mode=no continue ;; esac done func_quote_for_eval "$libobj" test "X$libobj" != "X$func_quote_for_eval_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi func_append removelist " $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist func_append removelist " $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir func_append command " -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then func_append command " -o $obj" fi # Suppress compiler output if we already did a PIC compilation. func_append command "$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$opt_mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $opt_mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to build PIC objects only -prefer-non-pic try to build non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking -Wc,FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix-dir PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -bindir BINDIR specify path to binaries directory (for systems where libraries must be found in the PATH setting at runtime) -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$opt_mode'" ;; esac echo $ECHO "Try \`$progname --help' for more information about other modes." } # Now that we've collected a possible --mode arg, show help if necessary if $opt_help; then if test "$opt_help" = :; then func_mode_help else { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do func_mode_help done } | sed -n '1p; 2,$s/^Usage:/ or: /p' { func_help noexit for opt_mode in compile link execute install finish uninstall clean; do echo func_mode_help done } | sed '1d /^When reporting/,/^Report/{ H d } $x /information about other modes/d /more detailed .*MODE/d s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/' fi exit $? fi # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $opt_dlopen; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then func_append dir "/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -* | *.la | *.lo ) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_append_quoted args "$file" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" echo "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$opt_mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libs= libdirs= admincmds= for opt in "$nonopt" ${1+"$@"} do if test -d "$opt"; then func_append libdirs " $opt" elif test -f "$opt"; then if func_lalib_unsafe_p "$opt"; then func_append libs " $opt" else func_warning "\`$opt' is not a valid libtool archive" fi else func_fatal_error "invalid argument \`$opt'" fi done if test -n "$libs"; then if test -n "$lt_sysroot"; then sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"` sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;" else sysroot_cmd= fi # Remove sysroot references if $opt_dry_run; then for lib in $libs; do echo "removing references to $lt_sysroot and \`=' prefixes from $lib" done else tmpdir=`func_mktempdir` for lib in $libs; do sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \ > $tmpdir/tmp-la mv -f $tmpdir/tmp-la $lib done ${RM}r "$tmpdir" fi fi if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || func_append admincmds " $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then echo "----------------------------------------------------------------------" echo "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" echo "specify the full pathname of the library, or use the \`-LLIBDIR'" echo "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then echo " - add LIBDIR to the \`$shlibpath_var' environment variable" echo " during execution" fi if test -n "$runpath_var"; then echo " - add LIBDIR to the \`$runpath_var' environment variable" echo " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi echo echo "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) echo "more information, such as the ld(1), crle(1) and ld.so(8) manual" echo "pages." ;; *) echo "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac echo "----------------------------------------------------------------------" fi exit $EXIT_SUCCESS } test "$opt_mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. case $nonopt in *shtool*) :;; *) false;; esac; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" func_append install_prog "$func_quote_for_eval_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; *) install_cp=false ;; esac # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= no_mode=: for arg do arg2= if test -n "$dest"; then func_append files " $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) if $install_cp; then :; else prev=$arg fi ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then if test "x$prev" = x-m && test -n "$install_override_mode"; then arg2=$install_override_mode no_mode=false fi prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" func_append install_prog " $func_quote_for_eval_result" if test -n "$arg2"; then func_quote_for_eval "$arg2" fi func_append install_shared_prog " $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else func_quote_for_eval "$install_override_mode" func_append install_shared_prog " -m $func_quote_for_eval_result" fi fi if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. func_append staticlibs " $file" ;; *.la) func_resolve_sysroot "$file" file=$func_resolve_sysroot_result # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) func_append current_libdirs " $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) func_append future_libdirs " $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" func_append dir "$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && func_append staticlibs " $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $tool_oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$opt_mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif #if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4)) #pragma GCC diagnostic ignored \"-Wstrict-prototypes\" #endif /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP` for progfile in $progfiles; do func_to_tool_file "$progfile" func_convert_file_msys_to_w32 func_verbose "extracting global C symbols from \`$func_to_tool_file_result'" $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" case $host in *cygwin* | *mingw* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" eval "curr_lafile=\$libfile_$func_tr_sh_result" dlprefile_dlbasename="" if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then # Use subshell, to avoid clobbering current variable values dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"` if test -n "$dlprefile_dlname" ; then func_basename "$dlprefile_dlname" dlprefile_dlbasename="$func_basename_result" else # no lafile. user explicitly requested -dlpreopen . $sharedlib_from_linklib_cmd "$dlprefile" dlprefile_dlbasename=$sharedlib_from_linklib_result fi fi $opt_dry_run || { if test -n "$dlprefile_dlbasename" ; then eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"' else func_warning "Could not compute DLL name from $name" eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" } else # not an import lib $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } fi ;; *) $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'" } ;; esac done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else echo '/* NONE */' >> "$output_objdir/$my_dlsyms" fi echo >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; extern LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; LT_DLSYM_CONST lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac echo >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) func_append symtab_cflags " $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"` finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. # Despite the name, also deal with 64 bit binaries. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then func_to_tool_file "$1" func_convert_file_msys_to_w32 win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_cygming_dll_for_implib ARG # # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib () { $opt_debug sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"` } # func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs # # The is the core of a fallback implementation of a # platform-specific function to extract the name of the # DLL associated with the specified import library LIBNAME. # # SECTION_NAME is either .idata$6 or .idata$7, depending # on the platform and compiler that created the implib. # # Echos the name of the DLL associated with the # specified import library. func_cygming_dll_for_implib_fallback_core () { $opt_debug match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"` $OBJDUMP -s --section "$1" "$2" 2>/dev/null | $SED '/^Contents of section '"$match_literal"':/{ # Place marker at beginning of archive member dllname section s/.*/====MARK====/ p d } # These lines can sometimes be longer than 43 characters, but # are always uninteresting /:[ ]*file format pe[i]\{,1\}-/d /^In archive [^:]*:/d # Ensure marker is printed /^====MARK====/p # Remove all lines with less than 43 characters /^.\{43\}/!d # From remaining lines, remove first 43 characters s/^.\{43\}//' | $SED -n ' # Join marker and all lines until next marker into a single line /^====MARK====/ b para H $ b para b :para x s/\n//g # Remove the marker s/^====MARK====// # Remove trailing dots and whitespace s/[\. \t]*$// # Print /./p' | # we now have a list, one entry per line, of the stringified # contents of the appropriate section of all members of the # archive which possess that section. Heuristic: eliminate # all those which have a first or second character that is # a '.' (that is, objdump's representation of an unprintable # character.) This should work for all archives with less than # 0x302f exports -- but will fail for DLLs whose name actually # begins with a literal '.' or a single character followed by # a '.'. # # Of those that remain, print the first one. $SED -e '/^\./d;/^.\./d;q' } # func_cygming_gnu_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is a GNU/binutils-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_gnu_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'` test -n "$func_cygming_gnu_implib_tmp" } # func_cygming_ms_implib_p ARG # This predicate returns with zero status (TRUE) if # ARG is an MS-style import library. Returns # with nonzero status (FALSE) otherwise. func_cygming_ms_implib_p () { $opt_debug func_to_tool_file "$1" func_convert_file_msys_to_w32 func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'` test -n "$func_cygming_ms_implib_tmp" } # func_cygming_dll_for_implib_fallback ARG # Platform-specific function to extract the # name of the DLL associated with the specified # import library ARG. # # This fallback implementation is for use when $DLLTOOL # does not support the --identify-strict option. # Invoked by eval'ing the libtool variable # $sharedlib_from_linklib_cmd # Result is available in the variable # $sharedlib_from_linklib_result func_cygming_dll_for_implib_fallback () { $opt_debug if func_cygming_gnu_implib_p "$1" ; then # binutils import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"` elif func_cygming_ms_implib_p "$1" ; then # ms-generated import library sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"` else # unknown sharedlib_from_linklib_result="" fi } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" if test "$lock_old_archive_extraction" = yes; then lockfile=$f_ex_an_ar_oldlib.lock until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done fi func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \ 'stat=$?; rm -f "$lockfile"; exit $stat' if test "$lock_old_archive_extraction" = yes; then $opt_dry_run || rm -f "$lockfile" fi if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=${1-no} $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` $ECHO "\ # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } ECHO=\"$qECHO\" fi # Very basic option parsing. These options are (a) specific to # the libtool wrapper, (b) are identical between the wrapper # /script/ and the wrapper /executable/ which is used only on # windows platforms, and (c) all begin with the string "--lt-" # (application programs are unlikely to have options which match # this pattern). # # There are only two supported options: --lt-debug and # --lt-dump-script. There is, deliberately, no --lt-help. # # The first argument to this parsing function should be the # script's $0 value, followed by "$@". lt_option_debug= func_parse_lt_options () { lt_script_arg0=\$0 shift for lt_opt do case \"\$lt_opt\" in --lt-debug) lt_option_debug=1 ;; --lt-dump-script) lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\` test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=. lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\` cat \"\$lt_dump_D/\$lt_dump_F\" exit 0 ;; --lt-*) \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2 exit 1 ;; esac done # Print the debug banner immediately: if test -n \"\$lt_option_debug\"; then echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2 fi } # Used when --lt-debug. Prints its arguments to stdout # (redirection is the responsibility of the caller) func_lt_dump_args () { lt_dump_args_N=1; for lt_arg do \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\" lt_dump_args_N=\`expr \$lt_dump_args_N + 1\` done } # Core function for launching the target application func_exec_program_core () { " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2 func_lt_dump_args \${1+\"\$@\"} 1>&2 fi exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 } # A function to encapsulate launching the target application # Strips options in the --lt-* namespace from \$@ and # launches target application with the remaining arguments. func_exec_program () { case \" \$* \" in *\\ --lt-*) for lt_wr_arg do case \$lt_wr_arg in --lt-*) ;; *) set x \"\$@\" \"\$lt_wr_arg\"; shift;; esac shift done ;; esac func_exec_program_core \${1+\"\$@\"} } # Parse options func_parse_lt_options \"\$0\" \${1+\"\$@\"} # Find the directory that this script lives in. thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # fixup the dll searchpath if we need to. # # Fix the DLL searchpath if we need to. Do this before prepending # to shlibpath, because on Windows, both are PATH and uninstalled # libraries must come first. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\` export $shlibpath_var " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. func_exec_program \${1+\"\$@\"} fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include #else # include # include # ifdef __CYGWIN__ # include # endif #endif #include #include #include #include #include #include #include #include /* declarations of non-ANSI functions */ #if defined(__MINGW32__) # ifdef __STRICT_ANSI__ int _putenv (const char *); # endif #elif defined(__CYGWIN__) # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif /* #elif defined (other platforms) ... */ #endif /* portability defines, excluding path handling macros */ #if defined(_MSC_VER) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv # define S_IXUSR _S_IEXEC # ifndef _INTPTR_T_DEFINED # define _INTPTR_T_DEFINED # define intptr_t int # endif #elif defined(__MINGW32__) # define setmode _setmode # define stat _stat # define chmod _chmod # define getcwd _getcwd # define putenv _putenv #elif defined(__CYGWIN__) # define HAVE_SETENV # define FOPEN_WB "wb" /* #elif defined (other platforms) ... */ #endif #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif /* path handling portability macros */ #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #if defined(LT_DEBUGWRAPPER) static int lt_debug = 1; #else static int lt_debug = 0; #endif const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */ void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_debugprintf (const char *file, int line, const char *fmt, ...); void lt_fatal (const char *file, int line, const char *message, ...); static const char *nonnull (const char *s); static const char *nonempty (const char *s); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); char **prepare_spawn (char **argv); void lt_dump_script (FILE *f); EOF cat <= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n", nonempty (path)); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n", nonempty (wrapper)); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal (__FILE__, __LINE__, "getcwd failed: %s", nonnull (strerror (errno))); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { lt_debugprintf (__FILE__, __LINE__, "checking path component for symlinks: %s\n", tmp_pathspec); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { lt_fatal (__FILE__, __LINE__, "error accessing file \"%s\": %s", tmp_pathspec, nonnull (strerror (errno))); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal (__FILE__, __LINE__, "could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } void lt_debugprintf (const char *file, int line, const char *fmt, ...) { va_list args; if (lt_debug) { (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line); va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } } static void lt_error_core (int exit_status, const char *file, int line, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *file, int line, const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap); va_end (ap); } static const char * nonnull (const char *s) { return s ? s : "(null)"; } static const char * nonempty (const char *s) { return (s && !*s) ? "(empty)" : nonnull (s); } void lt_setenv (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_setenv) setting '%s' to '%s'\n", nonnull (name), nonnull (value)); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } void lt_update_exe_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_exe_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { lt_debugprintf (__FILE__, __LINE__, "(lt_update_lib_path) modifying '%s' by prepending '%s'\n", nonnull (name), nonnull (value)); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF case $host_os in mingw*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). Note that spawn() does not by itself call the command interpreter (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") : ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&v); v.dwPlatformId == VER_PLATFORM_WIN32_NT; }) ? "cmd.exe" : "command.com"). Instead it simply concatenates the arguments, separated by ' ', and calls CreateProcess(). We must quote the arguments since Win32 CreateProcess() interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a special way: - Space and tab are interpreted as delimiters. They are not treated as delimiters if they are surrounded by double quotes: "...". - Unescaped double quotes are removed from the input. Their only effect is that within double quotes, space and tab are treated like normal characters. - Backslashes not followed by double quotes are not special. - But 2*n+1 backslashes followed by a double quote become n backslashes followed by a double quote (n >= 0): \" -> " \\\" -> \" \\\\\" -> \\" */ #define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" #define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037" char ** prepare_spawn (char **argv) { size_t argc; char **new_argv; size_t i; /* Count number of arguments. */ for (argc = 0; argv[argc] != NULL; argc++) ; /* Allocate new argument vector. */ new_argv = XMALLOC (char *, argc + 1); /* Put quoted arguments into the new argument vector. */ for (i = 0; i < argc; i++) { const char *string = argv[i]; if (string[0] == '\0') new_argv[i] = xstrdup ("\"\""); else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL) { int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL); size_t length; unsigned int backslashes; const char *s; char *quoted_string; char *p; length = 0; backslashes = 0; if (quote_around) length++; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') length += backslashes + 1; length++; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) length += backslashes + 1; quoted_string = XMALLOC (char, length + 1); p = quoted_string; backslashes = 0; if (quote_around) *p++ = '"'; for (s = string; *s != '\0'; s++) { char c = *s; if (c == '"') { unsigned int j; for (j = backslashes + 1; j > 0; j--) *p++ = '\\'; } *p++ = c; if (c == '\\') backslashes++; else backslashes = 0; } if (quote_around) { unsigned int j; for (j = backslashes; j > 0; j--) *p++ = '\\'; *p++ = '"'; } *p = '\0'; new_argv[i] = quoted_string; } else new_argv[i] = (char *) string; } new_argv[argc] = NULL; return new_argv; } EOF ;; esac cat <<"EOF" void lt_dump_script (FILE* f) { EOF func_emit_wrapper yes | $SED -n -e ' s/^\(.\{79\}\)\(..*\)/\1\ \2/ h s/\([\\"]\)/\\\1/g s/$/\\n/ s/\([^\n]*\).*/ fputs ("\1", f);/p g D' cat <<"EOF" } EOF } # end: func_emit_cwrapperexe_src # func_win32_import_lib_p ARG # True if ARG is an import lib, as indicated by $file_magic_cmd func_win32_import_lib_p () { $opt_debug case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in *import*) : ;; *) false ;; esac } # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no bindir= dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in bindir) bindir="$arg" prev= continue ;; dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then func_append dlfiles " $arg" else func_append dlprefiles " $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) func_append deplibs " $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # func_append moreargs " $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) func_append rpath " $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) func_append xrpath " $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) func_append weak_libs " $arg" prev= continue ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) func_append compiler_flags " $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) func_append linker_flags " $qarg" func_append compiler_flags " $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -bindir) prev=bindir continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname "-L" '' "$arg" if test -z "$func_stripname_result"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "* | *" $arg "*) # Will only happen for absolute or sysroot arguments ;; *) # Preserve sysroot, but never include relative directories case $dir in [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;; *) func_append deplibs " -L$dir" ;; esac func_append lib_search_path " $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) func_append dllsearchpath ":$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework func_append deplibs " System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi func_append deplibs " $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot|--sysroot) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) func_append compiler_flags " $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) func_append new_inherited_linker_flags " $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; =*) func_stripname '=' '' "$dir" dir=$lt_sysroot$func_stripname_result ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $func_quote_for_eval_result" func_append compiler_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" func_append arg " $wl$func_quote_for_eval_result" func_append compiler_flags " $wl$func_quote_for_eval_result" func_append linker_flags " $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # Flags to be passed through unchanged, with rationale: # -64, -mips[0-9] enable 64-bit mode for the SGI compiler # -r[0-9][0-9]* specify processor for the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler # +DA*, +DD* enable 64-bit mode for the HP compiler # -q* compiler args for the IBM compiler # -m*, -t[45]*, -txscale* architecture-specific flags for GCC # -F/path path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* profiling flags for GCC # @file GCC response files # -tp=* Portland pgcc target processor selection # --sysroot=* for sysroot support # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-flto*|-fwhopr*|-fuse-linker-plugin) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" func_append compiler_flags " $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. func_append objs " $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then func_append dlfiles " $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. func_append dlprefiles " $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. func_append deplibs " $arg" func_append old_deplibs " $arg" continue ;; *.la) # A libtool-controlled library. func_resolve_sysroot "$arg" if test "$prev" = dlfiles; then # This library was specified with -dlopen. func_append dlfiles " $func_resolve_sysroot_result" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. func_append dlprefiles " $func_resolve_sysroot_result" prev= else func_append deplibs " $func_resolve_sysroot_result" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" func_to_tool_file "$output_objdir/" tool_output_objdir=$func_to_tool_file_result # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_preserve_dup_deps ; then case "$libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append libs " $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;; esac func_append pre_post_deps " $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= func_resolve_sysroot "$lib" case $lib in *.la) func_source "$func_resolve_sysroot_result" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do func_basename "$deplib" deplib_base=$func_basename_result case " $weak_libs " in *" $deplib_base "*) ;; *) func_append deplibs " $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \ |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append compiler_flags " $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) func_append new_inherited_linker_flags " $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" func_resolve_sysroot "$func_stripname_result" dir=$func_resolve_sysroot_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) func_append xrpath " $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) func_resolve_sysroot "$deplib" lib=$func_resolve_sysroot_result ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then echo $ECHO "*** Warning: Trying to link with static lib archive $deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because the file extensions .$libext of this argument makes me believe" echo "*** that it is just a static archive that I should not use here." else echo $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. func_append newdlprefiles " $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else func_append newdlfiles " $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && func_append dlfiles " $dlopen" test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. func_append convenience " $ladir/$objdir/$old_library" func_append old_convenience " $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= if test -n "$old_library" && { test "$prefer_static_libs" = yes || test "$prefer_static_libs,$installed" = "built,no"; }; then linklib=$old_library else for l in $old_library $library_names; do linklib="$l" done fi if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. func_append dlprefiles " $lib $dependency_libs" else func_append newdlfiles " $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$lt_sysroot$libdir" absdir="$lt_sysroot$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later func_append notinst_path " $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later func_append notinst_path " $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi case "$host" in # special handling for platforms with PE-DLLs. *cygwin* | *mingw* | *cegcc* ) # Linker will automatically link against shared library if both # static and shared are present. Therefore, ensure we extract # symbols from the import library if a shared library is present # (otherwise, the dlopen module name will be incorrect). We do # this by putting the import library name into $newdlprefiles. # We recover the dlopen module name by 'saving' the la file # name in a special purpose variable, and (later) extracting the # dlname from the la file. if test -n "$dlname"; then func_tr_sh "$dir/$linklib" eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname" func_append newdlprefiles " $dir/$linklib" else func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" fi ;; * ) # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then func_append newdlprefiles " $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ func_append dlpreconveniencelibs " $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then func_append newdlprefiles " $dir/$dlname" else func_append newdlprefiles " $dir/$linklib" fi ;; esac fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then func_append newlib_search_path " $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result" func_append newlib_search_path " $func_resolve_sysroot_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $deplib "*) func_append specialdeplibs " $deplib" ;; esac fi func_append tmp_libs " $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) func_append temp_rpath "$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded func_append notinst_deplibs " $lib" need_relink=no ;; *) if test "$installed" = no; then func_append notinst_deplibs " $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then echo if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) func_append compile_rpath " $absdir" ;; esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$opt_mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then echo echo "*** And there doesn't seem to be a static archive available" echo "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$absdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) func_append compile_shlibpath "$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$opt_mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) func_append finalize_shlibpath "$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) func_append add_dir " -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. echo $ECHO "*** Warning: This system can not link to static lib archive $lib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then echo "*** But as you try to build a module library, libtool will still create " echo "*** a static module, that should work as long as the dlopening application" echo "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) func_append xrpath " $temp_xrpath";; esac;; *) func_append temp_deplibs " $libdir";; esac done dependency_libs="$temp_deplibs" fi func_append newlib_search_path " $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" case $deplib in -L*) func_stripname '-L' '' "$deplib" func_resolve_sysroot "$func_stripname_result";; *) func_resolve_sysroot "$deplib" ;; esac if $opt_preserve_dup_deps ; then case "$tmp_libs " in *" $func_resolve_sysroot_result "*) func_append specialdeplibs " $func_resolve_sysroot_result" ;; esac fi func_append tmp_libs " $func_resolve_sysroot_result" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_resolve_sysroot "$deplib" deplib=$func_resolve_sysroot_result func_dirname "$deplib" "" "." dir=$func_dirname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) func_append lib_search_path " $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) func_append tmp_libs " $deplib" ;; esac ;; *) func_append tmp_libs " $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then func_append tmp_libs " $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" func_append objs "$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else echo $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" func_append libobjs " $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in # correct linux to gnu/linux during the next big refactor darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|qnx|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type \`$version_type'" ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) # correct to gnu/linux during the next big refactor func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. func_append verstring ":${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" func_append libobjs " $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$opt_mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi func_append removelist " $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then func_append oldlibs " $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"` # deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"` # dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do func_replace_sysroot "$libdir" func_append temp_xrpath " -R$func_replace_sysroot_result" case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) func_append dlfiles " $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) func_append dlprefiles " $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework func_append deplibs " System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then func_append deplibs " -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` $nocaseglob else potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null` fi for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) func_append newdeplibs " $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then func_append newdeplibs " $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes echo $ECHO "*** Warning: linker path does not have real file for library $a_deplib." echo "*** I have the capability to make that library automatically link in when" echo "*** you link to this library. But I can only do this if you have a" echo "*** shared version of the library, which you do not appear to have" echo "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. func_append newdeplibs " $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"` done fi case $tmp_deplibs in *[!\ \ ]*) echo if test "X$deplibs_check_method" = "Xnone"; then echo "*** Warning: inter-library dependencies are not supported in this platform." else echo "*** Warning: inter-library dependencies are not known to be supported." fi echo "*** All declared inter-library dependencies are being dropped." droppeddeps=yes ;; esac ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then echo echo "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" echo "*** a static module, that should work as long as the dlopening" echo "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then echo echo "*** However, this would only work if libtool was able to extract symbol" echo "*** lists from a program, using \`nm' or equivalent, but libtool could" echo "*** not find such a program. So, this module is probably useless." echo "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else echo "*** The inter-library dependencies that have been dropped here will be" echo "*** automatically added whenever a program is linked with this library" echo "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then echo echo "*** Since this library must not contain undefined symbols," echo "*** because either the platform does not support them or" echo "*** it was explicitly requested with -no-undefined," echo "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then # Remove ${wl} instances when linking with ld. # FIXME: should test the right _cmds variable. case $archive_cmds in *\$LD\ *) wl= ;; esac if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$opt_mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then func_replace_sysroot "$libdir" libdir=$func_replace_sysroot_result if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append dep_rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval "dep_rpath=\"$hardcode_libdir_flag_spec\"" fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do func_append linknames " $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" func_append delfiles " $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd1 in $cmds; do IFS="$save_ifs" # Take the normal branch if the nm_file_list_spec branch # doesn't work or if tool conversion is not needed. case $nm_file_list_spec~$to_tool_file_cmd in *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*) try_normal_branch=yes eval cmd=\"$cmd1\" func_len " $cmd" len=$func_len_result ;; *) try_normal_branch=no ;; esac if test "$try_normal_branch" = yes \ && { test "$len" -lt "$max_cmd_len" \ || test "$max_cmd_len" -le -1; } then func_show_eval "$cmd" 'exit $?' skipped_export=false elif test -n "$nm_file_list_spec"; then func_basename "$output" output_la=$func_basename_result save_libobjs=$libobjs save_output=$output output=${output_objdir}/${output_la}.nm func_to_tool_file "$output" libobjs=$nm_file_list_spec$func_to_tool_file_result func_append delfiles " $output" func_verbose "creating $NM input file list: $output" for obj in $save_libobjs; do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > "$output" eval cmd=\"$cmd1\" func_show_eval "$cmd" 'exit $?' output=$save_output libobjs=$save_libobjs skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) func_append tmp_deplibs " $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $convenience func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" func_append linker_flags " $flag" fi # Make a backup of the uninstalled library when relinking if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output func_basename "$output" output_la=$func_basename_result # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" echo 'INPUT (' > $output for obj in $save_libobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done echo ')' >> $output func_append delfiles " $output" func_to_tool_file "$output" output=$func_to_tool_file_result elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" >> $output done func_append delfiles " $output" func_to_tool_file "$output" output=$firstobj\"$file_list_spec$func_to_tool_file_result\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. reload_objs=$objlist eval concat_cmds=\"$reload_cmds\" else # All subsequent reloadable object files will link in # the last one created. reload_objs="$objlist $last_robj" eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=" $obj" func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ reload_objs="$objlist $last_robj" eval concat_cmds=\"\${concat_cmds}$reload_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi func_append delfiles " $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter func_append delfiles " $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append libobjs " $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$opt_mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$opt_mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'` else gentop="$output_objdir/${obj}x" func_append generated " $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # If we're not building shared, we need to use non_pic_objs test "$build_libtool_libs" != yes && libobjs="$non_pic_objects" # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) func_append compile_command " ${wl}-bind_at_load" func_append finalize_command " ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) func_append new_libs " -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) func_append new_libs " $deplib" ;; esac ;; *) func_append new_libs " $deplib" ;; esac done compile_deplibs="$new_libs" func_append compile_command " $compile_deplibs" func_append finalize_command " $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) func_append finalize_rpath " $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) func_append perm_rpath " $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) func_append dllsearchpath ":$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) func_append dllsearchpath ":$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) func_append hardcode_libdirs "$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" func_append rpath " $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) func_append finalize_perm_rpath " $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP` finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cegcc* | *mingw32ce*) # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway. wrappers_required=no ;; *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do func_append rpath "$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do func_append rpath "$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' if test -n "$postlink_cmds"; then func_to_tool_file "$output_objdir/$outputname" postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'` func_execute_cmds "$postlink_cmds" 'exit $?' fi # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then func_append oldobjs " $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $addlibs func_append oldobjs " $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_extract_archives $gentop $dlprefiles func_append oldobjs " $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else echo "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" func_append generated " $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" func_append oldobjs " $gentop/$newobj" ;; *) func_append oldobjs " $obj" ;; esac done fi func_to_tool_file "$oldlib" func_convert_file_msys_to_w32 tool_oldlib=$func_to_tool_file_result eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds elif test -n "$archiver_list_spec"; then func_verbose "using command file archive linking..." for obj in $oldobjs do func_to_tool_file "$obj" $ECHO "$func_to_tool_file_result" done > $output_objdir/$libname.libcmd func_to_tool_file "$output_objdir/$libname.libcmd" oldobjs=" $archiver_list_spec$func_to_tool_file_result" cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" func_resolve_sysroot "$deplib" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name" ;; -L*) func_stripname -L '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -L$func_replace_sysroot_result" ;; -R*) func_stripname -R '' "$deplib" func_replace_sysroot "$func_stripname_result" func_append newdependency_libs " -R$func_replace_sysroot_result" ;; *) func_append newdependency_libs " $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name" ;; *) func_append newdlfiles " $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlfiles " $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac func_append newdlprefiles " $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin # In fact, it would be nice if we could use this code for all target # systems that can't hard-code library paths into their executables # and that have no shared library path variable independent of PATH, # but it turns out we can't easily determine that from inspecting # libtool variables, so we have to hard-code the OSs to which it # applies here; at the moment, that means platforms that use the PE # object format with DLL files. See the long comment at the top of # tests/bindir.at for full details. tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) # If a -bindir argument was supplied, place the dll there. if test "x$bindir" != x ; then func_relative_path "$install_libdir" "$bindir" tdlname=$func_relative_path_result$dlname else # Otherwise fall back on heuristic. tdlname=../bin/$dlname fi ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$opt_mode" = link || test "$opt_mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) func_append RM " $arg"; rmforce=yes ;; -*) func_append RM " $arg" ;; *) func_append files " $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then odir="$objdir" else odir="$dir/$objdir" fi func_basename "$file" name="$func_basename_result" test "$opt_mode" = uninstall && odir="$dir" # Remember odir for removal later, being careful to avoid duplicates if test "$opt_mode" = clean; then case " $rmdirs " in *" $odir "*) ;; *) func_append rmdirs " $odir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do func_append rmfiles " $odir/$n" done test -n "$old_library" && func_append rmfiles " $odir/$old_library" case "$opt_mode" in clean) case " $library_names " in *" $dlname "*) ;; *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;; esac test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then func_append rmfiles " $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then func_append rmfiles " $dir/$non_pic_object" fi fi ;; *) if test "$opt_mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe func_append rmfiles " $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result func_append rmfiles " $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles func_append rmfiles " $odir/$name $odir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then func_append rmfiles " $odir/lt-$name" fi if test "X$noexename" != "X$name" ; then func_append rmfiles " $odir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$opt_mode" = uninstall || test "$opt_mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$opt_mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$opt_mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 tomcat-connectors-1.2.41-src/native/scripts/build/unix/install-sh0000755000000000000020000003325512555256562023403 0ustar rootbin#!/bin/sh # install - install a program, script, or datafile scriptversion=2011-11-20.07; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: tomcat-connectors-1.2.41-src/native/scripts/build/unix/config.guess0000755000000000000020000012353612303362243023702 0ustar rootbin#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2014 Free Software Foundation, Inc. timestamp='2014-02-12' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that # program. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD # # Please send patches with a ChangeLog entry to config-patches@gnu.org. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright 1992-2014 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="gnulibc1" ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } ;; or1k:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; or32:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; x86_64:Haiku:*:*) echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} exit ;; NSE-*:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; esac cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: tomcat-connectors-1.2.41-src/native/scripts/build/unix/compile0000755000000000000020000001624512555256562022755 0ustar rootbin#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2012-10-14.11; # UTC # Copyright (C) 1999-2013 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: tomcat-connectors-1.2.41-src/native/scripts/build/config_vars.mk0000644000000000000020000000157210666607673023246 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # libtool is given by Apache-2.0 when installed otherwise we provide it. LIBTOOL = $(SHELL) ../libtool tomcat-connectors-1.2.41-src/native/scripts/build/rules.mk0000644000000000000020000000222510666607673022074 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # That an extract of what is in APR. # # Compile commands #VPATH=.:../common COMPILE = $(CC) $(CFLAGS) LT_COMPILE = $(LIBTOOL) --mode=compile $(COMPILE) -c $< -o $@ # Implicit rules for creating outputs from input files .SUFFIXES: .SUFFIXES: .c .lo .o .slo .s .c.o: $(COMPILE) -c $< .s.o: $(COMPILE) -c $< .c.lo: $(LT_COMPILE) .s.lo: $(LT_COMPILE) .c.slo: $(SH_COMPILE) tomcat-connectors-1.2.41-src/native/scripts/build/jk_common.m40000644000000000000020000001027411066375725022625 0ustar rootbindnl -------------------------------------------------------- -*- autoconf -*- dnl Licensed to the Apache Software Foundation (ASF) under one or more dnl contributor license agreements. See the NOTICE file distributed with dnl this work for additional information regarding copyright ownership. dnl The ASF licenses this file to You under the Apache License, Version 2.0 dnl (the "License"); you may not use this file except in compliance with dnl the License. You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl dnl jk_common.m4: JK's general-purpose autoconf macros dnl Mostly taken from APR. dnl dnl dnl JK_CHECK_SIZEOF_EXTENDED(INCLUDES, TYPE [, CROSS_SIZE]) dnl dnl A variant of AC_CHECK_SIZEOF which allows the checking of dnl sizes of non-builtin types dnl AC_DEFUN([JK_CHECK_SIZEOF_EXTENDED], [changequote(<<,>>)dnl dnl The name to #define define(<>, translit(sizeof_$2, [a-z *], [A-Z_P]))dnl dnl The cache variable define(<>, translit(ac_cv_sizeof_$2, [ *],[

]))dnl changequote([, ])dnl AC_MSG_CHECKING(size of $2) AC_CACHE_VAL(AC_CV_NAME, [AC_TRY_RUN([#include $1 main() { FILE *f=fopen("conftestval","w"); if (!f) exit(1); fprintf(f, "%d\n", sizeof($2)); exit(0); }], AC_CV_NAME=`cat conftestval`, AC_CV_NAME=0, ifelse([$3],,, AC_CV_NAME=$3))])dnl AC_MSG_RESULT($AC_CV_NAME) AC_DEFINE_UNQUOTED(AC_TYPE_NAME, $AC_CV_NAME, [The size of ]$2) undefine([AC_TYPE_NAME])dnl undefine([AC_CV_NAME])dnl ]) dnl dnl JK_PREFIX_IF_MISSING(variable, prefix) dnl dnl Prefix all tokens in a variable with "prefix" unless dnl it is already there. dnl AC_DEFUN([JK_PREFIX_IF_MISSING], [ jk_new_val="" jk_val_changed=0 for i in $$1; do case $i in $2*) jk_new_val="$jk_new_val $i" ;; *) jk_new_val="$jk_new_val $2$i" jk_val_changed=1 ;; esac done if test $jk_val_changed = "1"; then AC_MSG_NOTICE(tokens in $1 have been prefixed with '[$2]') $1=$jk_new_val fi ]) dnl dnl Iteratively interpolate the contents of the second argument dnl until interpolation offers no new result. Then assign the dnl final result to $1. dnl dnl Example: dnl dnl foo=1 dnl bar='${foo}/2' dnl baz='${bar}/3' dnl JK_EXPAND_VAR(fraz, $baz) dnl $fraz is now "1/2/3" dnl AC_DEFUN([JK_EXPAND_VAR], [ jk_last= jk_cur="$2" while test "x${jk_cur}" != "x${jk_last}"; do jk_last="${jk_cur}" jk_cur=`eval "echo ${jk_cur}"` done $1="${jk_cur}" ]) dnl dnl JK_CONFIG_NICE(filename) dnl dnl Saves a snapshot of the configure command-line for later reuse dnl AC_DEFUN([JK_CONFIG_NICE], [ rm -f $1 cat >$1<> $1 fi if test -n "$CFLAGS"; then echo "CFLAGS=\"$CFLAGS\"; export CFLAGS" >> $1 fi if test -n "$CPPFLAGS"; then echo "CPPFLAGS=\"$CPPFLAGS\"; export CPPFLAGS" >> $1 fi if test -n "$LDFLAGS"; then echo "LDFLAGS=\"$LDFLAGS\"; export LDFLAGS" >> $1 fi if test -n "$LTFLAGS"; then echo "LTFLAGS=\"$LTFLAGS\"; export LTFLAGS" >> $1 fi if test -n "$LIBS"; then echo "LIBS=\"$LIBS\"; export LIBS" >> $1 fi if test -n "$INCLUDES"; then echo "INCLUDES=\"$INCLUDES\"; export INCLUDES" >> $1 fi if test -n "$NOTEST_CFLAGS"; then echo "NOTEST_CFLAGS=\"$NOTEST_CFLAGS\"; export NOTEST_CFLAGS" >> $1 fi if test -n "$NOTEST_CPPFLAGS"; then echo "NOTEST_CPPFLAGS=\"$NOTEST_CPPFLAGS\"; export NOTEST_CPPFLAGS" >> $1 fi if test -n "$NOTEST_LDFLAGS"; then echo "NOTEST_LDFLAGS=\"$NOTEST_LDFLAGS\"; export NOTEST_LDFLAGS" >> $1 fi if test -n "$NOTEST_LIBS"; then echo "NOTEST_LIBS=\"$NOTEST_LIBS\"; export NOTEST_LIBS" >> $1 fi # Retrieve command-line arguments. eval "set x $[0] $ac_configure_args" shift for arg do JK_EXPAND_VAR(arg, $arg) echo "\"[$]arg\" \\" >> $1 done echo '"[$]@"' >> $1 chmod +x $1 ])dnl tomcat-connectors-1.2.41-src/native/scripts/build/instdso.sh0000755000000000000020000000534410530276210022413 0ustar rootbin#!/bin/sh # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # # instdso.sh - install Apache DSO modules # # we use this instead of libtool --install because: # 1) on a few platforms libtool doesn't install DSOs exactly like we'd # want (weird names, doesn't remove DSO first) # 2) we never want the .la files copied, so we might as well copy # the .so files ourselves if test "$#" != "3"; then echo "wrong number of arguments to instdso.sh" echo "Usage: instdso.sh SH_LIBTOOL-value dso-name path-to-modules" exit 1 fi SH_LIBTOOL=`echo $1 | sed -e 's/^SH_LIBTOOL=//'` DSOARCHIVE=$2 DSOARCHIVE_BASENAME=`basename $2` TARGETDIR=$3 DSOBASE=`echo $DSOARCHIVE_BASENAME | sed -e 's/\.la$//'` TARGET_NAME="$DSOBASE.so" SYS=`uname -s` if test "$SYS" = "AIX" then # on AIX, shared libraries remain in storage even when # all processes using them have exited; standard practice # prior to installing a shared library is to rm -f first CMD="rm -f $TARGETDIR/$TARGET_NAME" echo $CMD $CMD || exit $? fi CMD="$SH_LIBTOOL --mode=install cp $DSOARCHIVE $TARGETDIR/" echo $CMD $CMD || exit $? if test "$SYS" = "OS/2" then # on OS/2, aplibtool --install doesn't copy the .la files & we can't # rename DLLs to have a .so extension or they won't load so none of the # steps below make sense. exit 0 fi if test -s "$TARGETDIR/$DSOARCHIVE_BASENAME" then DLNAME=`sed -n "/^dlname=/{s/.*='\([^']*\)'/\1/;p;}" $TARGETDIR/$DSOARCHIVE_BASENAME` LIBRARY_NAMES=`sed -n "/^library_names/{s/library_names='\([^']*\)'/\1/;p;}" $TARGETDIR/$DSOARCHIVE_BASENAME` LIBRARY_NAMES=`echo $LIBRARY_NAMES | sed -e "s/ *$DLNAME//g"` fi if test -z "$DLNAME" then echo "Warning! dlname not found in $TARGETDIR/$DSOARCHIVE_BASENAME." echo "Assuming installing a .so rather than a libtool archive." exit 0 fi if test -n "$LIBRARY_NAMES" then for f in $LIBRARY_NAMES do rm -f $TARGETDIR/$f done fi if test "$DLNAME" != "$TARGET_NAME" then mv $TARGETDIR/$DLNAME $TARGETDIR/$TARGET_NAME fi exit 0 tomcat-connectors-1.2.41-src/native/apache-1.3/0000755000000000000020000000000012555256552017335 5ustar rootbintomcat-connectors-1.2.41-src/native/apache-1.3/mod_jk.dsp0000644000000000000020000001661411660226567021317 0ustar rootbin# Microsoft Developer Studio Project File - Name="mod_jk" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=mod_jk - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "mod_jk.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 "mod_jk.mak" CFG="mod_jk - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "mod_jk - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "mod_jk - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "mod_jk - 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 /Zi /O2 /Oy- /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MOD_JK_EXPORTS" /FD /c # ADD CPP /nologo /MD /W3 /Zi /O2 /Oy- /I "..\common" /I "$(APACHE1_HOME)\include" /I "$(APACHE1_HOME)\src\include" /I "$(APACHE1_HOME)\src\os\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MOD_JK_EXPORTS" /Fd"Release\mod_jk_src" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 ApacheCore.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /base:"0x6A6B0000" /subsystem:windows /dll /debug /machine:I386 /out:"Release/mod_jk.so" /libpath:"$(APACHE1_HOME)\libexec" /libpath:"$(APACHE1_HOME)\src\CoreR" /libpath:"$(APACHE1_HOME)\src\Release" /opt:ref !ELSEIF "$(CFG)" == "mod_jk - 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 /MDd /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MOD_JK_EXPORTS" /FD /c # ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "..\common" /I "$(APACHE1_HOME)\include" /I "$(APACHE1_HOME)\src\include" /I "$(APACHE1_HOME)\src\os\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "MOD_JK_EXPORTS" /Fd"Debug\mod_jk_src" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 ApacheCore.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /base:"0x6A6B0000" /subsystem:windows /dll /incremental:no /debug /machine:I386 /out:"Debug/mod_jk.so" /libpath:"$(APACHE1_HOME)\libexec" /libpath:"$(APACHE1_HOME)\src\CoreD" /libpath:"$(APACHE1_HOME)\src\Debug" !ENDIF # Begin Target # Name "mod_jk - Win32 Release" # Name "mod_jk - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\common\jk_ajp12_worker.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp13.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp13_worker.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp14.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp14_worker.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp_common.c # End Source File # Begin Source File SOURCE=..\common\jk_connect.c # End Source File # Begin Source File SOURCE=..\common\jk_context.c # End Source File # Begin Source File SOURCE=..\common\jk_lb_worker.c # End Source File # Begin Source File SOURCE=..\common\jk_map.c # End Source File # Begin Source File SOURCE=..\common\jk_md5.c # End Source File # Begin Source File SOURCE=..\common\jk_msg_buff.c # End Source File # Begin Source File SOURCE=..\common\jk_pool.c # End Source File # Begin Source File SOURCE=..\common\jk_shm.c # End Source File # Begin Source File SOURCE=..\common\jk_sockbuf.c # End Source File # Begin Source File SOURCE=..\common\jk_status.c # End Source File # Begin Source File SOURCE=..\common\jk_uri_worker_map.c # End Source File # Begin Source File SOURCE=..\common\jk_url.c # End Source File # Begin Source File SOURCE=..\common\jk_util.c # End Source File # Begin Source File SOURCE=..\common\jk_worker.c # End Source File # Begin Source File SOURCE=.\mod_jk.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=..\common\jk_ajp12_worker.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp13.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp13_worker.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp14.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp14_worker.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp_common.h # End Source File # Begin Source File SOURCE=..\common\jk_connect.h # End Source File # Begin Source File SOURCE=..\common\jk_context.h # End Source File # Begin Source File SOURCE=..\common\jk_global.h # End Source File # Begin Source File SOURCE=..\common\jk_lb_worker.h # End Source File # Begin Source File SOURCE=..\common\jk_logger.h # End Source File # Begin Source File SOURCE=..\common\jk_map.h # End Source File # Begin Source File SOURCE=..\common\jk_md5.h # End Source File # Begin Source File SOURCE=..\common\jk_msg_buff.h # End Source File # Begin Source File SOURCE=..\common\jk_mt.h # End Source File # Begin Source File SOURCE=..\common\jk_pool.h # End Source File # Begin Source File SOURCE=..\common\jk_service.h # End Source File # Begin Source File SOURCE=..\common\jk_shm.h # End Source File # Begin Source File SOURCE=..\common\jk_sockbuf.h # End Source File # Begin Source File SOURCE=..\common\jk_status.h # End Source File # Begin Source File SOURCE=..\common\jk_uri_worker_map.h # End Source File # Begin Source File SOURCE=..\common\jk_url.h # End Source File # Begin Source File SOURCE=..\common\jk_util.h # End Source File # Begin Source File SOURCE=..\common\jk_worker.h # End Source File # Begin Source File SOURCE=..\common\jk_worker_list.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project tomcat-connectors-1.2.41-src/native/apache-1.3/Makefile.netware0000644000000000000020000001720511660656133022441 0ustar rootbin# # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # # Makefile for mod_jk (NetWare version - gnu make) # created by Guenter Knauf # # Edit the path below to point to the base of your Apache 1.3 includes. ifndef AP_HOME AP_HOME = c:/projects/cw/apache_1.3.37 endif # Edit the path below to point to the base of your Novell NDK. ifndef NDKBASE NDKBASE = c:/novell endif INSTDIR = s:/apache/modules # Edit the vars below to change NLM target settings. TARGET = mod_jk VERSION = $(JK_VERSION) COPYR = Licensed under the Apache License, Version 2.0 DESCR = Apache $(AP_VERSION_STR) plugin for Tomcat $(JK_VERSION_STR) MTSAFE = NO STACK = 65536 #SCREEN = NONE EXPORTS = jk_module #AP_PRE = YES #MODULES = # Edit the var below to point to your lib architecture. ifndef LIBARCH LIBARCH = CLIB # LIBARCH = LIBC endif # must be equal to DEBUG or NDEBUG DB = NDEBUG # DB = DEBUG # Optimization: -O or debugging: -g ifeq ($(DB),NDEBUG) OPT = -O2 OBJDIR = release else OPT = -g OBJDIR = debug endif # Include the version info retrieved from jk_version.h -include $(OBJDIR)/version.inc # The following line defines your compiler. ifdef METROWERKS CC = mwccnlm else CC = gcc GCC_ROOT = $(MINGNLM) endif # RM = rm -f #CP = cp -fv AWK = awk # Global flags for all compilers CFLAGS = $(OPT) -D$(DB) -DNETWARE -nostdinc ifeq ($(CC),mwccnlm) LD = mwldnlm LDFLAGS = -nostdlib $(OBJS) $(PRELUDE) $(LDLIBS) -o $@ -commandfile CFLAGS += -gccinc -inline off -opt nointrinsics #CFLAGS += -w on ifeq ($(LIBARCH),LIBC) PRELUDE = $(SDK_LIBC)/imports/libcpre.o CFLAGS += -align 4 -inst mmx -proc 586 # CFLAGS += -D__ANSIC__ else # PRELUDE = $(SDK_CLIB)/imports/clibpre.obj PRELUDE = "$(METROWERKS)/Novell Support/libraries/runtime/prelude.obj" LDLIBS = "$(METROWERKS)/Novell Support/libraries/runtime/mwcrtl.lib" # CFLAGS += -include "$(METROWERKS)/Novell Support/headers/nlm_prefix.h" CFLAGS += -align 1 -proc 586 endif else LD = nlmconv LDFLAGS = -T CFLAGS += -fno-builtin -fpack-struct -fpcc-struct-return CFLAGS += -w #CFLAGS += -Wall -Wno-main # -pedantic ifeq ($(LIBARCH),LIBC) PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o # CFLAGS += -D__ANSIC__ else # PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o PRELUDE = $(NDK_ROOT)/pre/prelude.o LDLIBS = $(GCC_ROOT)/lib/gcc-lib/i586-netware/3.2.3/libgcc.a CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h endif endif CFLAGS += -include "precomp.h" ifeq ($(AP_PRE),YES) PRELUDE = $(OBJDIR)/libpre.o endif NDK_ROOT = $(NDKBASE)/ndk SDK_CLIB = $(NDK_ROOT)/nwsdk SDK_LIBC = $(NDK_ROOT)/libc JKCOMMON = ../common INCLUDES = -I$(AP_HOME)/src/include -I$(AP_HOME)/src/os/netware INCLUDES += -I$(JKCOMMON) ifeq ($(LIBARCH),LIBC) INCLUDES += -I$(SDK_LIBC)/include INCLUDES += -I$(SDK_LIBC)/include/winsock else INCLUDES += -I$(SDK_CLIB)/include/nlm -I$(SDK_CLIB)/include INCLUDES += -I$(NDKBASE)/ws295sdk/include CFLAGS += -DNETDB_USE_INTERNET CFLAGS += -DNO_GETTIMEOFDAY CFLAGS += -DJK_PREFORK endif CFLAGS += $(INCLUDES) ifeq ($(MTSAFE),YES) XDCDATA = $(AP_HOME)/src/os/netware/apache.xdc endif ifeq ($(findstring linux,$(OSTYPE)),linux) DL = ' #-include $(NDKBASE)/nlmconv/ncpfs.inc endif OBJS = \ $(OBJDIR)/$(TARGET).o \ $(OBJDIR)/jk_nwmain.o \ $(OBJDIR)/jk_ajp12_worker.o \ $(OBJDIR)/jk_ajp13.o \ $(OBJDIR)/jk_ajp13_worker.o \ $(OBJDIR)/jk_ajp14.o \ $(OBJDIR)/jk_ajp14_worker.o \ $(OBJDIR)/jk_ajp_common.o \ $(OBJDIR)/jk_connect.o \ $(OBJDIR)/jk_context.o \ $(OBJDIR)/jk_lb_worker.o \ $(OBJDIR)/jk_map.o \ $(OBJDIR)/jk_md5.o \ $(OBJDIR)/jk_msg_buff.o \ $(OBJDIR)/jk_pool.o \ $(OBJDIR)/jk_shm.o \ $(OBJDIR)/jk_sockbuf.o \ $(OBJDIR)/jk_status.o \ $(OBJDIR)/jk_uri_worker_map.o \ $(OBJDIR)/jk_url.o \ $(OBJDIR)/jk_util.o \ $(OBJDIR)/jk_worker.o #OBJS += $(OBJDIR)/ap_snprintf.o vpath %.c . $(JKCOMMON) $(AP_HOME)/src/os/netware all: $(OBJDIR) $(OBJDIR)/version.inc $(OBJDIR)/$(TARGET).nlm $(OBJDIR)/%.o: %.c @echo Compiling $< @$(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/version.inc: $(JKCOMMON)/jk_version.h $(AP_HOME)/src/include/httpd.h $(OBJDIR) @echo Creating $@ @$(AWK) -f ../../support/get_ver.awk $< $(AP_HOME)/src/include/httpd.h > $@ dist: all -$(RM) $(OBJDIR)/*.o $(OBJDIR)/$(TARGET).map $(OBJDIR)/$(TARGET).ncv -$(RM) $(OBJDIR)/$(TARGET).def $(OBJDIR)/version.inc # -$(CP) ../changes.txt $(OBJDIR)/ install: all @[ -d $(INSTDIR) ] || mkdir $(INSTDIR) @$(CP) $(TARGET).nlm $(INSTDIR) clean: -$(RM) -r $(OBJDIR) $(OBJDIR): @mkdir $(OBJDIR) #$(OBJDIR)/$(TARGET).nlm: $(OBJS) $(OBJDIR)/$(TARGET).def $(XDCDATA) $(PRELUDE) $(OBJDIR)/$(TARGET).nlm: $(OBJS) $(OBJDIR)/$(TARGET).def $(XDCDATA) @echo Linking $@ @-$(RM) $@ @$(LD) $(LDFLAGS) $(OBJDIR)/$(TARGET).def $(OBJDIR)/%.xdc: Makefile.netware @echo Creating $@ @$(MPKXDC) $(XDCOPT) $@ $(OBJDIR)/%.def: Makefile.netware @echo $(DL)# DEF file for linking with $(LD)$(DL) > $@ @echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@ @echo $(DL)# All your changes will be lost!!$(DL) >> $@ @echo $(DL)#$(DL) >> $@ @echo $(DL)copyright "$(COPYR)"$(DL) >> $@ @echo $(DL)description "$(DESCR)"$(DL) >> $@ @echo $(DL)version $(VERSION)$(DL) >> $@ ifdef NLMTYPE @echo $(DL)type $(NLMTYPE)$(DL) >> $@ endif ifdef STACK @echo $(DL)stack $(STACK)$(DL) >> $@ endif ifdef SCREEN @echo $(DL)screenname "$(SCREEN)"$(DL) >> $@ else @echo $(DL)screenname "DEFAULT"$(DL) >> $@ endif ifeq ($(DB),DEBUG) @echo $(DL)debug$(DL) >> $@ endif @echo $(DL)threadname "$*"$(DL) >> $@ ifdef XDCDATA @echo $(DL)xdcdata $(XDCDATA)$(DL) >> $@ endif ifeq ($(LIBARCH),CLIB) ifeq ($(AP_PRE),YES) @echo $(DL)start _lib_start$(DL) >> $@ @echo $(DL)exit _lib_stop$(DL) >> $@ else @echo $(DL)start _Prelude$(DL) >> $@ @echo $(DL)exit _Stop$(DL) >> $@ endif @echo $(DL)import @$(NDK_ROOT)/nwsdk/imports/clib.imp$(DL) >> $@ @echo $(DL)import @$(NDK_ROOT)/nwsdk/imports/threads.imp$(DL) >> $@ @echo $(DL)import @$(NDK_ROOT)/nwsdk/imports/nlmlib.imp$(DL) >> $@ @echo $(DL)import @$(NDK_ROOT)/nwsdk/imports/socklib.imp$(DL) >> $@ # @echo $(DL)import @$(NDK_ROOT)/nwsdk/imports/ws2nlm.imp$(DL) >> $@ @echo $(DL)import @$(AP_HOME)/src/os/netware/apachecore.imp$(DL) >> $@ @echo $(DL)module clib$(DL) >> $@ else @echo $(DL)flag_on 64$(DL) >> $@ @echo $(DL)pseudopreemption$(DL) >> $@ @echo $(DL)start _LibCPrelude$(DL) >> $@ @echo $(DL)exit _LibCPostlude$(DL) >> $@ @echo $(DL)check _LibCCheckUnload$(DL) >> $@ @echo $(DL)import @$(NDK_ROOT)/libc/imports/libc.imp$(DL) >> $@ @echo $(DL)import @$(NDK_ROOT)/libc/imports/netware.imp$(DL) >> $@ # @echo $(DL)import @$(NDK_ROOT)/libc/imports/ws2nlm.imp$(DL) >> $@ @echo $(DL)import @$(AP_HOME)/src/os/netware/apachecore.imp$(DL) >> $@ @echo $(DL)module libc$(DL) >> $@ endif ifdef MODULES @echo $(DL)module $(MODULES)$(DL) >> $@ endif ifdef EXPORTS @echo $(DL)export $(EXPORTS)$(DL) >> $@ endif ifdef IMPORTS @echo $(DL)import $(IMPORTS)$(DL) >> $@ endif ifeq ($(LD),nlmconv) @echo $(DL)input $(OBJS)$(DL) >> $@ @echo $(DL)input $(PRELUDE)$(DL) >> $@ ifdef LDLIBS @echo $(DL)input $(LDLIBS)$(DL) >> $@ endif @echo $(DL)output $*.nlm$(DL) >> $@ endif tomcat-connectors-1.2.41-src/native/apache-1.3/Makefile.libdir0000644000000000000020000000037407307132056022234 0ustar rootbinThis is a place-holder which indicates to Configure that it shouldn't provide the default targets when building the Makefile in this directory. Instead it'll just prepend all the important variable definitions, and copy the Makefile.tmpl onto the end. tomcat-connectors-1.2.41-src/native/apache-1.3/NWGNUmakefile0000644000000000000020000000232610666607673021664 0ustar rootbin# # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # # Declare the sub-directories to be built here # SUBDIRS = \ $(EOLIST) # # Get the 'head' of the build environment. This includes default targets and # paths to tools # include $(AP_WORK)\NWGNUhead.inc # # build this level's files ifeq "$(wildcard NWGNUmakefile.mak)" "NWGNUmakefile.mak" include NWGNUmakefile.mak endif # # You can use this target if all that is needed is to copy files to the # installation area # install :: nlms FORCE tomcat-connectors-1.2.41-src/native/apache-1.3/mod_jk.c0000644000000000000020000037671612470732025020756 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Apache 1.3 plugin for Tomcat * * See ../common/jk_service.h for general mod_jk info * * Author: Gal Shachor * * Dan Milstein * * Henri Gomez * * Version: $Revision: 1660504 $ * ***************************************************************************/ /* * mod_jk: keeps all servlet related ramblings together. */ /* #include "ap_config.h" */ #include "httpd.h" #include "http_config.h" #include "http_request.h" #include "http_core.h" #include "http_protocol.h" #include "http_main.h" #include "http_log.h" #include "util_script.h" #include "util_date.h" #include "http_conf_globals.h" /* * jk_ include files */ #ifdef NETWARE #define _SYS_TYPES_H_ #define _NETDB_H_INCLUDED #define _IN_ #define _INET_ #define _SYS_TIMEVAL_H_ #define _SYS_SOCKET_H_ #undef ntohs #endif #include "jk_global.h" #include "jk_util.h" #include "jk_map.h" #include "jk_pool.h" #include "jk_service.h" #include "jk_worker.h" #include "jk_uri_worker_map.h" #include "jk_ajp13.h" #include "jk_shm.h" #include "jk_url.h" #define JK_LOG_DEF_FILE ("logs/mod_jk.log") #define JK_SHM_DEF_FILE ("logs/jk-runtime-status") #define JK_ENV_REMOTE_ADDR ("JK_REMOTE_ADDR") #define JK_ENV_REMOTE_PORT ("JK_REMOTE_PORT") #define JK_ENV_REMOTE_HOST ("JK_REMOTE_HOST") #define JK_ENV_REMOTE_USER ("JK_REMOTE_USER") #define JK_ENV_AUTH_TYPE ("JK_AUTH_TYPE") #define JK_ENV_LOCAL_NAME ("JK_LOCAL_NAME") #define JK_ENV_LOCAL_ADDR ("JK_LOCAL_ADDR") #define JK_ENV_LOCAL_PORT ("JK_LOCAL_PORT") #define JK_ENV_IGNORE_CL ("JK_IGNORE_CL") #define JK_ENV_HTTPS ("HTTPS") #define JK_ENV_SSL_PROTOCOL ("SSL_PROTOCOL") #define JK_ENV_CERTS ("SSL_CLIENT_CERT") #define JK_ENV_CIPHER ("SSL_CIPHER") #define JK_ENV_SESSION ("SSL_SESSION_ID") #define JK_ENV_KEY_SIZE ("SSL_CIPHER_USEKEYSIZE") #define JK_ENV_CERTCHAIN_PREFIX ("SSL_CLIENT_CERT_CHAIN_") #define JK_ENV_REPLY_TIMEOUT ("JK_REPLY_TIMEOUT") #define JK_ENV_STICKY_IGNORE ("JK_STICKY_IGNORE") #define JK_ENV_STATELESS ("JK_STATELESS") #define JK_ENV_ROUTE ("JK_ROUTE") #define JK_ENV_WORKER_NAME ("JK_WORKER_NAME") #define JK_NOTE_WORKER_NAME ("JK_WORKER_NAME") #define JK_NOTE_WORKER_TYPE ("JK_WORKER_TYPE") #define JK_NOTE_REQUEST_DURATION ("JK_REQUEST_DURATION") #define JK_NOTE_WORKER_ROUTE ("JK_WORKER_ROUTE") #define JK_HANDLER ("jakarta-servlet") #define JK_MAGIC_TYPE ("application/x-jakarta-servlet") #define NULL_FOR_EMPTY(x) ((x && !strlen(x)) ? NULL : x) #define STRNULL_FOR_NULL(x) ((x) ? (x) : "(null)") /* * If you are not using SSL, comment out the following line. It will make * apache run faster. * * Personally, I (DM), think this may be a lie. */ #define ADD_SSL_INFO module MODULE_VAR_EXPORT jk_module; #ifdef WIN32 extern __declspec(dllimport) module dir_module; #else extern module dir_module; #endif static int xfer_flags = (O_WRONLY | O_APPEND | O_CREAT); #if defined(OS2) || defined(WIN32) || defined(NETWARE) /* OS/2 dosen't support users and groups */ static mode_t xfer_mode = (S_IREAD | S_IWRITE); #else static mode_t xfer_mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); #endif /* * Environment variable forward object */ typedef struct { int has_default; char *name; char *value; } envvar_item; /* * Configuration object for the mod_jk module. */ typedef struct { /* * Log stuff */ char *log_file; int log_level; jk_logger_t *log; /* * Mount stuff */ char *mount_file; int mount_file_reload; jk_map_t *uri_to_context; int mountcopy; jk_uri_worker_map_t *uw_map; int was_initialized; /* * Automatic context path apache alias */ char *alias_dir; /* * Request Logging */ char *stamp_format_string; char *format_string; array_header *format; /* * Setting target worker via environment */ char *worker_indicator; /* * Configurable environment variables to overwrite * request information using meta data send by a * proxy in front of us. */ char *remote_addr_indicator; char *remote_port_indicator; char *remote_host_indicator; char *remote_user_indicator; char *auth_type_indicator; char *local_name_indicator; char *local_addr_indicator; char *local_port_indicator; /* * Configurable environment variable to force * ignoring a request Content-Length header * (useful to make mod_deflate request inflation * compatible with mod_jk). */ char *ignore_cl_indicator; /* * SSL Support */ int ssl_enable; char *https_indicator; char *ssl_protocol_indicator; char *certs_indicator; char *cipher_indicator; char *session_indicator; char *key_size_indicator; char *certchain_prefix; /* Client certificate chain prefix */ /* * Jk Options */ int options; int exclude_options; int strip_session; char *strip_session_name; /* * Environment variables support */ int envvars_has_own; table *envvars; table *envvars_def; array_header *envvar_items; server_rec *s; } jk_server_conf_t; /* * Request specific configuration */ struct jk_request_conf { rule_extension_t *rule_extensions; int jk_handled; }; typedef struct jk_request_conf jk_request_conf_t; /* * The "private", or subclass portion of the web server service class for * Apache 1.3. An instance of this class is created for each request * handled. See jk_service.h for details about the ws_service object in * general. */ struct apache_private_data { /* * For memory management for this request. Aliased to be identical to * the pool in the superclass (jk_ws_service). */ jk_pool_t p; /* True iff request body data has been read from Apache */ int read_body_started; /* Apache request structure */ request_rec *r; }; typedef struct apache_private_data apache_private_data_t; typedef struct dir_config_struct { array_header *index_names; } dir_config_rec; static server_rec *main_server = NULL; static jk_logger_t *main_log = NULL; static table *jk_log_fds = NULL; static jk_worker_env_t worker_env; static char *jk_shm_file = NULL; static int jk_shm_size = 0; static int jk_shm_size_set = 0; /* * Worker stuff */ static jk_map_t *jk_worker_properties = NULL; static char *jk_worker_file = NULL; static int jk_mount_copy_all = JK_FALSE; static int JK_METHOD ws_start_response(jk_ws_service_t *s, int status, const char *reason, const char *const *header_names, const char *const *header_values, unsigned num_of_headers); static int JK_METHOD ws_read(jk_ws_service_t *s, void *b, unsigned l, unsigned *a); static int JK_METHOD ws_write(jk_ws_service_t *s, const void *b, unsigned l); static void JK_METHOD ws_add_log_items(jk_ws_service_t *s, const char *const *log_names, const char *const *log_values, unsigned num_of_log_items); static void * JK_METHOD ws_next_vhost(void *d); static void JK_METHOD ws_vhost_to_text(void *d, char *buf, size_t len); static jk_uri_worker_map_t * JK_METHOD ws_vhost_to_uw_map(void *d); /* srevilak - new function prototypes */ static void jk_server_cleanup(void *data); static void jk_generic_cleanup(server_rec * s); /* ====================================================================== */ /* JK Service step callbacks */ /* ====================================================================== */ /* * Send the HTTP response headers back to the browser. * * Think of this function as a method of the apache1.3-specific subclass of * the jk_ws_service class. Think of the *s param as a "this" or "self" * pointer. */ static int JK_METHOD ws_start_response(jk_ws_service_t *s, int status, const char *reason, const char *const *header_names, const char *const *header_values, unsigned num_of_headers) { if (s && s->ws_private) { unsigned h; /* Obtain a subclass-specific "this" pointer */ apache_private_data_t *p = s->ws_private; request_rec *r = p->r; /* If we use proxy error pages, still pass * through context headers needed for special status codes. */ if (s->extension.use_server_error_pages && status >= s->extension.use_server_error_pages) { if (status == HTTP_UNAUTHORIZED) { int found = JK_FALSE; for (h = 0; h < num_of_headers; h++) { if (!strcasecmp(header_names[h], "WWW-Authenticate")) { char *tmp = ap_pstrdup(r->pool, header_values[h]); ap_table_set(r->err_headers_out, "WWW-Authenticate", tmp); found = JK_TRUE; } } if (found == JK_FALSE) { jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(r->server->module_config, &jk_module); jk_log(conf->log, JK_LOG_INFO, "origin server sent 401 without" " WWW-Authenticate header"); } } return JK_TRUE; } if (!reason) { reason = ""; } r->status = status; r->status_line = ap_psprintf(r->pool, "%d %s", status, reason); for (h = 0; h < num_of_headers; h++) { if (!strcasecmp(header_names[h], "Content-type")) { char *tmp = ap_pstrdup(r->pool, header_values[h]); ap_content_type_tolower(tmp); r->content_type = tmp; } else if (!strcasecmp(header_names[h], "Location")) { ap_table_set(r->headers_out, header_names[h], header_values[h]); } else if (!strcasecmp(header_names[h], "Content-Length")) { ap_set_content_length(r, atol(header_values[h])); } else if (!strcasecmp(header_names[h], "Transfer-Encoding")) { ap_table_set(r->headers_out, header_names[h], header_values[h]); } else if (!strcasecmp(header_names[h], "Last-Modified")) { /* * If the script gave us a Last-Modified header, we can't just * pass it on blindly because of restrictions on future values. */ ap_update_mtime(r, ap_parseHTTPdate(header_values[h])); ap_set_last_modified(r); } else { ap_table_add(r->headers_out, header_names[h], header_values[h]); } } ap_send_http_header(r); s->response_started = JK_TRUE; return JK_TRUE; } return JK_FALSE; } /* * 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. * * Think of this function as a method of the apache1.3-specific subclass of * the jk_ws_service class. Think of the *s param as a "this" or "self" * pointer. */ static int JK_METHOD ws_read(jk_ws_service_t *s, void *b, unsigned len, unsigned *actually_read) { if (s && s->ws_private && b && actually_read) { apache_private_data_t *p = s->ws_private; if (!p->read_body_started) { if (ap_should_client_block(p->r)) { p->read_body_started = JK_TRUE; } } if (p->read_body_started) { long rv; if ((rv = ap_get_client_block(p->r, b, len)) < 0) { *actually_read = 0; } else { *actually_read = (unsigned)rv; } /* reset timeout after successful read */ ap_reset_timeout(p->r); return JK_TRUE; } } return JK_FALSE; } static void JK_METHOD ws_flush(jk_ws_service_t *s) { if (s && s->ws_private) { apache_private_data_t *p = s->ws_private; BUFF *bf = p->r->connection->client; ap_bflush(bf); } } /* * Write a chunk of response data back to the browser. If the headers * haven't yet been sent over, send over default header values (Status = * 200, basically). * * Write len bytes from buffer b. * * Think of this function as a method of the apache1.3-specific subclass of * the jk_ws_service class. Think of the *s param as a "this" or "self" * pointer. */ static int JK_METHOD ws_write(jk_ws_service_t *s, const void *b, unsigned len) { if (s && s->ws_private && b) { apache_private_data_t *p = s->ws_private; if (len) { char *buf = (char *)b; int w = (int)len; int r = 0; if (!s->response_started) { if (main_log) jk_log(main_log, JK_LOG_INFO, "Write without start, starting with defaults"); if (!s->start_response(s, 200, NULL, NULL, NULL, 0)) { return JK_FALSE; } } if (p->r->header_only) { BUFF *bf = p->r->connection->client; ap_bflush(bf); return JK_TRUE; } while (len && !p->r->connection->aborted) { w = ap_bwrite(p->r->connection->client, &buf[r], len); if (w > 0) { /* reset timeout after successful write */ ap_reset_timeout(p->r); r += w; len -= w; } else if (w < 0) { /* Error writing data -- abort */ if (!p->r->connection->aborted) { ap_bsetflag(p->r->connection->client, B_EOUT, 1); p->r->connection->aborted = 1; } return JK_FALSE; } } if (len && p->r->connection->aborted) { /* Fail if there is something left to send and * the connection was aborted by the client */ return JK_FALSE; } } return JK_TRUE; } return JK_FALSE; } static void JK_METHOD ws_add_log_items(jk_ws_service_t *s, const char *const *log_names, const char *const *log_values, unsigned num_of_log_items) { unsigned h; apache_private_data_t *p = s->ws_private; request_rec *r = p->r; for (h = 0; h < num_of_log_items; h++) { if (log_names[h] && log_values[h]) { ap_table_set(r->notes, log_names[h], log_values[h]); } } } static void * JK_METHOD ws_next_vhost(void *d) { server_rec *s = (server_rec *)d; if (s == NULL) return main_server; return s->next; } static void JK_METHOD ws_vhost_to_text(void *d, char *buf, size_t len) { server_rec *s = (server_rec *)d; size_t used = 0; if (s->server_hostname) { used += strlen(s->server_hostname); } if (!s->is_virtual) { if (s->port) used += strlen(":XXXXX"); } else if (s->addrs) { used += strlen(" ["); if (s->addrs->virthost) used += strlen(s->addrs->virthost); if (s->addrs->host_port) used += strlen(":XXXXX"); used += strlen("]"); } if (len < used && len > strlen("XXX")) { strcpy(buf, "XXX"); return; } used = 0; if (s->server_hostname) { strcpy(buf + used, s->server_hostname); used += strlen(s->server_hostname); } if (!s->is_virtual) { if (s->port) { sprintf(buf + used, ":%hu", s->port); used = strlen(buf); } } else if (s->addrs) { strcpy(buf + used, " ["); used += strlen(" ["); if (s->addrs->virthost) { strcpy(buf + used, s->addrs->virthost); used += strlen(s->addrs->virthost); } if (s->addrs->host_port) { sprintf(buf + used, ":%hu", s->addrs->host_port); used = strlen(buf); } strcpy(buf + used, "]"); used += strlen("]"); } } static jk_uri_worker_map_t * JK_METHOD ws_vhost_to_uw_map(void *d) { server_rec *s = (server_rec *)d; jk_server_conf_t *conf = NULL; if (s == NULL) return NULL; conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); return conf->uw_map; } /* ====================================================================== */ /* Utility functions */ /* ====================================================================== */ static void dump_options(server_rec *srv, ap_pool *p) { char server_name[80]; jk_server_conf_t *conf = (jk_server_conf_t *)ap_get_module_config(srv->module_config, &jk_module); int options = conf->options; ws_vhost_to_text(srv, server_name, 80); if (options & JK_OPT_FWDURICOMPAT) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardURICompat", server_name, JK_OPT_DEFAULT & JK_OPT_FWDURICOMPAT ? " (default)" : ""); if (options & JK_OPT_FWDURICOMPATUNPARSED) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardURICompatUnparsed", server_name, JK_OPT_DEFAULT & JK_OPT_FWDURICOMPATUNPARSED ? " (default)" : ""); if (options & JK_OPT_FWDURIESCAPED) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardURIEscaped", server_name, JK_OPT_DEFAULT & JK_OPT_FWDURIESCAPED ? " (default)" : ""); if (options & JK_OPT_FWDURIPROXY) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardURIProxy", server_name, JK_OPT_DEFAULT & JK_OPT_FWDURIPROXY ? " (default)" : ""); if (options & JK_OPT_FWDDIRS) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardDirectories", server_name, JK_OPT_DEFAULT & JK_OPT_FWDDIRS ? " (default)" : ""); if (options & JK_OPT_FWDLOCAL) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardLocalAddress", server_name, JK_OPT_DEFAULT & JK_OPT_FWDLOCAL ? " (default)" : ""); if (options & JK_OPT_FWDPHYSICAL) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardPhysicalAddress", server_name, JK_OPT_DEFAULT & JK_OPT_FWDPHYSICAL ? " (default)" : ""); if (options & JK_OPT_FWDCERTCHAIN) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardSSLCertChain", server_name, JK_OPT_DEFAULT & JK_OPT_FWDCERTCHAIN ? " (default)" : ""); if (options & JK_OPT_FWDKEYSIZE) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "ForwardKeySize", server_name, JK_OPT_DEFAULT & JK_OPT_FWDKEYSIZE ? " (default)" : ""); if (options & JK_OPT_FLUSHPACKETS) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "FlushPackets", server_name, JK_OPT_DEFAULT & JK_OPT_FLUSHPACKETS ? " (default)" : ""); if (options & JK_OPT_FLUSHEADER) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "FlushHeader", server_name, JK_OPT_DEFAULT & JK_OPT_FLUSHEADER ? " (default)" : ""); if (options & JK_OPT_DISABLEREUSE) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "DisableReuse", server_name, JK_OPT_DEFAULT & JK_OPT_DISABLEREUSE ? " (default)" : ""); if (options & JK_OPT_REJECTUNSAFE) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "RejectUnsafeURI", server_name, JK_OPT_DEFAULT & JK_OPT_REJECTUNSAFE ? " (default)" : ""); if (options & JK_OPT_COLLAPSEALL) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "CollapseSlashesAll", server_name, JK_OPT_DEFAULT & JK_OPT_COLLAPSEALL ? " (default)" : ""); if (options & JK_OPT_COLLAPSENONE) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "CollapseSlashesNone", server_name, JK_OPT_DEFAULT & JK_OPT_COLLAPSENONE ? " (default)" : ""); if (options & JK_OPT_COLLAPSEUNMOUNT) jk_log(conf->log, JK_LOG_DEBUG, "JkOption '%s' set in server '%s'%s", "CollapseSlashesUnmount", server_name, JK_OPT_DEFAULT & JK_OPT_COLLAPSEUNMOUNT ? " (default)" : ""); } /* Log something to JK log file then exit */ static void jk_error_exit(const char *file, int line, int level, const server_rec * s, ap_pool * p, const char *fmt, ...) { va_list ap; char *res; char *ch; va_start(ap, fmt); res = ap_pvsprintf(p, fmt, ap); va_end(ap); /* Replace all format characters in the resulting message */ /* because we feed the message to ap_log_error(). */ ch = res; while (*ch) { if (*ch == '%') { *ch = '#'; } ch++; } ap_log_error(file, line, level, s, "%s", res); if ( s ) { ap_log_error(file, line, level, NULL, "%s", res); } /* Exit process */ exit(1); } /* Return the content length associated with an Apache request structure */ static jk_uint64_t get_content_length(request_rec * r) { char *lenp = (char *)ap_table_get(r->headers_in, "Content-Length"); if (lenp) { jk_uint64_t rc = 0; if (sscanf(lenp, "%" JK_UINT64_T_FMT, &rc) > 0 && rc > 0) { return rc; } } return 0; } /* Retrieve string value from env var, use default if env var does not exist. */ static const char *get_env_string(request_rec *r, const char *def, char *env, int null_for_empty) { char *value = (char *)ap_table_get(r->subprocess_env, env); if (value) return null_for_empty ? NULL_FOR_EMPTY(value) : value; return null_for_empty ? NULL_FOR_EMPTY(def) : def; } /* Retrieve integer value from env var, use default if env var does not exist. */ static int get_env_int(request_rec *r, int def, char *env) { char *value = (char *)ap_table_get(r->subprocess_env, env); if (value) return atoi(value); return def; } /* * Set up an instance of a ws_service object for a single request. This * particular instance will be of the Apache 1.3-specific subclass. Copies * all of the important request information from the Apache request object * into the jk_ws_service_t object. * * Params * * private_data: The subclass-specific data structure, already initialized * (with a pointer to the Apache request_rec structure, among other things) * * s: The base class object. * * conf: Configuration information * * Called from jk_handler(). See jk_service.h for explanations of what most * of these fields mean. */ static int init_ws_service(apache_private_data_t * private_data, jk_ws_service_t *s, jk_server_conf_t * conf) { int size; request_rec *r = private_data->r; char *ssl_temp = NULL; const char *reply_timeout = NULL; const char *sticky_ignore = NULL; const char *stateless = NULL; const char *route = NULL; rule_extension_t *e; jk_request_conf_t *rconf; /* Copy in function pointers (which are really methods) */ s->start_response = ws_start_response; s->read = ws_read; s->write = ws_write; s->flush = ws_flush; s->add_log_items = ws_add_log_items; s->next_vhost = ws_next_vhost; s->vhost_to_text = ws_vhost_to_text; s->vhost_to_uw_map = ws_vhost_to_uw_map; s->auth_type = get_env_string(r, r->connection->ap_auth_type, conf->auth_type_indicator, 1); s->remote_user = get_env_string(r, r->connection->user, conf->remote_user_indicator, 1); s->protocol = r->protocol; s->remote_host = (char *)ap_get_remote_host(r->connection, r->per_dir_config, REMOTE_HOST); s->remote_host = get_env_string(r, s->remote_host, conf->remote_host_indicator, 1); if (conf->options & JK_OPT_FWDLOCAL) { s->remote_addr = r->connection->local_ip; /* We don't know the client port of the backend connection. */ s->remote_port = "0"; } else { s->remote_addr = r->connection->remote_ip; s->remote_port = ap_psprintf(r->pool, "%d", ntohs(r->connection->remote_addr.sin_port)); } s->remote_addr = get_env_string(r, s->remote_addr, conf->remote_addr_indicator, 1); s->remote_port = get_env_string(r, s->remote_port, conf->remote_port_indicator, 1); if (conf->options & JK_OPT_FLUSHPACKETS) s->flush_packets = 1; if (conf->options & JK_OPT_FLUSHEADER) s->flush_header = 1; rconf = (jk_request_conf_t *)ap_get_module_config(r->request_config, &jk_module); e = rconf->rule_extensions; if (e) { s->extension.reply_timeout = e->reply_timeout; s->extension.sticky_ignore = e->sticky_ignore; s->extension.stateless = e->stateless; s->extension.use_server_error_pages = e->use_server_error_pages; if (e->activation) { s->extension.activation = ap_palloc(r->pool, e->activation_size * sizeof(int)); memcpy(s->extension.activation, e->activation, e->activation_size * sizeof(int)); } if (e->fail_on_status_size > 0) { s->extension.fail_on_status_size = e->fail_on_status_size; s->extension.fail_on_status = ap_palloc(r->pool, e->fail_on_status_size * sizeof(int)); memcpy(s->extension.fail_on_status, e->fail_on_status, e->fail_on_status_size * sizeof(int)); } if (e->session_cookie) { s->extension.session_cookie = ap_pstrdup(r->pool, e->session_cookie); } if (e->session_path) { s->extension.session_path = ap_pstrdup(r->pool, e->session_path); } if (e->set_session_cookie) { s->extension.set_session_cookie = e->set_session_cookie; } if (e->session_cookie_path) { s->extension.session_cookie_path = ap_pstrdup(r->pool, e->session_cookie_path); } } reply_timeout = ap_table_get(r->subprocess_env, JK_ENV_REPLY_TIMEOUT); if (reply_timeout) { int r = atoi(reply_timeout); if (r >= 0) s->extension.reply_timeout = r; } sticky_ignore = ap_table_get(r->subprocess_env, JK_ENV_STICKY_IGNORE); if (sticky_ignore) { if (*sticky_ignore == '\0') { s->extension.sticky_ignore = JK_TRUE; } else { int r = atoi(sticky_ignore); if (r) { s->extension.sticky_ignore = JK_TRUE; } else { s->extension.sticky_ignore = JK_FALSE; } } } stateless = ap_table_get(r->subprocess_env, JK_ENV_STATELESS); if (stateless) { if (*stateless == '\0') { s->extension.stateless = JK_TRUE; } else { int r = atoi(stateless); if (r) { s->extension.stateless = JK_TRUE; } else { s->extension.stateless = JK_FALSE; } } } if (conf->options & JK_OPT_DISABLEREUSE) s->disable_reuse = 1; /* get route if known */ route = ap_table_get(r->subprocess_env, JK_ENV_ROUTE); if (route && *route) { s->route = route; } /* get server name */ /* s->server_name = (char *)(r->hostname ? r->hostname : r->server->server_hostname); */ /* XXX : a la jk2 */ s->server_name = get_env_string(r, (char *)ap_get_server_name(r), conf->local_name_indicator, 0); /* get the local IP address */ /* s->local_addr = r->connection->local_ip; */ /* XXX : a la jk2 */ s->local_addr = get_env_string(r, r->connection->local_ip, conf->local_addr_indicator, 0); /* get the real port (otherwise redirect failed) */ /* s->server_port = htons( r->connection->local_addr.sin_port ); */ /* XXX : a la jk2 */ s->server_port = get_env_int(r, ap_get_server_port(r), conf->local_port_indicator); s->server_software = (char *)ap_get_server_version(); s->method = (char *)r->method; s->content_length = get_content_length(r); s->is_chunked = r->read_chunked; if (s->content_length > 0 && get_env_string(r, NULL, conf->ignore_cl_indicator, 0) != NULL) { s->content_length = 0; s->is_chunked = 1; } s->no_more_chunks = 0; s->query_string = r->args; /* * The 2.2 servlet spec errata says the uri from * HttpServletRequest.getRequestURI() should remain encoded. * [http://java.sun.com/products/servlet/errata_042700.html] * * We use JkOptions to determine which method to be used * * ap_escape_uri is the latest recommanded but require * some java decoding (in TC 3.3 rc2) * * unparsed_uri is used for strict compliance with spec and * old Tomcat (3.2.3 for example) * * uri is use for compatibilty with mod_rewrite with old Tomcats */ switch (conf->options & JK_OPT_FWDURIMASK) { case JK_OPT_FWDURICOMPATUNPARSED: s->req_uri = r->unparsed_uri; if (s->req_uri != NULL) { char *query_str = strchr(s->req_uri, '?'); if (query_str != NULL) { *query_str = 0; } } break; case JK_OPT_FWDURICOMPAT: s->req_uri = r->uri; break; case JK_OPT_FWDURIPROXY: size = 3 * strlen(r->uri) + 1; s->req_uri = ap_palloc(r->pool, size); jk_canonenc(r->uri, s->req_uri, size); break; case JK_OPT_FWDURIESCAPED: s->req_uri = ap_escape_uri(r->pool, r->uri); break; default: return JK_FALSE; } if (conf->ssl_enable || conf->envvars) { ap_add_common_vars(r); if (conf->ssl_enable) { ssl_temp = (char *)ap_table_get(r->subprocess_env, conf->https_indicator); if (ssl_temp && !strcasecmp(ssl_temp, "on")) { s->is_ssl = JK_TRUE; s->ssl_cert = (char *)ap_table_get(r->subprocess_env, conf->certs_indicator); if (conf->options & JK_OPT_FWDCERTCHAIN) { array_header *t = ap_table_elts(r->subprocess_env); if (t && t->nelts) { int i; table_entry *elts = (table_entry *) t->elts; array_header *certs = ap_make_array(r->pool, 1, sizeof(char *)); *(const char **)ap_push_array(certs) = s->ssl_cert; for (i = 0; i < t->nelts; i++) { if (!elts[i].key) continue; if (!strncasecmp(elts[i].key, conf->certchain_prefix, strlen(conf->certchain_prefix))) *(const char **)ap_push_array(certs) = elts[i].val; } s->ssl_cert = ap_array_pstrcat(r->pool, certs, '\0'); } } if (s->ssl_cert) { s->ssl_cert_len = strlen(s->ssl_cert); if (JK_IS_DEBUG_LEVEL(conf->log)) { jk_log(conf->log, JK_LOG_DEBUG, "SSL client certificate (%d bytes): %s", s->ssl_cert_len, s->ssl_cert); } } s->ssl_protocol = (char *)ap_table_get(r->subprocess_env, conf->ssl_protocol_indicator); /* Servlet 2.3 API */ s->ssl_cipher = (char *)ap_table_get(r->subprocess_env, conf->cipher_indicator); s->ssl_session = (char *)ap_table_get(r->subprocess_env, conf->session_indicator); if (conf->options & JK_OPT_FWDKEYSIZE) { /* Servlet 2.3 API */ ssl_temp = (char *)ap_table_get(r->subprocess_env, conf->key_size_indicator); if (ssl_temp) s->ssl_key_size = atoi(ssl_temp); } } } if (conf->envvars) { const array_header *t = conf->envvar_items; if (t && t->nelts) { int i; int j = 0; envvar_item *elts = (envvar_item *) t->elts; s->attributes_names = ap_palloc(r->pool, sizeof(char *) * t->nelts); s->attributes_values = ap_palloc(r->pool, sizeof(char *) * t->nelts); for (i = 0; i < t->nelts; i++) { s->attributes_names[i - j] = elts[i].name; s->attributes_values[i - j] = (char *)ap_table_get(r->subprocess_env, elts[i].name); if (!s->attributes_values[i - j]) { if (elts[i].has_default) { s->attributes_values[i - j] = elts[i].value; } else { s->attributes_values[i - j] = ""; s->attributes_names[i - j] = ""; j++; } } } s->num_attributes = t->nelts - j; } } } if (r->headers_in && ap_table_elts(r->headers_in)) { int need_content_length_header = (!s->is_chunked && s->content_length == 0) ? JK_TRUE : JK_FALSE; array_header *t = ap_table_elts(r->headers_in); if (t && t->nelts) { int i; int off = 0; table_entry *elts = (table_entry *) t->elts; s->num_headers = t->nelts; /* allocate an extra header slot in case we need to add a content-length header */ s->headers_names = ap_palloc(r->pool, sizeof(char *) * (t->nelts + 1)); s->headers_values = ap_palloc(r->pool, sizeof(char *) * (t->nelts + 1)); if (!s->headers_names || !s->headers_values) return JK_FALSE; for (i = 0; i < t->nelts; i++) { char *hname = ap_pstrdup(r->pool, elts[i].key); if (!strcasecmp(hname, "content-length")) { if (need_content_length_header) { need_content_length_header = JK_FALSE; } else if (s->is_chunked) { s->num_headers--; off++; continue; } } s->headers_values[i - off] = ap_pstrdup(r->pool, elts[i].val); s->headers_names[i - off] = hname; } /* Add a content-length = 0 header if needed. * Ajp13 assumes an absent content-length header means an unknown, * but non-zero length body. */ if (need_content_length_header) { s->headers_names[s->num_headers] = "content-length"; s->headers_values[s->num_headers] = "0"; s->num_headers++; } } /* Add a content-length = 0 header if needed. */ else if (need_content_length_header) { s->headers_names = ap_palloc(r->pool, sizeof(char *)); s->headers_values = ap_palloc(r->pool, sizeof(char *)); if (!s->headers_names || !s->headers_values) return JK_FALSE; s->headers_names[0] = "content-length"; s->headers_values[0] = "0"; s->num_headers++; } } s->uw_map = conf->uw_map; /* Dump all connection param so we can trace what's going to * the remote tomcat */ if (JK_IS_DEBUG_LEVEL(conf->log)) { jk_log(conf->log, JK_LOG_DEBUG, "Service protocol=%s method=%s ssl=%s host=%s addr=%s name=%s port=%d auth=%s user=%s laddr=%s raddr=%s uri=%s", STRNULL_FOR_NULL(s->protocol), STRNULL_FOR_NULL(s->method), s->is_ssl ? "true" : "false", STRNULL_FOR_NULL(s->remote_host), STRNULL_FOR_NULL(s->remote_addr), STRNULL_FOR_NULL(s->server_name), s->server_port, STRNULL_FOR_NULL(s->auth_type), STRNULL_FOR_NULL(s->remote_user), STRNULL_FOR_NULL(r->connection->local_ip), STRNULL_FOR_NULL(r->connection->remote_ip), STRNULL_FOR_NULL(s->req_uri)); } return JK_TRUE; } /* * The JK module command processors * * The below are all installed so that Apache calls them while it is * processing its config files. This allows configuration info to be * copied into a jk_server_conf_t object, which is then used for request * filtering/processing. * * See jk_cmds definition below for explanations of these options. */ /* * JkMountCopy directive handling * * JkMountCopy On/Off/All */ static const char *jk_set_mountcopy(cmd_parms * cmd, void *dummy, char *mount_copy) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); if (! strcasecmp(mount_copy, "all")) { jk_mount_copy_all = JK_TRUE; } else if (strcasecmp(mount_copy, "on") && strcasecmp(mount_copy, "off")) { return "JkMountCopy must be All, On or Off"; } else { conf->mountcopy = strcasecmp(mount_copy, "off") ? JK_TRUE : JK_FALSE; } return NULL; } /* * JkMount directive handling * * JkMount URI(context) worker */ static const char *jk_mount_context(cmd_parms * cmd, void *dummy, char *context, char *worker) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); const char *c, *w; if (worker != NULL && cmd->path == NULL ) { c = context; w = worker; } else if (worker == NULL && cmd->path != NULL) { c = cmd->path; w = context; } else { if (worker == NULL) return "JkMount needs a path when not defined in a location"; else return "JkMount can not have a path when defined in a location"; } if (c[0] != '/') return "JkMount context should start with /"; if (!conf->uri_to_context) { if (!jk_map_alloc(&(conf->uri_to_context))) { return "JkMount Memory error"; } } /* * Add the new worker to the alias map. */ jk_map_put(conf->uri_to_context, c, w, NULL); return NULL; } /* * JkUnMount directive handling * * JkUnMount URI(context) worker */ static const char *jk_unmount_context(cmd_parms * cmd, void *dummy, const char *context, const char *worker) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); char *uri; const char *c, *w; if (worker != NULL && cmd->path == NULL ) { c = context; w = worker; } else if (worker == NULL && cmd->path != NULL) { c = cmd->path; w = context; } else { if (worker == NULL) return "JkUnMount needs a path when not defined in a location"; else return "JkUnMount can not have a path when defined in a location"; } if (c[0] != '/') return "JkUnMount context should start with /"; uri = ap_pstrcat(cmd->temp_pool, "!", c, NULL); if (!conf->uri_to_context) { if (!jk_map_alloc(&(conf->uri_to_context))) { return "JkUnMount Memory error"; } } /* * Add the new worker to the alias map. */ jk_map_put(conf->uri_to_context, uri, w, NULL); return NULL; } /* * JkWorkersFile Directive Handling * * JkWorkersFile file */ static const char *jk_set_worker_file(cmd_parms * cmd, void *dummy, char *worker_file) { struct stat statbuf; if (jk_worker_file != NULL) return "JkWorkersFile only allowed once"; /* we need an absolute path */ jk_worker_file = ap_server_root_relative(cmd->pool, worker_file); #ifdef CHROOTED_APACHE ap_server_strip_chroot(jk_worker_file, 0); #endif if (jk_worker_file == worker_file) jk_worker_file = ap_pstrdup(cmd->pool, worker_file); if (jk_worker_file == NULL) return "JkWorkersFile file name invalid"; if (stat(jk_worker_file, &statbuf) == -1) return "JkWorkersFile: Can't find the workers file specified"; return NULL; } /* * JkMountFile Directive Handling * * JkMountFile file */ static const char *jk_set_mount_file(cmd_parms * cmd, void *dummy, char *mount_file) { server_rec *s = cmd->server; struct stat statbuf; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); /* we need an absolute path (ap_server_root_relative does the ap_pstrdup) */ conf->mount_file = ap_server_root_relative(cmd->pool, mount_file); #ifdef CHROOTED_APACHE ap_server_strip_chroot(conf->mount_file, 0); #endif if (conf->mount_file == NULL) return "JkMountFile file name invalid"; if (stat(conf->mount_file, &statbuf) == -1) return "JkMountFile: Can't find the mount file specified"; if (!conf->uri_to_context) { if (!jk_map_alloc(&(conf->uri_to_context))) { return "JkMountFile Memory error"; } } return NULL; } /* * JkMountFileReload Directive Handling * * JkMountFileReload seconds */ static const char *jk_set_mount_file_reload(cmd_parms * cmd, void *dummy, char *mount_file_reload) { server_rec *s = cmd->server; int interval; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); interval = atoi(mount_file_reload); if (interval < 0) { interval = 0; } conf->mount_file_reload = interval; return NULL; } /* * JkLogFile Directive Handling * * JkLogFile file */ static const char *jk_set_log_file(cmd_parms * cmd, void *dummy, char *log_file) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); /* we need an absolute path */ if (*log_file != '|') { conf->log_file = ap_server_root_relative(cmd->pool, log_file); #ifdef CHROOTED_APACHE ap_server_strip_chroot(conf->log_file, 0); #endif } else conf->log_file = ap_pstrdup(cmd->pool, log_file); if (conf->log_file == NULL) return "JkLogFile file name invalid"; return NULL; } /* * JkShmFile Directive Handling * * JkShmFile file */ static const char *jk_set_shm_file(cmd_parms * cmd, void *dummy, char *shm_file) { /* we need an absolute path */ jk_shm_file = ap_server_root_relative(cmd->pool, shm_file); #ifdef CHROOTED_APACHE ap_server_strip_chroot(jk_shm_file, 0); #endif if (jk_shm_file == shm_file) jk_shm_file = ap_pstrdup(cmd->pool, shm_file); if (jk_shm_file == NULL) return "JkShmFile file name invalid"; return NULL; } /* * JkShmSize Directive Handling * * JkShmSize size in kilobytes */ static const char *jk_set_shm_size(cmd_parms * cmd, void *dummy, const char *shm_size) { int sz = 0; /* we need an absolute path */ sz = atoi(shm_size) * 1024; if (sz < JK_SHM_MIN_SIZE) sz = JK_SHM_MIN_SIZE; else sz = JK_SHM_ALIGN(sz); jk_shm_size = sz; if (jk_shm_size) jk_shm_size_set = 1; return NULL; } /* * JkLogLevel Directive Handling * * JkLogLevel debug/info/request/error/emerg */ static const char *jk_set_log_level(cmd_parms * cmd, void *dummy, char *log_level) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->log_level = jk_parse_log_level(log_level); return NULL; } /* * JkLogStampFormat Directive Handling * * JkLogStampFormat "[%a %b %d %H:%M:%S %Y] " */ static const char *jk_set_log_fmt(cmd_parms * cmd, void *dummy, char *log_format) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->stamp_format_string = ap_pstrdup(cmd->pool, log_format); return NULL; } /* * JkAutoAlias Directive Handling * * JkAutoAlias application directory */ static const char *jk_set_auto_alias(cmd_parms * cmd, void *dummy, char *directory) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->alias_dir = directory; if (conf->alias_dir == NULL) return "JkAutoAlias directory invalid"; return NULL; } /* * JkStripSession directive handling * * JkStripSession On/Off [session path identifier] */ static const char *jk_set_strip_session(cmd_parms * cmd, void *dummy, const char *flag, const char *name) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); if (strcasecmp(flag, "on") && strcasecmp(flag, "off")) { return "JkStripSession must be On or Off"; } else { conf->strip_session = strcasecmp(flag, "off") ? JK_TRUE : JK_FALSE; } /* Check for optional path value */ if (name) conf->strip_session_name = ap_pstrdup(cmd->pool, name); else conf->strip_session_name = ap_pstrdup(cmd->pool, JK_PATH_SESSION_IDENTIFIER); return NULL; } /***************************************************************** * * Actually logging. */ typedef const char *(*item_key_func) (request_rec *, char *); typedef struct { item_key_func func; char *arg; } request_log_format_item; static const char *process_item(request_rec * r, request_log_format_item * item) { const char *cp; cp = (*item->func) (r, item->arg); return cp ? cp : "-"; } static int request_log_transaction(request_rec * r) { request_log_format_item *items; char *str, *s; int i; int len = 0; const char **strs; int *strl; jk_server_conf_t *conf; jk_request_conf_t *rconf; array_header *format; conf = (jk_server_conf_t *) ap_get_module_config(r->server->module_config, &jk_module); format = conf->format; if (format == NULL) { return DECLINED; } rconf = (jk_request_conf_t *)ap_get_module_config(r->request_config, &jk_module); if (rconf == NULL || rconf->jk_handled == JK_FALSE) { return DECLINED; } strs = ap_palloc(r->pool, sizeof(char *) * (format->nelts)); strl = ap_palloc(r->pool, sizeof(int) * (format->nelts)); items = (request_log_format_item *) format->elts; for (i = 0; i < format->nelts; ++i) { strs[i] = process_item(r, &items[i]); } for (i = 0; i < format->nelts; ++i) { len += strl[i] = strlen(strs[i]); } str = ap_palloc(r->pool, len + 1); for (i = 0, s = str; i < format->nelts; ++i) { memcpy(s, strs[i], strl[i]); s += strl[i]; } *s = 0; jk_log(conf->log, JK_LOG_REQUEST, "%s", str); return OK; } /***************************************************************** * * Parsing the log format string */ static char *format_integer(pool * p, int i) { return ap_psprintf(p, "%d", i); } static char *pfmt(pool * p, int i) { if (i <= 0) { return "-"; } else { return format_integer(p, i); } } static const char *constant_item(request_rec * dummy, char *stuff) { return stuff; } static const char *log_worker_name(request_rec * r, char *a) { return ap_table_get(r->notes, JK_NOTE_WORKER_NAME); } static const char *log_worker_route(request_rec * r, char *a) { return ap_table_get(r->notes, JK_NOTE_WORKER_ROUTE); } static const char *log_request_duration(request_rec * r, char *a) { return ap_table_get(r->notes, JK_NOTE_REQUEST_DURATION); } static const char *log_request_line(request_rec * r, char *a) { /* NOTE: If the original request contained a password, we * re-write the request line here to contain XXXXXX instead: * (note the truncation before the protocol string for HTTP/0.9 requests) * (note also that r->the_request contains the unmodified request) */ return (r->parsed_uri.password) ? ap_pstrcat(r->pool, r->method, " ", ap_unparse_uri_components(r-> pool, &r-> parsed_uri, 0), r->assbackwards ? NULL : " ", r->protocol, NULL) : r->the_request; } /* These next two routines use the canonical name:port so that log * parsers don't need to duplicate all the vhost parsing crud. */ static const char *log_virtual_host(request_rec * r, char *a) { return r->server->server_hostname; } static const char *log_server_port(request_rec * r, char *a) { return ap_psprintf(r->pool, "%u", r->server->port ? r->server-> port : ap_default_port(r)); } /* This respects the setting of UseCanonicalName so that * the dynamic mass virtual hosting trick works better. */ static const char *log_server_name(request_rec * r, char *a) { return ap_get_server_name(r); } static const char *log_request_uri(request_rec * r, char *a) { return r->uri; } static const char *log_request_method(request_rec * r, char *a) { return r->method; } static const char *log_request_protocol(request_rec * r, char *a) { return r->protocol; } static const char *log_request_query(request_rec * r, char *a) { return (r->args != NULL) ? ap_pstrcat(r->pool, "?", r->args, NULL) : ""; } static const char *log_status(request_rec * r, char *a) { return pfmt(r->pool, r->status); } static const char *clf_log_bytes_sent(request_rec * r, char *a) { if (!r->sent_bodyct) { return "-"; } else { long int bs; ap_bgetopt(r->connection->client, BO_BYTECT, &bs); return ap_psprintf(r->pool, "%ld", bs); } } static const char *log_bytes_sent(request_rec * r, char *a) { if (!r->sent_bodyct) { return "0"; } else { long int bs; ap_bgetopt(r->connection->client, BO_BYTECT, &bs); return ap_psprintf(r->pool, "%ld", bs); } } static struct log_item_list { char ch; item_key_func func; } log_item_keys[] = { { 'T', log_request_duration }, { 'r', log_request_line }, { 'U', log_request_uri }, { 's', log_status }, { 'b', clf_log_bytes_sent }, { 'B', log_bytes_sent }, { 'V', log_server_name }, { 'v', log_virtual_host }, { 'p', log_server_port }, { 'H', log_request_protocol }, { 'm', log_request_method }, { 'q', log_request_query }, { 'w', log_worker_name }, { 'R', log_worker_route}, { '\0', NULL } }; static struct log_item_list *find_log_func(char k) { int i; for (i = 0; log_item_keys[i].ch; ++i) if (k == log_item_keys[i].ch) { return &log_item_keys[i]; } return NULL; } static char *parse_request_log_misc_string(pool * p, request_log_format_item * it, const char **sa) { const char *s; char *d; it->func = constant_item; s = *sa; while (*s && *s != '%') { s++; } /* * This might allocate a few chars extra if there's a backslash * escape in the format string. */ it->arg = ap_palloc(p, s - *sa + 1); d = it->arg; s = *sa; while (*s && *s != '%') { if (*s != '\\') { *d++ = *s++; } else { s++; switch (*s) { case '\\': *d++ = '\\'; s++; break; case 'n': *d++ = '\n'; s++; break; case 't': *d++ = '\t'; s++; break; default: /* copy verbatim */ *d++ = '\\'; /* * Allow the loop to deal with this *s in the normal * fashion so that it handles end of string etc. * properly. */ break; } } } *d = '\0'; *sa = s; return NULL; } static char *parse_request_log_item(pool * p, request_log_format_item * it, const char **sa) { const char *s = *sa; struct log_item_list *l; if (*s != '%') { return parse_request_log_misc_string(p, it, sa); } ++s; it->arg = ""; /* For safety's sake... */ l = find_log_func(*s++); if (!l) { char dummy[2]; dummy[0] = s[-1]; dummy[1] = '\0'; return ap_pstrcat(p, "Unrecognized JkRequestLogFormat directive %", dummy, NULL); } it->func = l->func; *sa = s; return NULL; } static array_header *parse_request_log_string(pool * p, const char *s, const char **err) { array_header *a = ap_make_array(p, 0, sizeof(request_log_format_item)); char *res; while (*s) { if ((res = parse_request_log_item(p, (request_log_format_item *) ap_push_array(a), &s))) { *err = res; return NULL; } } return a; } /* * JkRequestLogFormat Directive Handling * * JkRequestLogFormat format string * * %b - Bytes sent, excluding HTTP headers. In CLF format * %B - Bytes sent, excluding HTTP headers. * %H - The request protocol * %m - The request method * %p - The canonical Port of the server serving the request * %q - The query string (prepended with a ? if a query string exists, * otherwise an empty string) * %r - First line of request * %s - request HTTP status code * %T - Requset duration, elapsed time to handle request in seconds '.' micro seconds * %U - The URL path requested, not including any query string. * %v - The canonical ServerName of the server serving the request. * %V - The server name according to the UseCanonicalName setting. * %w - Tomcat worker name */ static const char *jk_set_request_log_format(cmd_parms * cmd, void *dummy, char *format) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->format_string = ap_pstrdup(cmd->pool, format); return NULL; } /* * JkWorkerIndicator Directive Handling * * JkWorkerIndicator JkWorker */ static const char *jk_set_worker_indicator(cmd_parms * cmd, void *dummy, char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->worker_indicator = ap_pstrdup(cmd->pool, indicator); return NULL; } /* * Directives Handling for setting various environment names * used to overwrite the following request information: * - remote_addr * - remote_port * - remote_host * - remote_user * - auth_type * - server_name * - server_port */ static const char *jk_set_remote_addr_indicator(cmd_parms * cmd, void *dummy, char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->remote_addr_indicator = ap_pstrdup(cmd->pool, indicator); return NULL; } static const char *jk_set_remote_port_indicator(cmd_parms * cmd, void *dummy, char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->remote_port_indicator = ap_pstrdup(cmd->pool, indicator); return NULL; } static const char *jk_set_remote_host_indicator(cmd_parms * cmd, void *dummy, char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->remote_host_indicator = ap_pstrdup(cmd->pool, indicator); return NULL; } static const char *jk_set_remote_user_indicator(cmd_parms * cmd, void *dummy, char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->remote_user_indicator = ap_pstrdup(cmd->pool, indicator); return NULL; } static const char *jk_set_auth_type_indicator(cmd_parms * cmd, void *dummy, char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->auth_type_indicator = ap_pstrdup(cmd->pool, indicator); return NULL; } static const char *jk_set_local_name_indicator(cmd_parms * cmd, void *dummy, char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->local_name_indicator = ap_pstrdup(cmd->pool, indicator); return NULL; } static const char *jk_set_local_addr_indicator(cmd_parms * cmd, void *dummy, char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->local_addr_indicator = ap_pstrdup(cmd->pool, indicator); return NULL; } static const char *jk_set_local_port_indicator(cmd_parms * cmd, void *dummy, char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->local_port_indicator = ap_pstrdup(cmd->pool, indicator); return NULL; } static const char *jk_set_ignore_cl_indicator(cmd_parms * cmd, void *dummy, const char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->ignore_cl_indicator = ap_pstrdup(cmd->pool, indicator); return NULL; } /* * JkExtractSSL Directive Handling * * JkExtractSSL On/Off */ static const char *jk_set_enable_ssl(cmd_parms * cmd, void *dummy, int flag) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); /* Set up our value */ conf->ssl_enable = flag ? JK_TRUE : JK_FALSE; return NULL; } /* * JkHTTPSIndicator Directive Handling * * JkHTTPSIndicator HTTPS */ static const char *jk_set_https_indicator(cmd_parms * cmd, void *dummy, char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->https_indicator = ap_pstrdup(cmd->pool, indicator); return NULL; } /* * JkSSLPROTOCOLIndicator Directive Handling * * JkSSLPROTOCOLIndicator SSL_PROTOCOL */ static const char *jk_set_ssl_protocol_indicator(cmd_parms * cmd, void *dummy, char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->ssl_protocol_indicator = ap_pstrdup(cmd->pool, indicator); return NULL; } /* * JkCERTSIndicator Directive Handling * * JkCERTSIndicator SSL_CLIENT_CERT */ static const char *jk_set_certs_indicator(cmd_parms * cmd, void *dummy, char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->certs_indicator = ap_pstrdup(cmd->pool, indicator); return NULL; } /* * JkCIPHERIndicator Directive Handling * * JkCIPHERIndicator SSL_CIPHER */ static const char *jk_set_cipher_indicator(cmd_parms * cmd, void *dummy, char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->cipher_indicator = ap_pstrdup(cmd->pool, indicator); return NULL; } /* * JkCERTCHAINPrefix Directive Handling * * JkCERTCHAINPrefix SSL_CLIENT_CERT_CHAIN_ */ static const char *jk_set_certchain_prefix(cmd_parms * cmd, void *dummy, const char *prefix) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->certchain_prefix = ap_pstrdup(cmd->pool, prefix); return NULL; } /* * JkSESSIONIndicator Directive Handling * * JkSESSIONIndicator SSL_SESSION_ID */ static const char *jk_set_session_indicator(cmd_parms * cmd, void *dummy, char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->session_indicator = ap_pstrdup(cmd->pool, indicator); return NULL; } /* * JkKEYSIZEIndicator Directive Handling * * JkKEYSIZEIndicator SSL_CIPHER_USEKEYSIZE */ static const char *jk_set_key_size_indicator(cmd_parms * cmd, void *dummy, char *indicator) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->key_size_indicator = ap_pstrdup(cmd->pool, indicator); return NULL; } /* * JkOptions Directive Handling * * * +ForwardSSLKeySize => Forward SSL Key Size, to follow 2.3 specs but may broke old TC 3.2 * -ForwardSSLKeySize => Don't Forward SSL Key Size, will make mod_jk works with all TC release * ForwardURICompat => Forward URI normally, less spec compliant but mod_rewrite compatible (old TC) * ForwardURICompatUnparsed => Forward URI as unparsed, spec compliant but broke mod_rewrite (old TC) * ForwardURIEscaped => Forward URI escaped and Tomcat (3.3 rc2) stuff will do the decoding part * ForwardDirectories => Forward all directory requests with no index files to Tomcat * +ForwardSSLCertChain => Forward SSL certificate chain * -ForwardSSLCertChain => Don't forward SSL certificate chain */ const char *jk_set_options(cmd_parms * cmd, void *dummy, const char *line) { int opt = 0; int mask = 0; char action; char *w; server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); while (line[0] != 0) { w = ap_getword_conf(cmd->pool, &line); action = 0; if (*w == '+' || *w == '-') { action = *(w++); } mask = 0; if (action == '-' && (!strncasecmp(w, "ForwardURI", strlen("ForwardURI")) || !strncasecmp(w, "CollapseSlashes", strlen("CollapseSlashes")))) return ap_pstrcat(cmd->pool, "JkOptions: Illegal option '-", w, "': option can not be disabled", NULL); if (!strcasecmp(w, "ForwardURICompat")) { opt = JK_OPT_FWDURICOMPAT; mask = JK_OPT_FWDURIMASK; } else if (!strcasecmp(w, "ForwardURICompatUnparsed")) { opt = JK_OPT_FWDURICOMPATUNPARSED; mask = JK_OPT_FWDURIMASK; } else if (!strcasecmp(w, "ForwardURIEscaped")) { opt = JK_OPT_FWDURIESCAPED; mask = JK_OPT_FWDURIMASK; } else if (!strcasecmp(w, "ForwardURIProxy")) { opt = JK_OPT_FWDURIPROXY; mask = JK_OPT_FWDURIMASK; } else if (!strcasecmp(w, "CollapseSlashesAll")) { opt = JK_OPT_COLLAPSEALL; mask = JK_OPT_COLLAPSEMASK; } else if (!strcasecmp(w, "CollapseSlashesNone")) { opt = JK_OPT_COLLAPSENONE; mask = JK_OPT_COLLAPSEMASK; } else if (!strcasecmp(w, "CollapseSlashesUnmount")) { opt = JK_OPT_COLLAPSEUNMOUNT; mask = JK_OPT_COLLAPSEMASK; } else if (!strcasecmp(w, "ForwardDirectories")) { opt = JK_OPT_FWDDIRS; } else if (!strcasecmp(w, "ForwardLocalAddress")) { opt = JK_OPT_FWDLOCAL; } else if (!strcasecmp(w, "FlushPackets")) { opt = JK_OPT_FLUSHPACKETS; } else if (!strcasecmp(w, "FlushHeader")) { opt = JK_OPT_FLUSHEADER; } else if (!strcasecmp(w, "DisableReuse")) { opt = JK_OPT_DISABLEREUSE; } else if (!strcasecmp(w, "ForwardSSLCertChain")) { opt = JK_OPT_FWDCERTCHAIN; } else if (!strcasecmp(w, "ForwardKeySize")) { opt = JK_OPT_FWDKEYSIZE; } else if (!strcasecmp(w, "RejectUnsafeURI")) { opt = JK_OPT_REJECTUNSAFE; } else return ap_pstrcat(cmd->pool, "JkOptions: Illegal option '", w, "'", NULL); conf->options &= ~mask; if (action == '-') { conf->exclude_options |= opt; } else if (action == '+') { conf->options |= opt; } else { /* for now +Opt == Opt */ conf->options |= opt; } } return NULL; } /* * JkEnvVar Directive Handling * * JkEnvVar MYOWNDIR */ static const char *jk_add_env_var(cmd_parms * cmd, void *dummy, char *env_name, char *default_value) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); conf->envvars_has_own = JK_TRUE; if (!conf->envvars) { conf->envvars = ap_make_table(cmd->pool, 0); conf->envvars_def = ap_make_table(cmd->pool, 0); conf->envvar_items = ap_make_array(cmd->pool, 0, sizeof(envvar_item)); } /* env_name is mandatory, default_value is optional. * No value means send the attribute only, if the env var is set during runtime. */ ap_table_setn(conf->envvars, env_name, default_value ? default_value : ""); ap_table_setn(conf->envvars_def, env_name, default_value ? "1" : "0"); return NULL; } /* * JkWorkerProperty Directive Handling * * JkWorkerProperty name=value */ static const char *jk_set_worker_property(cmd_parms * cmd, void *dummy, const char *line) { server_rec *s = cmd->server; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); if (!jk_worker_properties) jk_map_alloc(&jk_worker_properties); if (jk_map_read_property(jk_worker_properties, NULL, line, JK_MAP_HANDLE_DUPLICATES, conf->log) == JK_FALSE) return ap_pstrcat(cmd->temp_pool, "Invalid JkWorkerProperty ", line, NULL); return NULL; } static const command_rec jk_cmds[] = { /* * JkWorkersFile specifies a full path to the location of the worker * properties file. * * This file defines the different workers used by apache to redirect * servlet requests. */ {"JkWorkersFile", jk_set_worker_file, NULL, RSRC_CONF, TAKE1, "The name of a worker file for the Tomcat servlet containers"}, /* * JkMountFile specifies a full path to the location of the * uriworker properties file. * * This file defines the different mapping for workers used by apache * to redirect servlet requests. */ {"JkMountFile", jk_set_mount_file, NULL, RSRC_CONF, TAKE1, "The name of a mount file for the Tomcat servlet uri mappings"}, /* * JkMountFileReload specifies the reload check interval for the * uriworker properties file. * * Default value is: JK_URIMAP_DEF_RELOAD */ {"JkMountFileReload", jk_set_mount_file_reload, NULL, RSRC_CONF, TAKE1, "The reload check interval of the mount file"}, /* * JkMount mounts a url prefix to a worker (the worker need to be * defined in the worker properties file. */ {"JkMount", jk_mount_context, NULL, RSRC_CONF|ACCESS_CONF, TAKE12, "A mount point from a context to a servlet-engine worker"}, /* * JkUnMount unmounts a url prefix to a worker (the worker need to be * defined in the worker properties file. */ {"JkUnMount", jk_unmount_context, NULL, RSRC_CONF|ACCESS_CONF, TAKE12, "A no mount point from a context to a servlet-engine worker"}, /* * JkMountCopy specifies if mod_jk should copy the mount points * from the main server to the virtual servers. */ {"JkMountCopy", jk_set_mountcopy, NULL, RSRC_CONF, TAKE1, "Should the base server mounts be copied to the virtual server"}, /* * JkStripSession specifies if mod_jk should strip the ;jsessionid * from the unmapped urls */ {"JkStripSession", jk_set_strip_session, NULL, RSRC_CONF, TAKE12, "Should the server strip the jsessionid from unmapped URLs"}, /* * JkLogFile & JkLogLevel specifies to where should the plugin log * its information and how much. * JkLogStampFormat specify the time-stamp to be used on log */ {"JkLogFile", jk_set_log_file, NULL, RSRC_CONF, TAKE1, "Full path to the mod_jk module log file"}, {"JkShmFile", jk_set_shm_file, NULL, RSRC_CONF, TAKE1, "Full path to the mod_jk module shared memory file"}, {"JkShmSize", jk_set_shm_size, NULL, RSRC_CONF, TAKE1, "Size of the shared memory file in KBytes"}, {"JkLogLevel", jk_set_log_level, NULL, RSRC_CONF, TAKE1, "The mod_jk module log level, can be debug, info, request, error, or emerg"}, {"JkLogStampFormat", jk_set_log_fmt, NULL, RSRC_CONF, TAKE1, "The mod_jk module log format, follow strftime syntax"}, {"JkRequestLogFormat", jk_set_request_log_format, NULL, RSRC_CONF, TAKE1, "The mod_jk module request log format string"}, /* * Automatically Alias webapp context directories into the Apache * document space. */ {"JkAutoAlias", jk_set_auto_alias, NULL, RSRC_CONF, TAKE1, "The mod_jk module automatic context apache alias directory"}, /* * Enable worker name to be set in an environment variable. * This way one can use LocationMatch together with mod_env, * mod_setenvif and mod_rewrite to set the target worker. * Use this in combination with SetHandler jakarta-servlet to * make mod_jk the handler for the request. * */ {"JkWorkerIndicator", jk_set_worker_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains the worker name"}, /* * Environment variables used to overwrite the following * request information which gets forwarded: * - remote_addr * - remote_port * - remote_host * - remote_user * - auth_type * - server_name * - server_port */ {"JkRemoteAddrIndicator", jk_set_remote_addr_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains the remote address"}, {"JkRemotePortIndicator", jk_set_remote_port_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains the remote port"}, {"JkRemoteHostIndicator", jk_set_remote_host_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains the remote host name"}, {"JkRemoteUserIndicator", jk_set_remote_user_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains the remote user name"}, {"JkAuthTypeIndicator", jk_set_auth_type_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains the type of authentication"}, {"JkLocalNameIndicator", jk_set_local_name_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains the local name"}, {"JkLocalAddrIndicator", jk_set_local_addr_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains the local IP address"}, {"JkLocalPortIndicator", jk_set_local_port_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains the local port"}, {"JkIgnoreCLIndicator", jk_set_ignore_cl_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that forces to ignore a request " "Content-Length header"}, /* * Apache has multiple SSL modules (for example apache_ssl, stronghold * IHS ...). Each of these can have a different SSL environment names * The following properties let the administrator specify the envoiroment * variables names. * * HTTPS - indication for SSL * CERTS - Base64-Der-encoded client certificates. * CIPHER - A string specifing the ciphers suite in use. * SESSION - A string specifing the current SSL session. * KEYSIZE - Size of Key used in dialogue (#bits are secure) */ {"JkHTTPSIndicator", jk_set_https_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains SSL indication"}, {"JkSSLPROTOCOLIndicator", jk_set_ssl_protocol_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains the SSL protocol name"}, {"JkCERTSIndicator", jk_set_certs_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains SSL client certificates"}, {"JkCIPHERIndicator", jk_set_cipher_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains SSL client cipher"}, {"JkCERTCHAINPrefix", jk_set_certchain_prefix, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment (prefix) that contains SSL client chain certificates"}, {"JkSESSIONIndicator", jk_set_session_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains SSL session"}, {"JkKEYSIZEIndicator", jk_set_key_size_indicator, NULL, RSRC_CONF, TAKE1, "Name of the Apache environment that contains SSL key size in use"}, {"JkExtractSSL", jk_set_enable_ssl, NULL, RSRC_CONF, FLAG, "Turns on SSL processing and information gathering by mod_jk"}, /* * Options to tune mod_jk configuration * for now we understand : * +ForwardSSLKeySize => Forward SSL Key Size, to follow 2.3 specs but may broke old TC 3.2 * -ForwardSSLKeySize => Don't Forward SSL Key Size, will make mod_jk works with all TC release * ForwardURICompat => Forward URI normally, less spec compliant but mod_rewrite compatible (old TC) * ForwardURICompatUnparsed => Forward URI as unparsed, spec compliant but broke mod_rewrite (old TC) * ForwardURIEscaped => Forward URI escaped and Tomcat (3.3 rc2) stuff will do the decoding part * +ForwardSSLCertChain => Forward SSL certificate chain * -ForwardSSLCertChain => Don't forward SSL certificate chain */ {"JkOptions", jk_set_options, NULL, RSRC_CONF, RAW_ARGS, "Set one of more options to configure the mod_jk module"}, /* * JkEnvVar let user defines envs var passed from WebServer to * Servlet Engine */ {"JkEnvVar", jk_add_env_var, NULL, RSRC_CONF, TAKE12, "Adds a name of environment variable and an optional value " "that should be sent to servlet-engine"}, {"JkWorkerProperty", jk_set_worker_property, NULL, RSRC_CONF, RAW_ARGS, "Set workers.properties formated directive"}, {NULL} }; /* ====================================================================== */ /* The JK module handlers */ /* ====================================================================== */ /* * Called to handle a single request. */ static int jk_handler(request_rec * r) { jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(r->server-> module_config, &jk_module); jk_request_conf_t *rconf; int worker_name_extension = JK_FALSE; /* Retrieve the worker name stored by jk_translate() */ const char *worker_name; int rc; JK_TRACE_ENTER(conf->log); if (ap_table_get(r->subprocess_env, "no-jk")) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Into handler no-jk env var detected for uri=%s, declined", r->uri); JK_TRACE_EXIT(conf->log); return DECLINED; } worker_name = ap_table_get(r->notes, JK_NOTE_WORKER_NAME); if (worker_name == NULL && r->handler && !strcmp(r->handler, JK_HANDLER)) { /* we may be here because of a manual directive ( that overrides * translate and * sets the handler directly ). We still need to know the worker. */ if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Retrieving environment %s", conf->worker_indicator); worker_name = (char *)ap_table_get(r->subprocess_env, conf->worker_indicator); if (worker_name) { /* The JkWorkerIndicator environment variable has * been used to explicitely set the worker without JkMount. * This is useful in combination with LocationMatch or mod_rewrite. */ if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Retrieved worker (%s) from env %s for %s", worker_name, conf->worker_indicator, r->uri); if (strchr(worker_name, ';')) { rule_extension_t *e = ap_palloc(r->pool, sizeof(rule_extension_t)); char *w = ap_pstrdup(r->pool, worker_name); worker_name_extension = JK_TRUE; parse_rule_extensions(w, e, conf->log); worker_name = w; rconf = (jk_request_conf_t *)ap_get_module_config(r->request_config, &jk_module); rconf->rule_extensions = e; } } else if (worker_env.num_of_workers == 1) { /* We have a single worker ( the common case ). * ( lb is a bit special, it should count as a single worker but * I'm not sure how ). We also have a manual config directive that * explicitely give control to us. */ worker_name = worker_env.worker_list[0]; if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Single worker (%s) configuration for %s", worker_name, r->uri); } else if (worker_env.num_of_workers) { worker_name = worker_env.worker_list[0]; if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Using first worker (%s) from %d workers for %s", worker_name, worker_env.num_of_workers, r->uri); } } if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Into handler %s worker=%s" " r->proxyreq=%d", r->handler, STRNULL_FOR_NULL(worker_name), r->proxyreq); rconf = (jk_request_conf_t *)ap_get_module_config(r->request_config, &jk_module); rconf->jk_handled = JK_TRUE; if (r->proxyreq) { jk_log(conf->log, JK_LOG_ERROR, "Request has proxyreq flag set in mod_jk handler - aborting."); JK_TRACE_EXIT(conf->log); return HTTP_INTERNAL_SERVER_ERROR; } /* Set up r->read_chunked flags for chunked encoding, if present */ if ((rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK))) { jk_log(conf->log, JK_LOG_ERROR, "Could not setup client_block for chunked encoding - aborting"); JK_TRACE_EXIT(conf->log); return rc; } if (worker_name) { jk_worker_t *worker; worker = wc_get_worker_for_name(worker_name, conf->log); if (worker) { #ifndef NO_GETTIMEOFDAY struct timeval tv_begin, tv_end; long micro, seconds; char *duration = NULL; #endif int rc = JK_FALSE; int is_error = JK_HTTP_SERVER_ERROR; apache_private_data_t private_data; jk_ws_service_t s; jk_pool_atom_t buf[SMALL_POOL_SIZE]; jk_open_pool(&private_data.p, buf, sizeof(buf)); private_data.read_body_started = JK_FALSE; private_data.r = r; if (worker_name_extension == JK_TRUE) { extension_fix(&private_data.p, worker_name, rconf->rule_extensions, conf->log); } wc_maintain(conf->log); jk_init_ws_service(&s); s.ws_private = &private_data; s.pool = &private_data.p; ap_table_setn(r->notes, JK_NOTE_WORKER_TYPE, wc_get_name_for_type(worker->type, conf->log)); #ifndef NO_GETTIMEOFDAY gettimeofday(&tv_begin, NULL); #endif if (init_ws_service(&private_data, &s, conf)) { jk_endpoint_t *end = NULL; if (worker->get_endpoint(worker, &end, conf->log)) { rc = end->service(end, &s, conf->log, &is_error); end->done(&end, conf->log); if (s.content_read < s.content_length || (s.is_chunked && !s.no_more_chunks)) { /* * If the servlet engine didn't consume all of the * request data, consume and discard all further * characters left to read from client */ char *buff = ap_palloc(r->pool, 2048); int consumed = 0; if (buff != NULL) { int rd; while ((rd = ap_get_client_block(r, buff, 2048)) > 0) { s.content_read += rd; consumed += rd; } } if (JK_IS_DEBUG_LEVEL(conf->log)) { jk_log(conf->log, JK_LOG_DEBUG, "Consumed %d bytes of remaining request data for worker=%s", consumed, STRNULL_FOR_NULL(worker_name)); } } } else { jk_log(conf->log, JK_LOG_ERROR, "Could not get endpoint" " for worker=%s", STRNULL_FOR_NULL(worker_name)); rc = 0; /* just to make sure that we know we've failed */ is_error = HTTP_SERVICE_UNAVAILABLE; } #ifndef NO_GETTIMEOFDAY gettimeofday(&tv_end, NULL); if (tv_end.tv_usec < tv_begin.tv_usec) { tv_end.tv_usec += 1000000; tv_end.tv_sec--; } micro = tv_end.tv_usec - tv_begin.tv_usec; seconds = tv_end.tv_sec - tv_begin.tv_sec; duration = ap_psprintf(r->pool, "%.1ld.%.6ld", seconds, micro); ap_table_setn(r->notes, JK_NOTE_REQUEST_DURATION, duration); #endif if (s.route && *s.route) ap_table_set(r->notes, JK_NOTE_WORKER_ROUTE, s.route); } else { jk_log(conf->log, JK_LOG_ERROR, "Could not init service" " for worker=%s", worker_name); jk_close_pool(&private_data.p); JK_TRACE_EXIT(conf->log); return is_error; } jk_close_pool(&private_data.p); if (rc > 0) { if (s.extension.use_server_error_pages && s.http_response_status >= s.extension.use_server_error_pages) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Forwarding status=%d" " for worker=%s", s.http_response_status, worker_name); JK_TRACE_EXIT(conf->log); return s.http_response_status; } /* If tomcat returned no body and the status is not OK, let apache handle the error code */ if (!r->sent_bodyct && r->status >= HTTP_BAD_REQUEST) { jk_log(conf->log, JK_LOG_INFO, "No body with status=%d" " for worker=%s", r->status, worker_name); JK_TRACE_EXIT(conf->log); return r->status; } if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Service finished" " with status=%d for worker=%s", r->status, worker_name); JK_TRACE_EXIT(conf->log); return OK; /* NOT r->status, even if it has changed. */ } else if (rc == JK_CLIENT_ERROR) { if (is_error != HTTP_REQUEST_ENTITY_TOO_LARGE) r->connection->aborted = 1; jk_log(conf->log, JK_LOG_INFO, "Aborting connection" " for worker=%s", worker_name); JK_TRACE_EXIT(conf->log); return is_error; } else { jk_log(conf->log, JK_LOG_INFO, "Service error=%d" " for worker=%s", rc, worker_name); JK_TRACE_EXIT(conf->log); return is_error; } } else { jk_log(conf->log, JK_LOG_ERROR, "Could not init service" " for worker=%s", worker_name); JK_TRACE_EXIT(conf->log); return HTTP_INTERNAL_SERVER_ERROR; } } JK_TRACE_EXIT(conf->log); return HTTP_INTERNAL_SERVER_ERROR; } /* * Create a default config object. */ static void *create_jk_config(ap_pool * p, server_rec * s) { jk_server_conf_t *c = (jk_server_conf_t *) ap_pcalloc(p, sizeof(jk_server_conf_t)); c->mountcopy = JK_FALSE; c->was_initialized = JK_FALSE; if (s->is_virtual) { c->mountcopy = JK_UNSET; c->mount_file_reload = JK_UNSET; c->log_level = JK_UNSET; c->ssl_enable = JK_UNSET; c->strip_session = JK_UNSET; } else { if (!jk_map_alloc(&(c->uri_to_context))) { ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, NULL, "Memory error"); } c->mountcopy = JK_FALSE; c->mount_file_reload = JK_URIMAP_DEF_RELOAD; c->log_level = JK_LOG_DEF_LEVEL; c->options = JK_OPT_DEFAULT; c->worker_indicator = JK_ENV_WORKER_NAME; /* * Configurable environment variables to overwrite * request information using meta data send by a * proxy in front of us. */ c->remote_addr_indicator = JK_ENV_REMOTE_ADDR; c->remote_port_indicator = JK_ENV_REMOTE_PORT; c->remote_host_indicator = JK_ENV_REMOTE_HOST; c->remote_user_indicator = JK_ENV_REMOTE_USER; c->auth_type_indicator = JK_ENV_AUTH_TYPE; c->local_name_indicator = JK_ENV_LOCAL_NAME; c->local_addr_indicator = JK_ENV_LOCAL_ADDR; c->local_port_indicator = JK_ENV_LOCAL_PORT; c->ignore_cl_indicator = JK_ENV_IGNORE_CL; /* * By default we will try to gather SSL info. * Disable this functionality through JkExtractSSL */ c->ssl_enable = JK_TRUE; /* * The defaults ssl indicators match those in mod_ssl (seems * to be in more use). */ c->https_indicator = JK_ENV_HTTPS; c->ssl_protocol_indicator = JK_ENV_SSL_PROTOCOL; c->certs_indicator = JK_ENV_CERTS; c->cipher_indicator = JK_ENV_CIPHER; c->certchain_prefix = JK_ENV_CERTCHAIN_PREFIX; c->session_indicator = JK_ENV_SESSION; c->key_size_indicator = JK_ENV_KEY_SIZE; c->strip_session = JK_FALSE; } c->envvars_has_own = JK_FALSE; c->s = s; return c; } /* * Utility - copy items from apr table src to dst, * for keys that exist in src but not in dst. */ static void merge_apr_table(table *src, table *dst) { int i; const array_header *arr; const table_entry *elts; arr = ap_table_elts(src); elts = (const table_entry *)arr->elts; for (i = 0; i < arr->nelts; ++i) { if (!ap_table_get(dst, elts[i].key)) { ap_table_setn(dst, elts[i].key, elts[i].val); } } } static void *merge_jk_config(ap_pool * p, void *basev, void *overridesv) { jk_server_conf_t *base = (jk_server_conf_t *) basev; jk_server_conf_t *overrides = (jk_server_conf_t *) overridesv; int mask = 0; if (!overrides->log_file) overrides->log_file = base->log_file; if (overrides->log_level == JK_UNSET) overrides->log_level = base->log_level; if (!overrides->stamp_format_string) overrides->stamp_format_string = base->stamp_format_string; if (!overrides->format_string) overrides->format_string = base->format_string; if (!overrides->worker_indicator) overrides->worker_indicator = base->worker_indicator; if (!overrides->remote_addr_indicator) overrides->remote_addr_indicator = base->remote_addr_indicator; if (!overrides->remote_port_indicator) overrides->remote_port_indicator = base->remote_port_indicator; if (!overrides->remote_host_indicator) overrides->remote_host_indicator = base->remote_host_indicator; if (!overrides->remote_user_indicator) overrides->remote_user_indicator = base->remote_user_indicator; if (!overrides->auth_type_indicator) overrides->auth_type_indicator = base->auth_type_indicator; if (!overrides->local_name_indicator) overrides->local_name_indicator = base->local_name_indicator; if (!overrides->local_port_indicator) overrides->local_port_indicator = base->local_port_indicator; if (!overrides->ignore_cl_indicator) overrides->ignore_cl_indicator = base->ignore_cl_indicator; if (overrides->ssl_enable == JK_UNSET) overrides->ssl_enable = base->ssl_enable; if (!overrides->https_indicator) overrides->https_indicator = base->https_indicator; if (!overrides->ssl_protocol_indicator) overrides->ssl_protocol_indicator = base->ssl_protocol_indicator; if (!overrides->certs_indicator) overrides->certs_indicator = base->certs_indicator; if (!overrides->cipher_indicator) overrides->cipher_indicator = base->cipher_indicator; if (!overrides->certchain_prefix) overrides->certchain_prefix = base->certchain_prefix; if (!overrides->session_indicator) overrides->session_indicator = base->session_indicator; if (!overrides->key_size_indicator) overrides->key_size_indicator = base->key_size_indicator; /* Don't simply accumulate bits in the JK_OPT_FWDURIMASK or * JK_OPT_COLLAPSEMASK region, because those are multi-bit values. */ if (overrides->options & JK_OPT_FWDURIMASK) mask |= JK_OPT_FWDURIMASK; if (overrides->options & JK_OPT_COLLAPSEMASK) mask |= JK_OPT_COLLAPSEMASK; overrides->options |= (base->options & ~base->exclude_options) & ~mask; if (base->envvars) { if (overrides->envvars && overrides->envvars_has_own) { /* merge_apr_table() preserves existing entries in overrides table */ merge_apr_table(base->envvars, overrides->envvars); merge_apr_table(base->envvars_def, overrides->envvars_def); } else { overrides->envvars = base->envvars; overrides->envvars_def = base->envvars_def; overrides->envvar_items = base->envvar_items; } } if (overrides->mountcopy == JK_UNSET && jk_mount_copy_all == JK_TRUE) { overrides->mountcopy = JK_TRUE; } if (overrides->uri_to_context && overrides->mountcopy == JK_TRUE) { /* jk_map_copy() preserves existing entries in overrides map */ if (jk_map_copy(base->uri_to_context, overrides->uri_to_context) == JK_FALSE) { jk_error_exit(APLOG_MARK, APLOG_EMERG, overrides->s, p, "Memory error"); } if (!overrides->mount_file) overrides->mount_file = base->mount_file; } if (overrides->mountcopy == JK_TRUE) { if (!overrides->alias_dir) overrides->alias_dir = base->alias_dir; } if (overrides->mount_file_reload == JK_UNSET) overrides->mount_file_reload = base->mount_file_reload; if (overrides->strip_session == JK_UNSET) { overrides->strip_session = base->strip_session; overrides->strip_session_name = base->strip_session_name; } return overrides; } static int JK_METHOD jk_log_to_file(jk_logger_t *l, int level, int used, char *what) { if (l && (l->level <= level || level == JK_LOG_REQUEST_LEVEL) && l->logger_private && what && used > 0) { jk_file_logger_t *flp = l->logger_private; int log_fd = flp->log_fd; if (log_fd >= 0) { #if defined(WIN32) what[used++] = '\r'; #endif what[used++] = '\n'; if (write(log_fd, what, used) < 0 ) { ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, NULL, "mod_jk: jk_log_to_file %.*s failed", used, what); } } else { /* Can't use mod_jk log any more, log to error log instead. * Choose APLOG_ERR, since we already checked above, that if * the mod_jk log file would still be open, we would have * actually logged the message there */ ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, NULL, "%.*s", used, what); } return JK_TRUE; } return JK_FALSE; } static int log_fd_get(char *key) { const char *buf=ap_table_get(jk_log_fds, key); if (buf) return atoi(buf); return 0; } static void log_fd_set(pool *p, char *key, int v) { char *buf=(char *)ap_pcalloc(p, 8*sizeof(char)); ap_snprintf(buf, 8, "%d", v); ap_table_setn(jk_log_fds, key, buf); } static void open_jk_log(server_rec *s, pool *p) { const char *fname; int jklogfd; piped_log *pl; jk_logger_t *jkl; jk_file_logger_t *flp; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); if (!s->is_virtual && !conf->log_file) { conf->log_file = ap_server_root_relative(p, JK_LOG_DEF_FILE); if (conf->log_file) ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, s, "No JkLogFile defined in httpd.conf. " "Using default %s", conf->log_file); } if (s->is_virtual && conf->log_file == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, s, "mod_jk: Invalid JkLogFile NULL"); conf->log = main_log; return; } if (s->is_virtual && *(conf->log_file) == '\0') { ap_log_error(APLOG_MARK, APLOG_ERR, s, "mod_jk: Invalid JkLogFile EMPTY"); conf->log = main_log; return; } #ifdef CHROOTED_APACHE ap_server_strip_chroot(conf->log_file, 0); #endif jklogfd = log_fd_get(conf->log_file); if (!jklogfd) { if (*conf->log_file == '|') { if ((pl = ap_open_piped_log(p, conf->log_file + 1)) == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, s, "mod_jk: could not open reliable pipe " "to jk log %s", conf->log_file + 1); exit(1); } jklogfd = ap_piped_log_write_fd(pl); } else { fname = ap_server_root_relative(p, conf->log_file); if (!fname) { ap_log_error(APLOG_MARK, APLOG_ERR, s, "mod_jk: Invalid JkLog " "path %s", conf->log_file); exit(1); } #if AP_MODULE_MAGIC_AT_LEAST(19990320,14) if ((jklogfd = ap_popenf_ex(p, fname, xfer_flags, xfer_mode, 1)) < 0) { #else if ((jklogfd = ap_popenf(p, fname, xfer_flags, xfer_mode)) < 0) { #endif ap_log_error(APLOG_MARK, APLOG_ERR, s, "mod_jk: could not open JkLog " "file %s", fname); exit(1); } } log_fd_set(p, conf->log_file, jklogfd); } jkl = (jk_logger_t *)ap_palloc(p, sizeof(jk_logger_t)); flp = (jk_file_logger_t *)ap_palloc(p, sizeof(jk_file_logger_t)); if (jkl && flp) { jkl->log = jk_log_to_file; jkl->level = conf->log_level; jkl->logger_private = flp; flp->log_fd = jklogfd; if (*conf->log_file == '|') flp->is_piped = JK_TRUE; else flp->is_piped = JK_FALSE; conf->log = jkl; jk_set_time_fmt(conf->log, conf->stamp_format_string); if (main_log == NULL) main_log = conf->log; return; } return; } static void jk_init(server_rec * s, ap_pool * p) { int rc; server_rec *srv = s; const char *err_string = NULL; int remain; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); remain = jk_check_buffer_size(); if (remain < 0) { jk_error_exit(APLOG_MARK, APLOG_EMERG, srv, p, "mod_jk: JK_MAX_ATTRIBUTE_NAME_LEN in jk_util.c is too small, " "increase by %d", -1 * remain); } if (!jk_worker_properties) jk_map_alloc(&jk_worker_properties); jk_map_put(jk_worker_properties, "ServerRoot", ap_server_root, NULL); main_server = s; jk_log_fds = ap_make_table(p, 0); /* step through the servers and open each jk logfile * and do additional post config initialization. */ for (; srv; srv = srv->next) { jk_server_conf_t *sconf = (jk_server_conf_t *)ap_get_module_config(srv->module_config, &jk_module); /* * If a virtual server contains no JK directive, httpd shares * the config structure. But we don't want to share some settings * by default, especially the JkMount rules. * Therefore we check, if this config structure really belongs to this * vhost, otherwise we create a new one and merge. */ if (sconf && sconf->s != srv) { jk_server_conf_t *srvconf = (jk_server_conf_t *)create_jk_config(p, srv); sconf = (jk_server_conf_t *)merge_jk_config(p, sconf, srvconf); ap_set_module_config(srv->module_config, &jk_module, sconf); } if (sconf && sconf->was_initialized == JK_FALSE) { sconf->was_initialized = JK_TRUE; open_jk_log(srv, p); sconf->options &= ~sconf->exclude_options; dump_options(srv, p); if (sconf->uri_to_context) { if (!uri_worker_map_alloc(&(sconf->uw_map), sconf->uri_to_context, sconf->log)) jk_error_exit(APLOG_MARK, APLOG_EMERG, srv, p, "Memory error"); if (sconf->options & JK_OPT_REJECTUNSAFE) sconf->uw_map->reject_unsafe = 1; else sconf->uw_map->reject_unsafe = 0; if (sconf->mount_file) { sconf->uw_map->fname = sconf->mount_file; sconf->uw_map->reload = sconf->mount_file_reload; uri_worker_map_switch(sconf->uw_map, sconf->log); uri_worker_map_load(sconf->uw_map, sconf->log); } switch (sconf->options & JK_OPT_COLLAPSEMASK) { case JK_OPT_COLLAPSEALL: sconf->uw_map->collapse_slashes = JK_COLLAPSE_ALL; break; case JK_OPT_COLLAPSENONE: sconf->uw_map->collapse_slashes = JK_COLLAPSE_NONE; break; case JK_OPT_COLLAPSEUNMOUNT: sconf->uw_map->collapse_slashes = JK_COLLAPSE_UNMOUNT; break; default: ap_log_error(APLOG_MARK, APLOG_WARNING, srv, "Collapse slashes value %d ignored, setting to %d", sconf->options & JK_OPT_COLLAPSEMASK, JK_COLLAPSE_DEFAULT); sconf->uw_map->collapse_slashes = JK_COLLAPSE_DEFAULT; } } else { if (sconf->mountcopy == JK_TRUE) { sconf->uw_map = conf->uw_map; } } if (sconf->format_string) { sconf->format = parse_request_log_string(p, sconf->format_string, &err_string); if (sconf->format == NULL) ap_log_error(APLOG_MARK, APLOG_ERR, srv, "JkRequestLogFormat format array NULL"); } if (sconf->envvars && sconf->envvars_has_own) { int i; const array_header *arr; const table_entry *elts; envvar_item *item; const char *envvar_def; arr = ap_table_elts(sconf->envvars); if (arr) { elts = (const table_entry *)arr->elts; for (i = 0; i < arr->nelts; ++i) { item = (envvar_item *)ap_push_array(sconf->envvar_items); if (!item) jk_error_exit(APLOG_MARK, APLOG_EMERG, srv, p, "Memory error"); item->name = elts[i].key; envvar_def = ap_table_get(sconf->envvars_def, elts[i].key); if (envvar_def && !strcmp("1", envvar_def) ) { item->value = elts[i].val; item->has_default = 1; } else { item->value = ""; item->has_default = 0; } } } } } } if ((jk_worker_file != NULL) && !jk_map_read_properties(jk_worker_properties, NULL, jk_worker_file, NULL, JK_MAP_HANDLE_DUPLICATES, conf->log)) { jk_error_exit(APLOG_MARK, APLOG_EMERG | APLOG_NOERRNO, s, p, "Error in reading worker properties from '%s'", jk_worker_file); } if (jk_map_resolve_references(jk_worker_properties, "worker.", 1, 1, conf->log) == JK_FALSE) { jk_error_exit(APLOG_MARK, APLOG_EMERG | APLOG_NOERRNO, s, p, "Error in resolving configuration references"); } #if !defined(WIN32) && !defined(NETWARE) if (!jk_shm_file) { jk_shm_file = ap_server_root_relative(p, JK_SHM_DEF_FILE); #ifdef CHROOTED_APACHE ap_server_strip_chroot(jk_shm_file, 0); #endif if (jk_shm_file) ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_NOERRNO, s, "No JkShmFile defined in httpd.conf. " "Using default %s", jk_shm_file); } #endif if (jk_shm_size == 0) { jk_shm_size = jk_shm_calculate_size(jk_worker_properties, conf->log); } else if (jk_shm_size_set) { jk_log(conf->log, JK_LOG_WARNING, "The optimal shared memory size can now be determined automatically."); jk_log(conf->log, JK_LOG_WARNING, "You can remove the JkShmSize directive if you want to use the optimal size."); } if ((rc = jk_shm_open(jk_shm_file, jk_shm_size, conf->log)) != 0) { jk_log(conf->log, JK_LOG_ERROR, "Initializing shm:%s errno=%d. Load balancing workers will not function properly.", jk_shm_name(), rc); } /* SREVILAK -- register cleanup handler to clear resources on restart, * to make sure log file gets closed in the parent process */ ap_register_cleanup(p, s, jk_server_cleanup, ap_null_cleanup); /* we add the URI->WORKER MAP since workers using AJP14 will feed it */ worker_env.uri_to_worker = conf->uw_map; worker_env.virtual = "*"; /* for now */ worker_env.server_name = (char *)ap_get_server_version(); worker_env.pool = NULL; if (wc_open(jk_worker_properties, &worker_env, conf->log)) { #if MODULE_MAGIC_NUMBER >= 19980527 /* Tell apache we're here */ ap_add_version_component(JK_EXPOSED_VERSION); #endif jk_log(conf->log, JK_LOG_INFO, "%s initialized", JK_FULL_EXPOSED_VERSION); } else { jk_error_exit(APLOG_MARK, APLOG_EMERG | APLOG_NOERRNO, s, p, "Error in creating the workers." " Please consult your mod_jk log file '%s'.", conf->log_file); } if (conf->uw_map) { uri_worker_map_ext(conf->uw_map, conf->log); uri_worker_map_switch(conf->uw_map, conf->log); } for (srv = s; srv; srv = srv->next) { jk_server_conf_t *sconf = (jk_server_conf_t *)ap_get_module_config(srv->module_config, &jk_module); if (conf->uw_map != sconf->uw_map && sconf->uw_map) { uri_worker_map_ext(sconf->uw_map, sconf->log); uri_worker_map_switch(sconf->uw_map, sconf->log); } } } /* * Perform uri to worker mapping, and store the name of the relevant worker * in the notes fields of the request_rec object passed in. This will then * get picked up in jk_handler(). */ static int jk_translate(request_rec * r) { jk_request_conf_t *rconf = ap_palloc(r->pool, sizeof(jk_request_conf_t)); rconf->jk_handled = JK_FALSE; rconf->rule_extensions = NULL; ap_set_module_config(r->request_config, &jk_module, rconf); if (!r->proxyreq) { jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(r->server-> module_config, &jk_module); if (conf) { const char *worker; if (ap_table_get(r->subprocess_env, "no-jk")) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Into translate no-jk env var detected for uri=%s, declined", r->uri); return DECLINED; } if (!conf->uw_map) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "missing uri map for %s:%s", conf->s->server_hostname ? conf->s->server_hostname : "_default_", r->uri); return DECLINED; } else { rule_extension_t *e; worker = map_uri_to_worker_ext(conf->uw_map, r->uri, NULL, &e, NULL, conf->log); rconf->rule_extensions = e; ap_set_module_config(r->request_config, &jk_module, rconf); } /* Don't know the worker, ForwardDirectories is set, there is a * previous request for which the handler is JK_HANDLER (as set by * jk_fixups) and the request is for a directory: * --> forward to Tomcat, via default worker */ if (!worker && (conf->options & JK_OPT_FWDDIRS) && r->prev && r->prev->handler && !strcmp(r->prev->handler, JK_HANDLER) && r->uri && strlen(r->uri) && r->uri[strlen(r->uri) - 1] == '/') { if (worker_env.num_of_workers) { /* Nothing here to do but assign the first worker since we * already tried mapping and it didn't work out */ worker = worker_env.worker_list[0]; if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Manual configuration for %s %s", r->uri, worker_env.worker_list[0]); } } if (worker) { r->handler = ap_pstrdup(r->pool, JK_HANDLER); ap_table_setn(r->notes, JK_NOTE_WORKER_NAME, worker); } else if (conf->alias_dir != NULL) { char *clean_uri = ap_pstrdup(r->pool, r->uri); ap_no2slash(clean_uri); /* Automatically map uri to a context static file */ if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "check alias_dir: %s", conf->alias_dir); if (strlen(clean_uri) > 1) { /* Get the context directory name */ char *context_dir = NULL; char *context_path = NULL; char *child_dir = NULL; char *index = clean_uri; char *suffix = strchr(index + 1, '/'); if (suffix != NULL) { int size = suffix - index; context_dir = ap_pstrndup(r->pool, index, size); /* Get the context child directory name */ index = index + size + 1; suffix = strchr(index, '/'); if (suffix != NULL) { size = suffix - index; child_dir = ap_pstrndup(r->pool, index, size); } else { child_dir = index; } /* Deny access to WEB-INF and META-INF directories */ if (child_dir != NULL) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "AutoAlias child_dir: %s", child_dir); if (!strcasecmp(child_dir, "WEB-INF") || !strcasecmp(child_dir, "META-INF")) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "AutoAlias HTTP_NOT_FOUND for URI: %s", r->uri); return HTTP_NOT_FOUND; } } } else { context_dir = ap_pstrdup(r->pool, index); } context_path = ap_pstrcat(r->pool, conf->alias_dir, ap_os_escape_path(r->pool, context_dir, 1), NULL); if (context_path != NULL) { DIR *dir = ap_popendir(r->pool, context_path); if (dir != NULL) { char *escurl = ap_os_escape_path(r->pool, clean_uri, 1); char *ret = ap_pstrcat(r->pool, conf->alias_dir, escurl, NULL); ap_pclosedir(r->pool, dir); /* Add code to verify real path ap_os_canonical_name */ if (ret != NULL) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "AutoAlias OK for file: %s", ret); r->filename = ret; return OK; } } else { /* Deny access to war files in web app directory */ int size = strlen(context_dir); if (size > 4 && !strcasecmp(context_dir + (size - 4), ".war")) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "AutoAlias FORBIDDEN for URI: %s", r->uri); return FORBIDDEN; } } } } } else { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "no match for %s found", r->uri); if (conf->strip_session == JK_TRUE && conf->strip_session_name) { char *jsessionid; if (r->uri) { jsessionid = strstr(r->uri, conf->strip_session_name); if (jsessionid) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "removing session identifier [%s] for non servlet url [%s]", jsessionid, r->uri); *jsessionid = '\0'; } } if (r->filename) { jsessionid = strstr(r->filename, conf->strip_session_name); if (jsessionid) *jsessionid = '\0'; } } } } } return DECLINED; } /* In case ForwardDirectories option is set, we need to know if all files * mentioned in DirectoryIndex have been exhausted without success. If yes, we * need to let mod_dir know that we want Tomcat to handle the directory */ static int jk_fixups(request_rec * r) { /* This is a sub-request, probably from mod_dir */ if (r->main) { jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(r->server->module_config, &jk_module); char *worker = (char *)ap_table_get(r->notes, JK_NOTE_WORKER_NAME); if (ap_table_get(r->subprocess_env, "no-jk")) { if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "Into fixup no-jk env var detected for uri=%s, declined", r->uri); return DECLINED; } /* Only if we have no worker and ForwardDirectories is set */ if (!worker && (conf->options & JK_OPT_FWDDIRS)) { char *dummy_ptr[1], **names_ptr, *idx; int num_names; dir_config_rec *d = (dir_config_rec *) ap_get_module_config(r->per_dir_config, &dir_module); /* Direct lift from mod_dir */ if (d->index_names) { names_ptr = (char **)d->index_names->elts; num_names = d->index_names->nelts; } else { dummy_ptr[0] = DEFAULT_INDEX; names_ptr = dummy_ptr; num_names = 1; } /* Where the index file would start within the filename */ idx = r->filename + strlen(r->filename) - strlen(names_ptr[num_names - 1]); /* The requested filename has the last index file at the end */ if (idx >= r->filename && !strcmp(idx, names_ptr[num_names - 1])) { r->uri = r->main->uri; /* Trick mod_dir with URI */ r->finfo.st_mode = S_IFREG; /* Trick mod_dir with file stat */ /* We'll be checking for handler in r->prev later on */ r->main->handler = ap_pstrdup(r->pool, JK_HANDLER); if (JK_IS_DEBUG_LEVEL(conf->log)) jk_log(conf->log, JK_LOG_DEBUG, "ForwardDirectories on: %s", r->uri); } } } return DECLINED; } static void child_exit_handler(server_rec * s, ap_pool * p) { /* If the main log is piped, we need to make sure * it is no longer used. The external log process * (e.g. rotatelogs) will be gone now and the pipe will * block, once the buffer gets full. Setting * log_fd to -1 makes logging switch to error log. */ jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); jk_logger_t *l = conf->log; if (l && l->logger_private) { jk_file_logger_t *p = l->logger_private; if (p && p->is_piped == JK_TRUE) { p->log_fd = -1; p->is_piped = JK_FALSE; } } wc_shutdown(l); /* srevilak - refactor cleanup body to jk_generic_cleanup() */ jk_generic_cleanup(s); jk_shm_close(l); } static void child_init_handler(server_rec * s, ap_pool * p) { int rc; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); JK_TRACE_ENTER(conf->log); if ((rc = jk_shm_attach(jk_shm_file, jk_shm_size, conf->log)) != 0) { jk_log(conf->log, JK_LOG_ERROR, "Attaching shm:%s errno=%d", jk_shm_name(), rc); } JK_TRACE_EXIT(conf->log); } /** srevilak -- registered as a cleanup handler in jk_init */ static void jk_server_cleanup(void *data) { /* If the main log is piped, we need to make sure * it is no longer used. The external log process * (e.g. rotatelogs) will be gone now and the pipe will * block, once the buffer gets full. Setting * log_fd to -1 makes logging switch to error log. */ server_rec *s = (server_rec *) data; jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); jk_logger_t *l = conf->log; if (l && l->logger_private) { jk_file_logger_t *p = l->logger_private; if (p && p->is_piped == JK_TRUE) { p->log_fd = -1; p->is_piped = JK_FALSE; } } jk_generic_cleanup(s); jk_shm_close(l); } /** BEGIN SREVILAK * body taken from exit_handler() */ static void jk_generic_cleanup(server_rec *s) { if (jk_worker_properties) { jk_map_free(&jk_worker_properties); jk_worker_properties = NULL; jk_worker_file = NULL; jk_mount_copy_all = JK_FALSE; } /* loop through all available servers to clean up all configuration * records we've created */ while (NULL != s) { jk_server_conf_t *conf = (jk_server_conf_t *) ap_get_module_config(s->module_config, &jk_module); if (conf && conf->was_initialized == JK_TRUE) { /* On pool cleanup pass NULL for the jk_logger to prevent segmentation faults on Windows because we can't guarantee what order pools get cleaned up between APR implementations. */ wc_close(NULL); if (conf->uri_to_context) { jk_map_free(&conf->uri_to_context); /* We cannot have allocated uw_map * unless we've allocated uri_to_context */ if (conf->uw_map) uri_worker_map_free(&conf->uw_map, NULL); } conf->was_initialized = JK_FALSE; } s = s->next; } } /** END SREVILAK **/ static const handler_rec jk_handlers[] = { {JK_MAGIC_TYPE, jk_handler}, {JK_HANDLER, jk_handler}, {NULL} }; module MODULE_VAR_EXPORT jk_module = { STANDARD_MODULE_STUFF, jk_init, /* module initializer */ NULL, /* per-directory config creator */ NULL, /* dir config merger */ create_jk_config, /* server config creator */ merge_jk_config, /* server config merger */ jk_cmds, /* command table */ jk_handlers, /* [7] list of handlers */ jk_translate, /* [2] filename-to-URI translation */ NULL, /* [5] check/validate user_id */ NULL, /* [6] check user_id is valid *here* */ NULL, /* [4] check access by host address */ NULL, /* XXX [7] MIME type checker/setter */ jk_fixups, /* [8] fixups */ request_log_transaction, /* [10] logger */ NULL, /* [3] header parser */ child_init_handler, /* apache child process initializer */ child_exit_handler, /* apache child process exit/cleanup */ NULL /* [1] post read_request handling */ #ifdef EAPI /* * Extended module APIs, needed when using SSL. * STDC say that we do not have to have them as NULL but * why take a chance */ , NULL, /* add_module */ NULL, /* remove_module */ NULL, /* rewrite_command */ NULL, /* new_connection */ NULL /* close_connection */ #endif /* EAPI */ }; tomcat-connectors-1.2.41-src/native/apache-1.3/mod_jk.exp0000644000000000000020000000001307536137356021313 0ustar rootbinmod_jk.exp tomcat-connectors-1.2.41-src/native/apache-1.3/Makefile.in0000644000000000000020000000671712445347314021410 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. srcdir=@srcdir@ top_srcdir=@top_srcdir@ top_builddir=@top_builddir@ APXS=@APXS@ CP=@CP@ APACHE_DIR=@APACHE_DIR@ MKDIR=@MKDIR@ APXSCFLAGS=@APXSCFLAGS@ APXSCPPFLAGS=@APXSCPPFLAGS@ APXSLDFLAGS=@APXSLDFLAGS@ CC=@CC@ SHELL=@SHELL@ # Defaults libexecdir=${APACHE_DIR}/libexec JK=${top_builddir}/common/ # Defines APACHE_OBJECTS - the list of all common files include ${top_builddir}/common/list.mk # Apache settings, values guessed by Apache config and used to build it # Will define libexecdir, LIBTOOL, etc include @APACHE_CONFIG_VARS@ # Local settings ( overriding/appending to Apache's ) COMMON=common JK_INCL=-DUSE_APACHE_MD5 -I${top_builddir}/${COMMON} -I ${top_srcdir}/${COMMON} CFLAGS=@apache_include@ @CFLAGS@ ${JK_INCL} ${APXSCPPFLAGS} ${APXSCFLAGS} ${EXTRA_CFLAGS} ${EXTRA_CPPFLAGS} # Implicit rules include ${top_srcdir}/scripts/build/rules.mk OEXT=.lo all: Makefile @LIB_JK_TYPE@ install: @INSTALL_TYPE@ Makefile: ${srcdir}/Makefile.in echo Regenerating Makefile ( cd ..; ./config.status ) lib_jk.la: mod_jk.lo ${APACHE_OBJECTS} $(LIBTOOL) --mode=link $(CC) -o lib_jk.la -static -rpath ${libexecdir}/jk mod_jk.lo $(APACHE_OBJECTS) install_static: mod_jk.a @echo "" @echo "Copying files to Apache Modules Directory..." -${MKDIR} ${APACHE_DIR}/src/modules/jk ${LIBTOOL} --mode=install ${CP} $< ${APACHE_DIR}/src/modules/jk/mod_jk.a -${CP} Makefile.tmpl ${APACHE_DIR}/src/modules/jk -${CP} Makefile.libdir ${APACHE_DIR}/src/modules/jk -${CP} mod_jk.c ${APACHE_DIR}/src/modules/jk -${MKDIR} ${APACHE_DIR}/src/modules/jk/include -${CP} ../common/*.h ${APACHE_DIR}/src/modules/jk/include @echo "" @echo "Please be sure to re-compile Apache..." @echo "" @echo "cd ${APACHE_DIR}" @echo "./config.status --activate-module=src/modules/jk/libjk.a \\" @echo " --enable-module=dir \\" @echo " --disable-shared=dir" @echo "make" @echo "" #################### Dynamic .so file #################### # APXS will compile every file, this is derived from apxs mod_jk.a: mod_jk.lo $(APACHE_OBJECTS) $(LIBTOOL) --mode=link ${COMPILE} $(APXSLDFLAGS) -o $@ mod_jk.lo $(APACHE_OBJECTS) mod_jk.lo: ${srcdir}/mod_jk.c ${LT_COMPILE} mod_jk.la: mod_jk.lo $(APACHE_OBJECTS) $(LIBTOOL) --mode=link ${COMPILE} $(APXSLDFLAGS) -o $@ -module -rpath ${libexecdir} -avoid-version mod_jk.lo $(APACHE_OBJECTS) mod_jk.so: mod_jk.la ${top_srcdir}/scripts/build/instdso.sh SH_LIBTOOL='$(LIBTOOL)' mod_jk.la `pwd` install_dynamic: @echo "" @echo "Installing files to Apache Modules Directory..." $(APXS) -i mod_jk.la @echo "" @echo "Please be sure to arrange ${APACHE_DIR}/conf/httpd.conf..." @echo "" clean: rm -f *.o *.lo *.a *.la *.so *.so.* *.slo rm -rf .libs maintainer-clean: clean distclean: clean tomcat-connectors-1.2.41-src/native/apache-1.3/NWGNUmakefile.mak0000644000000000000020000001413011660656133022415 0ustar rootbin# # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # # NetWare Makefile for mod_jk (uses build system of Apache 1.3.x - gnu make) # created by Guenter Knauf # # # Make sure all needed macro's are defined # LDLIBS = -l"$(METROWERKS)/Novell Support/libraries/runtime/mwcrtl.lib" JKCOMMON = ../common # # Get the 'head' of the build environment if necessary. This includes default # targets and paths to tools # ifndef EnvironmentDefined include $(AP_WORK)\NWGNUhead.inc endif # # These directories will be at the beginning of the include list, followed by # INCDIRS # XINCDIRS += \ $(JKCOMMON) \ $(SRC)\include \ $(NWOS) \ $(EOLIST) # # These flags will come after CFLAGS # XCFLAGS += \ -DNO_GETTIMEOFDAY \ -DJK_PREFORK \ $(EOLIST) # # These defines will come after DEFINES # XDEFINES += \ $(EOLIST) # # These flags will be added to the link.opt file # XLFLAGS += \ $(LDLIBS) \ $(EOLIST) # # These values will be appended to the correct variables based on the value of # RELEASE # ifeq "$(RELEASE)" "debug" XINCDIRS += \ $(EOLIST) XCFLAGS += \ $(EOLIST) XDEFINES += \ $(EOLIST) XLFLAGS += \ $(EOLIST) endif ifeq "$(RELEASE)" "noopt" XINCDIRS += \ $(EOLIST) XCFLAGS += \ $(EOLIST) XDEFINES += \ $(EOLIST) XLFLAGS += \ $(EOLIST) endif ifeq "$(RELEASE)" "release" XINCDIRS += \ $(EOLIST) XCFLAGS += \ $(EOLIST) XDEFINES += \ $(EOLIST) XLFLAGS += \ $(EOLIST) endif # # These are used by the link target if an NLM is being generated # This is used by the link 'name' directive to name the nlm. If left blank # TARGET_nlm (see below) will be used. # NLM_NAME = mod_jk # # This is used by the link '-desc ' directive. # If left blank, NLM_NAME will be used. # NLM_DESCRIPTION = Apache $(AP_VERSION_STR) plugin for Tomcat $(JK_VERSION_STR) # # This is used by the link '-copy ' directive. # If left blank, the ASF copyright defined in NWGNUtail.inc will be used. # NLM_COPYRIGHT = Licensed under the Apache License Version 2.0 # # This is used by the '-threadname' directive. If left blank, # NLM_NAME Thread will be used. # NLM_THREAD_NAME = JK Module # # If this is specified, it will override VERSION value in # $(AP_WORK)\NWGNUenvironment.inc # NLM_VERSION = $(JK_VERSION) # # If this is specified, it will override the default of 64K # NLM_STACK_SIZE = 65536 # # If this is specified it will be used by the link '-entry' directive # NLM_ENTRY_SYM = _lib_start #NLM_ENTRY_SYM = _lib_start_ws # # If this is specified it will be used by the link '-exit' directive # NLM_EXIT_SYM = _lib_stop #NLM_EXIT_SYM = _lib_stop_ws # # If this is specified it will be used by the link '-flags' directive # NLM_FLAGS = # # Declare all target files (you must add your files here) # # # If there is an NLM target, put it here # TARGET_nlm = \ $(OBJDIR)/$(NLM_NAME).nlm \ $(EOLIST) # # If there is an LIB target, put it here # TARGET_lib = \ $(EOLIST) # # These are the OBJ files needed to create the NLM target above. # Paths must all use the '/' character # FILES_nlm_objs = \ $(OBJDIR)/$(NLM_NAME).o \ $(OBJDIR)/jk_nwmain.o \ $(OBJDIR)/jk_ajp12_worker.o \ $(OBJDIR)/jk_ajp13.o \ $(OBJDIR)/jk_ajp13_worker.o \ $(OBJDIR)/jk_ajp14.o \ $(OBJDIR)/jk_ajp14_worker.o \ $(OBJDIR)/jk_ajp_common.o \ $(OBJDIR)/jk_connect.o \ $(OBJDIR)/jk_context.o \ $(OBJDIR)/jk_lb_worker.o \ $(OBJDIR)/jk_map.o \ $(OBJDIR)/jk_md5.o \ $(OBJDIR)/jk_msg_buff.o \ $(OBJDIR)/jk_pool.o \ $(OBJDIR)/jk_shm.o \ $(OBJDIR)/jk_sockbuf.o \ $(OBJDIR)/jk_status.o \ $(OBJDIR)/jk_uri_worker_map.o \ $(OBJDIR)/jk_url.o \ $(OBJDIR)/jk_util.o \ $(OBJDIR)/jk_worker.o \ $(EOLIST) # # These are the LIB files needed to create the NLM target above. # These will be added as a library command in the link.opt file. # FILES_nlm_libs = \ $(NWOS)/$(OBJDIR)/libpre.o \ $(EOLIST) # $(NWOS)/$(OBJDIR)/libprews.o # # These are the modules that the above NLM target depends on to load. # These will be added as a module command in the link.opt file. # FILES_nlm_modules = \ $(EOLIST) # # If the nlm has a msg file, put it's path here # FILE_nlm_msg = # # If the nlm has a hlp file put it's path here # FILE_nlm_hlp = # # If this is specified, it will override $(NWOS)\copyright.txt. # FILE_nlm_copyright = # # Any additional imports go here # FILES_nlm_Ximports = \ @ApacheCore.imp \ @threads.imp \ @clib.imp \ @nlmlib.imp \ @socklib.imp \ $(EOLIST) # # Any symbols exported to here # FILES_nlm_exports = \ jk_module \ $(EOLIST) # # These are the OBJ files needed to create the LIB target above. # Paths must all use the '/' character # FILES_lib_objs = \ $(EOLIST) # # implement targets and dependancies (leave this section alone) # libs :: $(OBJDIR) $(TARGET_lib) nlms :: libs $(TARGET_nlm) # # Updated this target to create necessary directories and copy files to the # correct place. (See $(AP_WORK)\NWGNUhead.inc for examples) # install :: nlms FORCE copy $(OBJDIR)\$(NLM_NAME).nlm $(INSTALL)\Apache\modules # # Any specialized rules here # vpath %.c . $(JKCOMMON) $(SNPRINTF) $(OBJDIR)/version.inc: $(JKCOMMON)/jk_version.h $(SRC)/include/httpd.h $(OBJDIR) @echo Creating $@ @awk -f ../../support/get_ver.awk $< $(SRC)/include/httpd.h > $@ # Include the version info retrieved from jk_version.h -include $(OBJDIR)/version.inc # # Include the 'tail' makefile that has targets that depend on variables defined # in this makefile # include $(AP_WORK)/NWGNUtail.inc tomcat-connectors-1.2.41-src/native/apache-1.3/Makefile.apxs.in0000644000000000000020000000256712445323463022360 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ## configure should make the Makefile out of this file. srcdir=@srcdir@ top_srcdir=@top_srcdir@ top_builddir=@top_builddir@ APXS=@APXS@ APXSLDFLAGS=@APXSLDFLAGS@ APXSCFLAGS=@APXSCFLAGS@ COMMON=common JK_INCL=-DUSE_APACHE_MD5 -I${top_builddir}/${COMMON} -I ${top_srcdir}/${COMMON} ## read the object (.c) from the list file. OEXT=.c include @top_builddir@/common/list.mk all: mod_jk.so mod_jk.so: $(APXS) -c -o $@ -Wc,"${APXSCFLAGS} ${JK_INCL}" ${APXSLDFLAGS} ${srcdir}/mod_jk.c ${APACHE_OBJECTS} clean: rm -f *.o *.lo *.a *.la *.so *.so.* *.slo rm -rf .libs maintainer-clean: clean distclean: clean tomcat-connectors-1.2.41-src/native/apache-1.3/libjk.module0000644000000000000020000000017007307132056021624 0ustar rootbinName: jk_module ConfigStart LIBS="-Lmodules/jk -L../modules/jk -L../../modules/jk -ljk $LIBS" RULE_HIDE=yes ConfigEnd tomcat-connectors-1.2.41-src/native/apache-1.3/Makefile.vc0000644000000000000020000001254511660226567021412 0ustar rootbin!IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF !IFDEF EAPI OUTDIR=.\ReleaseSSL INTDIR=.\ReleaseSSL DEF_EAPI=/D "EAPI" !ELSE OUTDIR=.\Release INTDIR=.\Release DEF_EAPI= !ENDIF CPP=cl.exe MTL=midl.exe RSC=rc.exe ALL : "$(OUTDIR)\mod_jk.so" CLEAN : -@erase "$(INTDIR)\jk_ajp12_worker.obj" -@erase "$(INTDIR)\jk_ajp13.obj" -@erase "$(INTDIR)\jk_ajp13_worker.obj" -@erase "$(INTDIR)\jk_ajp14.obj" -@erase "$(INTDIR)\jk_ajp14_worker.obj" -@erase "$(INTDIR)\jk_ajp_common.obj" -@erase "$(INTDIR)\jk_connect.obj" -@erase "$(INTDIR)\jk_context.obj" -@erase "$(INTDIR)\jk_lb_worker.obj" -@erase "$(INTDIR)\jk_map.obj" -@erase "$(INTDIR)\jk_md5.obj" -@erase "$(INTDIR)\jk_msg_buff.obj" -@erase "$(INTDIR)\jk_pool.obj" -@erase "$(INTDIR)\jk_shm.obj" -@erase "$(INTDIR)\jk_sockbuf.obj" -@erase "$(INTDIR)\jk_status.obj" -@erase "$(INTDIR)\jk_uri_worker_map.obj" -@erase "$(INTDIR)\jk_url.obj" -@erase "$(INTDIR)\jk_util.obj" -@erase "$(INTDIR)\jk_worker.obj" -@erase "$(INTDIR)\mod_jk.obj" -@erase "$(INTDIR)\mod_jk_src.idb" -@erase "$(INTDIR)\mod_jk_src.pdb" -@erase "$(OUTDIR)\mod_jk.exp" -@erase "$(OUTDIR)\mod_jk.lib" -@erase "$(OUTDIR)\mod_jk.pdb" -@erase "$(OUTDIR)\mod_jk.so" "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_jk.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=ApacheCore.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib $(EXTRA_LIBS) /nologo /base:"0x6A6B0000" /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_jk.pdb" /debug /machine:I386 /out:"$(OUTDIR)\mod_jk.so" /implib:"$(OUTDIR)\mod_jk.lib" /libpath:"$(APACHE1_HOME)\lib" /libpath:"$(APACHE1_HOME)\libexec" /opt:ref LINK32_OBJS= \ "$(INTDIR)\jk_ajp12_worker.obj" \ "$(INTDIR)\jk_ajp13.obj" \ "$(INTDIR)\jk_ajp13_worker.obj" \ "$(INTDIR)\jk_ajp14.obj" \ "$(INTDIR)\jk_ajp14_worker.obj" \ "$(INTDIR)\jk_ajp_common.obj" \ "$(INTDIR)\jk_connect.obj" \ "$(INTDIR)\jk_context.obj" \ "$(INTDIR)\jk_lb_worker.obj" \ "$(INTDIR)\jk_map.obj" \ "$(INTDIR)\jk_md5.obj" \ "$(INTDIR)\jk_msg_buff.obj" \ "$(INTDIR)\jk_pool.obj" \ "$(INTDIR)\jk_shm.obj" \ "$(INTDIR)\jk_sockbuf.obj" \ "$(INTDIR)\jk_status.obj" \ "$(INTDIR)\jk_uri_worker_map.obj" \ "$(INTDIR)\jk_url.obj" \ "$(INTDIR)\jk_util.obj" \ "$(INTDIR)\jk_worker.obj" \ "$(INTDIR)\mod_jk.obj" "$(OUTDIR)\mod_jk.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << CPP_PROJ=-nologo -MD -W3 -O2 -Ob2 -Oy- -Zi -EHsc /I "..\common" /I "$(APACHE1_HOME)\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" $(DEF_EAPI) /D "MOD_JK_EXPORTS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_jk_src" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 SOURCE=..\common\jk_ajp12_worker.c "$(INTDIR)\jk_ajp12_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp13.c "$(INTDIR)\jk_ajp13.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp13_worker.c "$(INTDIR)\jk_ajp13_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp14.c "$(INTDIR)\jk_ajp14.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp14_worker.c "$(INTDIR)\jk_ajp14_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp_common.c "$(INTDIR)\jk_ajp_common.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_connect.c "$(INTDIR)\jk_connect.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_context.c "$(INTDIR)\jk_context.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_lb_worker.c "$(INTDIR)\jk_lb_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_map.c "$(INTDIR)\jk_map.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_md5.c "$(INTDIR)\jk_md5.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_msg_buff.c "$(INTDIR)\jk_msg_buff.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_pool.c "$(INTDIR)\jk_pool.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_shm.c "$(INTDIR)\jk_shm.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_sockbuf.c "$(INTDIR)\jk_sockbuf.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_status.c "$(INTDIR)\jk_status.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_uri_worker_map.c "$(INTDIR)\jk_uri_worker_map.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_url.c "$(INTDIR)\jk_url.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_util.c "$(INTDIR)\jk_util.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_worker.c "$(INTDIR)\jk_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=.\mod_jk.c "$(INTDIR)\mod_jk.obj" : $(SOURCE) "$(INTDIR)" tomcat-connectors-1.2.41-src/native/apache-1.3/Makefile.tmpl0000644000000000000020000000311110666607673021751 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ## ## Apache 1.3 Makefile template for mod_jk ## LIB=libjk.$(LIBEXT) JK_INCLUDES=$(INCLUDES) -I./include OBJS=mod_jk.o OBJS_LIB=mod_jk.a SHLIB_OBJS=mod_jk.so-o SHLIB_OBJS_LIB=mod_jk.a all: ${LIB} # build the static library by merging the object files libjk.a: $(OBJS) $(OBJS_LIB) cp $(OBJS_LIB) $@ ar r $@ $(OBJS) ${RANLIB} $@ # build the shared object library by linking the object files libjk.so: $(SHLIB_OBJS) $(SHLIB_OBJS_LIB) rm -f $@ $(LD_SHLIB) $(LDFLAGS_SHLIB) -o $@ $(SHLIB_OBJS) $(SHLIB_OBJS_LIB) $(LIBS) .SUFFIXES: .o .so-o .c.o: $(CC) -c $(JK_INCLUDES) $(CFLAGS) $(CPPFLAGS) $(SPACER) $< .c.so-o: $(CC) -c $(JK_INCLUDES) $(CFLAGS) $(CFLAGS_SHLIB) $(CPPFLAGS) $(SPACER) $< && mv $*.o $*.so-o clean: -rm -f $(OBJS) $(SHLIB_OBJS) $(LIB) distclean: clean -rm -f Makefile depend: echo "No depend" tomcat-connectors-1.2.41-src/native/BUILDING.txt0000644000000000000020000001172012303357053017541 0ustar rootbin Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. General Build Instructions ========================== To build tomcat-connectors you need to run "configure" and "make": ./configure [autoconf arguments] [tomcat-connectors arguments] make It is possible to set CFLAGS and LDFLAGS to add some platform specifics: LDFLAGS=-lc \ ./configure -with-apxs=/home2/local/apache/bin/apxs To find out about all available configure flags use ./configure --help Build for the Apache HTTP Server ================================ If you want to build mod_jk for the Apache HTTP Server you need to locate the apxs tool coming with the Apache HTTP server. If apxs is located in /usr/sbin/apxs, run: ./configure --with-apxs=/usr/sbin/apxs make The resulting module file mod_jk.so of mod_jk will be located in the directory apache-2.0 (for any version of Apache 2.x) respectively apache-1.3 (for Apache 1.3). Simply copy the file to your web server modules or libexec directory. Apache related configure arguments for tomcat-connectors -------------------------------------------------------- --with-apxs[=FILE] FILE is the location of the apxs tool. Default is finding apxs in PATH. It builds a shared Apache module. It detects automatically the Apache version. (2.x and 1.3) --with-apache=DIR DIR is the path where apache sources are located. The apache sources should have been configured before configuring mod_jk. DIR is something like: /home/apache/apache_1.3.19 It builds a static Apache module. --enable-EAPI This parameter is needed when using Apache 1.3 and mod_ssl, otherwise you will get the error message: "this module might crash under EAPI!" when loading libjk.so in httpd. Static build needs more tests, and we strongly recommend dynamic build using DSO/APXS. Building for Netscape/iPlanet/SunONE WebServer ============================================== Building uses the following command sequence: ./configure --enable-netscape cd netscape make -f Makefile.solaris This assumes that IPLANET_HOME is defined and points to your iPlanet install path (eg: /opt/SUNWwbsvr). By default GCC will be used. You can use Sun CC by providing CC=cc on the make command line: make -f Makefile.solaris CC=cc IPLANET_HOME=/opt/SUNWwbsrv70 EXTRA_CFLAGS=-m64 Misc Notes ========== Build for Multiple Web Servers ------------------------------ If you want to build for multiple web servers, you need to call "make clean" between the individual builds. HP-UX build notes ----------------- If you plan to use GCC on HP-UX to build mod_jk, be sure to have -DHPUX11GCC defined (usually by setting CLAGS before configure) Reports are that the stripped down cc version that ships with HP-UX won't be able to work, you should have the HP add-on ANSI C Compiler package. A good repository for HP-UX gnu tools is: http://gatekeep.cs.utah.edu/ Solaris build notes ------------------- The build should work with the GNU gcc compiler, on both SPARC and x86 architecture systems. A good repository for Solaris gnu tools is: http://www.sunfreeware.com/ Be carefull when mixing native compiler and gnu compiler, and ensure that apache and mod_jk will be compiled and linked with the same tools (i.e. full Solaris or full GNU) Building from the subversion tree ================================= This is only necessary if you want to build a not yet released versions. When using a subversion tree, "buildconf.sh" must be run before configure. This script uses the auto tools to provide the following files: - libtool files in scripts/build/unix (should copy them?) - Makefile.in from Makefile.am - aclocal.m4 from different m4 files located on the local machine - configure from configure.ac and aclocal.m4 buildconf.sh is known to work with libtool 1.5.2, automake 1.10 and autoconf 2.59 or newer. The use of more recent versions is strongly encouraged, e.g. for reliable detection of the features of recent version of operating systems (e.g. AIX 6.1). The script is run without arguments: ./buildconf.sh If you see error messages from automake, don't care about them. After running buildconf you can build as usual using configure and make. tomcat-connectors-1.2.41-src/native/TODO.txt0000644000000000000020000003175511660660436017132 0ustar rootbin Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. TODO for tomcat-connectors $Id: TODO.txt 1202556 2011-11-16 07:07:10Z mturk $ 1) Optimize "distance" ====================== Sorting the list of balanced workers by distance would be nice, but: How to combine the sorting with the offset implementation (especially useful for strategy BUSYNESS under low load). Local error states and likely other features will also break in case we do naive reordering. 2) Reduce number of string comparisons in most_suitable ======================================================== a) redirect/domains It would be easy to improve the redirect string b an integer, giving the index of the worker in the lb. Then lb would not need to search for the redirect worker. The same way, one could add a list with indizes to workers in the same domain. Whenever domain names are managed (init and status worker update) one would scan the worker list and update the index list. Finally one could have a list of workers, whose domain is the same as the redirect attribute of the worker, because that's also something we consider. What I'm not sure about, even in the existing code, is the locking between updates by the status worker and the process local information about the workers, especially in the case, when status updates a redirect or domain attribute. I would like to keep these attributes and the new index arrays process local, and the processes should find out about changes made by status to shm (redirect/domain) and then rebuild their data. No need to get these on every request from the shm, only the check for up-to-date should be made. b) exact matches for jvmRoutes Could we use hashes instead of string comparisons all the time? I'm not sure, if a good enough hash takes longer than a string comparison though. 3) Code separation between factory, validate and init in lb ============================================================ The factory contains: private_data->worker.retries = JK_RETRIES; private_data->s->recover_wait_time = WAIT_BEFORE_RECOVER; I think, this should move to validate() or init(). It might even be obsolete, because in init, we already have: pThis->retries = jk_get_worker_retries(props, p->s->name, p->s->retries = pThis->retries; p->s->recover_wait_time = jk_get_worker_recover_timeout(props, p->s->name, WAIT_BEFORE_RECOVER); if (p->s->recover_wait_time < WAIT_BEFORE_RECOVER) p->s->recover_wait_time = WAIT_BEFORE_RECOVER; Then: In validate there is p->lb_workers[i].s->error_time = 0; So shouldn't there also be p->lb_workers[i].s->maintain_time = time(NULL); 4) Logging ========== a) Allow logging of request url or uuid in jk log to ease matching with access log. b) Implement log rotation for IIS. (done in 1.2.31) c) Allow adding of log notes for IIS like we do with Apache. d) Add error type info to access log notes e) Refactor: Use the same code files for the request logging functions in Apache 1.3 and 2.0. f) Refactor: Use the same code files for piped logging in Apache 1.3 and 2.0. 5) ajpget ========== Combine ajplib and Apache ab to an ajp13 commandline client ajpget. 6) Parsing workers.properties ============================= Parsing of workers.properties aditionally to just looking up attributes would help users to detect syntax errors in the file. At the moment no information will be logged, e.g. when attributes contain typos. Example: worker.list vs. worker.lists. 7) Persisting workers.properties ================================ Make workers.properties persist from inside status worker. Add additional properties file, that contains a journal of property changes done via the status worker. When initializing those overwrite the initial workers.properties. Update actions in the status worker will allow to optionally add a change to this journal. We can also add a comment with timestamp etc. to each journal line. 8) Reduce number of uses of time(NULL) ====================================== We use time(NULL) a lot. Since it only has resolution of a second, I'm asking myself, if we could update the actual time in only a few places and get time out of some variables when needed. The same does not hold true for millisecond time, but in several cases we use the time, it's not very critical, that it is exact. These cases are related to: Some of this is already been done, the remaining parts are: - last_access for usage against timeout value that is ~minutes - error_time for usage against retry timeout that is ~minutes - uri_worker_map checked for usage against JK_URIMAP_RELOAD=1 minute So I think, it would suffice to set an actual time at the beginning of the request/response cycle (used by everything before the request is being sent over the socket) and maybe after the response shows up/ an error occurs (for everything else, if there is). For which cases would it be OK, to use the time before sending to TC: - uri_worker_map "checked" (uri map lookup starts early) - setting/testing last_access in - jk_ajp_common.c:ajp_connect_to_endpoint() - jk_ajp_common.c:ajp_get_endpoint() - jk_ajp_common.c:ajp_maintain() What about the others: - setting last_access in init should use the actual time in jk_ajp_common.c:ajp_create_endpoint_cache() - setting last_access again after the service could also use the actual time in jk_ajp_common.c:ajp_done() - setting error_time should better use the actual time jk_lb_worker.c service(): rec->s->error_time = time(NULL); The last two cases could again use the same time, which then would be needed to be generated at the end or directly after service. 9) Access/Modification Time in shm ================================== a) [Discussion] What will this generally be used for? At the moment, only jk_status "uses" it, but it only sets the values, it never asks for them. b) [Improvement, minor] jk_shm_set_workers_time() implicitly calls jk_shm_sync_access_time(), but jk_status does: jk_shm_set_workers_time(time(NULL)); /* Since we updated the config no need to reload * on the next request */ jk_shm_sync_access_time(); two times. So depending on the idea of the functionality of these calls, either set_workers_time and sync_access_time should be independently, or the second call in jk_status coulkd be removed. 10) "Destroy" functionality =========================== [Hint] Destroy on a worker never seems to free shm, but I think that was already a flaw without shm. 11) Locks against shm ===================== It might be an interesting experiment to implement an improved locking structure. It looks like one would need in fact different types of locks. In shm we have as read/write information: Changed only by status worker: - redirect, domain, lb_factor, sticky_session, sticky_session_force, recover_wait_time, retries, status (is_disabled, is_stopped). These changes need some kind of reconfiguration in the threads after change and before the next request/response. Since changes are rare, here we would be better of, with a simple detect change and copy from shm to process procedure. status updates the data in shm and after that the time stamp on the shh. Each process checks the time stamp before doing a request, and when the time stamp changed it does a writer CS lock and updates it's local copy. All threads always do a reader CS lock when doing a request/response cycle. Reader CS locks are concurrent, writers are exclusive. So readers are not allowed, when the config data is being updated. Changed by the threads themselves (and via reset by the status worker): - counters needed by routing decisions (lb_value, readed, transferred, busy) - timers needed by maintenance functions (error_time, servic_time/maintain_time) - status is_busy, in_error_state - uncritical data with no influence on routing decisions (max_busy, elected, errors, in_recovering) Here again we could improve by using reader/writer locks. I have a tendency for the PESSIMISTIC side of locking, but I think we could shrink the code blocks that should be locked. At the monent they are pretty big (most of get_most_suitable_worker). Read-only: name and id. By the way: at several places we don't check for errors on getting the lock. 12) Global locks ================ We might want to make the lock technology choosable, like httpd does. E.g. on Solaris the default lock type if fcntl, and we can easily get an invalid EDEADLOCK for our jk_log_lock. The following pthread based non global locks are used: - one mutex for each AJP worker, synchronizing access to the connection pool, which exists per process - one mutex for each lb worker - a mutex used during dynamic update of uriworkermap.properties to prevent concurrent updates. Updates are done per process. - a mutex to prevent concurrent execution of the process local internal maintenance task - a mutex for access to the shared memory when changing or reading configuration parameters. That might be a little unsafe, because it actually should be a global mutex, not a process local, but those config changes are only done due to interaction with the status worker, so there's very little chance for unwanted concurrency here. All dynamic runtime data are already marked as being volatile. All except the last seem to be safe. The last might need some hybrid model using thread local mostly and process global when doing updates. See also: http://marc.info/?t=123394059800003&r=1&w=2 13) Understand the exact behaviour of shm and restarts ====================================================== Furthermore: rotatelogs (?) and gzip (mod_mime_magic) seem to close the (non-existing) shm file. Maybe a problem on some platforms? 14) What I didn't yet check =========================== a) Correctness of is_busy handling b) Correctness of the reset values after reset by status worker c) What would be the exact behaviour, if shm does not work (memory case). Will this be a critical failure, or will we only experience a degradation in routing decisions. d) How complete is mod_proxy_ajp/mod_proxy_balancer. Port changes from mod_jk to them. 15) Status worker ================= Allow managing pool and connection parameters. Add flags to pool and connections to signal workers and maintenance whether existing connections should be closed and renewed. Check completeness of attribute manageability for AJP workers. Check completeness of runtime data display, e.g. reset_time, recover_time, etc. Maybe also add "last error type". Work on a global display of process local data, e.g. state of the process local connection pools (sizes, num connected/idle). Rework the GUI: - Basic overview start page with links to the workers, maybe a checkbox to decide whether you want to see config data too. - Detail view (what type of error was last and when etc.), detail view for connection pools. 16) URI mapping =============== Add more extensions? 17) Connection Pool =================== How would a good global maximum count look like? Simply limit busyness? Soft limit (applies only to non-sticky requests) and a hard limit (applies to all requests)? 18) IP V6 ========= There's a Bugzilla with a patch. 19) IIS Chunked Encoding ======================== Move from alternative build to default. What about the other ifdef'd features? 20) Add REMORE_PORT as a default JkEnvVar ========================================= ... and port to IIS to fix the getRemotePort() problem. 21) Rework HowTo docs ===================== 22) Add better example config ============================= 23) Remove JNI worker ===================== Done 24) Watchdog reload of uriworkermap.properties ============================================== Questions about uriworkermap.properties watchdog reload (r745898): - shm lock needed? - Apache port (need to iterate over vhosts) 25) Watchdog backend probing ============================ Configurable probe URL to test backend, e.g. to decide about recovery instead of using random real requests. 26) Commandline shm =================== Commandline tool to read data from shm file. 27) Status worker property format ================================= Check whether we return list properties as one line (because Java doesn't allow the same property key multiple times). Applies possibly to: "list", BALANCE_WORKERS, MOUNT_OF_WORKER, USER_OF_WORKER, GOOD_RATING_OF_WORKER, BAD_RATING_OF_WORKER, STATUS_FAIL_OF_WORKER, tomcat-connectors-1.2.41-src/native/configure0000755000000000000020000162327412555256563017545 0ustar rootbin#! /bin/sh # From configure.ac Id: configure.ac 1647040 2014-12-20 19:32:28Z rjung . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.69 for mod_jk 1.2.41. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 as_fn_exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. $as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='mod_jk' PACKAGE_TARNAME='mod_jk' PACKAGE_VERSION='1.2.41' PACKAGE_STRING='mod_jk 1.2.41' PACKAGE_BUGREPORT='' PACKAGE_URL='' ac_unique_file="common/jk_worker.h" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS INSTALL_TYPE LIB_JK_TYPE APACHE20_OEXT MAKE_DYNAMIC_APACHE_FALSE MAKE_DYNAMIC_APACHE_TRUE WEBSERVER APXSLDFLAGS APXSCPPFLAGS APXSCFLAGS APACHE_DIR apache_include pthread_t_value pthread_t_fmt pid_t_fmt uint64_t_hex_fmt uint64_t_fmt int64_t_fmt int64_value uint32_t_hex_fmt uint32_t_fmt int32_t_fmt int32_value CPP OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR DLLTOOL OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LIBTOOL LD FGREP EGREP am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CC APACHE_CONFIG_VARS APXS PERL CFLAGS MKDIR CP SED ECHO GREP TEST AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_os target_vendor target_cpu target host_os host_vendor host_cpu host build_os build_vendor build_cpu build target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules with_apxs enable_dependency_tracking with_gnu_ld enable_shared enable_static with_pic enable_fast_install with_sysroot enable_libtool_lock enable_sock_cloexec with_apache enable_netscape enable_EAPI enable_maintainer_mode enable_prefork enable_trace enable_api_compatibility enable_flock ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures mod_jk 1.2.41 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/mod_jk] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] --target=TARGET configure for building compilers for TARGET [HOST] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of mod_jk 1.2.41:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --disable-sock-cloexec Disable use of SOCK_CLOEXEC. This ensures the built module can be used on systems that do not support SOCK_CLOEXEC --enable-netscape=DIR Build Netscape/iPlanet/SunONE nsapi redirector plugin --enable-EAPI Enable EAPI support (mod_ssl, Apache 1.3) --enable-maintainer-mode Turn on debugging and compile time warnings --enable-prefork Turn on prefork web server mode (single-threaded) --disable-trace Exclude trace log code from compilation --enable-api-compatibility Only use httpd API functions available in all production releases. This improves binary compatibility of module builds with httpd releases older than the release against we build (only between minor versions). --enable-flock Turn on flock for shared locking if present Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-apxs[=FILE] Build shared Apache module. FILE is the optional pathname to the apxs tool; defaults to finding apxs in your PATH. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-sysroot=DIR Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-apache=DIR Build static Apache module. DIR is the pathname to the Apache source directory. Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF mod_jk configure 1.2.41 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_c_compute_int LINENO EXPR VAR INCLUDES # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_c_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid; break else as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_lo=$ac_mid; break else as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done else ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main () { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_hi=$ac_mid else as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval () { return $2; } static unsigned long int ulongval () { return $2; } #include #include int main () { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : echo >>conftest.val; read $3 &5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval \${$3+:} false; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_mongrel cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by mod_jk $as_me 1.2.41, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers common/config.h" ac_aux_dir= for ac_dir in scripts/build/unix "$srcdir"/scripts/build/unix; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in scripts/build/unix \"$srcdir\"/scripts/build/unix" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if ${ac_cv_build+:} false; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if ${ac_cv_host+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5 $as_echo_n "checking target system type... " >&6; } if ${ac_cv_target+:} false; then : $as_echo_n "(cached) " >&6 else if test "x$target_alias" = x; then ac_cv_target=$ac_cv_host else ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5 $as_echo "$ac_cv_target" >&6; } case $ac_cv_target in *-*-*) ;; *) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;; esac target=$ac_cv_target ac_save_IFS=$IFS; IFS='-' set x $ac_cv_target shift target_cpu=$1 target_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: target_os=$* IFS=$ac_save_IFS case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac # The aliases save the names the user supplied, while $host etc. # will get canonicalized. test -n "$target_alias" && test "$program_prefix$program_suffix$program_transform_name" = \ NONENONEs,x,x, && program_prefix=${target_alias}- am__api_version='1.14' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if ${ac_cv_path_install+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if ${ac_cv_path_mkdir+:} false; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AWK+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test "${enable_silent_rules+set}" = set; then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 $as_echo_n "checking whether $am_make supports nested variables... " >&6; } if ${am_cv_make_support_nested_variables+:} false; then : $as_echo_n "(cached) " >&6 else if $as_echo 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 $as_echo "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='mod_jk' VERSION='1.2.41' cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi rm -f config.nice cat >config.nice<> config.nice fi if test -n "$CFLAGS"; then echo "CFLAGS=\"$CFLAGS\"; export CFLAGS" >> config.nice fi if test -n "$CPPFLAGS"; then echo "CPPFLAGS=\"$CPPFLAGS\"; export CPPFLAGS" >> config.nice fi if test -n "$LDFLAGS"; then echo "LDFLAGS=\"$LDFLAGS\"; export LDFLAGS" >> config.nice fi if test -n "$LTFLAGS"; then echo "LTFLAGS=\"$LTFLAGS\"; export LTFLAGS" >> config.nice fi if test -n "$LIBS"; then echo "LIBS=\"$LIBS\"; export LIBS" >> config.nice fi if test -n "$INCLUDES"; then echo "INCLUDES=\"$INCLUDES\"; export INCLUDES" >> config.nice fi if test -n "$NOTEST_CFLAGS"; then echo "NOTEST_CFLAGS=\"$NOTEST_CFLAGS\"; export NOTEST_CFLAGS" >> config.nice fi if test -n "$NOTEST_CPPFLAGS"; then echo "NOTEST_CPPFLAGS=\"$NOTEST_CPPFLAGS\"; export NOTEST_CPPFLAGS" >> config.nice fi if test -n "$NOTEST_LDFLAGS"; then echo "NOTEST_LDFLAGS=\"$NOTEST_LDFLAGS\"; export NOTEST_LDFLAGS" >> config.nice fi if test -n "$NOTEST_LIBS"; then echo "NOTEST_LIBS=\"$NOTEST_LIBS\"; export NOTEST_LIBS" >> config.nice fi # Retrieve command-line arguments. eval "set x $0 $ac_configure_args" shift for arg do jk_last= jk_cur="$arg" while test "x${jk_cur}" != "x${jk_last}"; do jk_last="${jk_cur}" jk_cur=`eval "echo ${jk_cur}"` done arg="${jk_cur}" echo "\"$arg\" \\" >> config.nice done echo '"$@"' >> config.nice chmod +x config.nice # Extract the first word of "test", so it can be a program name with args. set dummy test; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_TEST+:} false; then : $as_echo_n "(cached) " >&6 else case $TEST in [\\/]* | ?:[\\/]*) ac_cv_path_TEST="$TEST" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_TEST="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_TEST" && ac_cv_path_TEST="$PATH" ;; esac fi TEST=$ac_cv_path_TEST if test -n "$TEST"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TEST" >&5 $as_echo "$TEST" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "grep", so it can be a program name with args. set dummy grep; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else case $GREP in [\\/]* | ?:[\\/]*) ac_cv_path_GREP="$GREP" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_GREP="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_GREP" && ac_cv_path_GREP="$PATH" ;; esac fi GREP=$ac_cv_path_GREP if test -n "$GREP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GREP" >&5 $as_echo "$GREP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "echo", so it can be a program name with args. set dummy echo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_ECHO+:} false; then : $as_echo_n "(cached) " >&6 else case $ECHO in [\\/]* | ?:[\\/]*) ac_cv_path_ECHO="$ECHO" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_ECHO="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_ECHO" && ac_cv_path_ECHO="echo" ;; esac fi ECHO=$ac_cv_path_ECHO if test -n "$ECHO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ECHO" >&5 $as_echo "$ECHO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "sed", so it can be a program name with args. set dummy sed; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else case $SED in [\\/]* | ?:[\\/]*) ac_cv_path_SED="$SED" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_SED" && ac_cv_path_SED="$PATH" ;; esac fi SED=$ac_cv_path_SED if test -n "$SED"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SED" >&5 $as_echo "$SED" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "cp", so it can be a program name with args. set dummy cp; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_CP+:} false; then : $as_echo_n "(cached) " >&6 else case $CP in [\\/]* | ?:[\\/]*) ac_cv_path_CP="$CP" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_CP="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_CP" && ac_cv_path_CP="$PATH" ;; esac fi CP=$ac_cv_path_CP if test -n "$CP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CP" >&5 $as_echo "$CP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi # Extract the first word of "mkdir", so it can be a program name with args. set dummy mkdir; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_MKDIR+:} false; then : $as_echo_n "(cached) " >&6 else case $MKDIR in [\\/]* | ?:[\\/]*) ac_cv_path_MKDIR="$MKDIR" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_MKDIR="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_MKDIR" && ac_cv_path_MKDIR="$PATH" ;; esac fi MKDIR=$ac_cv_path_MKDIR if test -n "$MKDIR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR" >&5 $as_echo "$MKDIR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi CFLAGS="${CFLAGS} -DHAVE_CONFIG_H" configure_dir=`dirname $0` configure_dir=`cd $configure_dir; pwd` APACHE_CONFIG_VARS=$configure_dir/scripts/build/config_vars.mk WEBSERVER="" apache_dir="" apache_include="" APXS="apxs" # Check whether --with-apxs was given. if test "${with_apxs+set}" = set; then : withval=$with_apxs; case "${withval}" in y | yes | true) find_apxs=true ;; n | no | false) find_apxs= ;; *) find_apxs=${withval} ;; esac if ${TEST} ${find_apxs} ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: need to check for Perl first, apxs depends on it..." >&5 $as_echo "need to check for Perl first, apxs depends on it..." >&6; } # Extract the first word of "perl", so it can be a program name with args. set dummy perl; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_PERL+:} false; then : $as_echo_n "(cached) " >&6 else case $PERL in [\\/]* | ?:[\\/]*) ac_cv_path_PERL="$PERL" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PERL" && ac_cv_path_PERL="$PATH" ;; esac fi PERL=$ac_cv_path_PERL if test -n "$PERL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5 $as_echo "$PERL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if ${TEST} ${find_apxs} = true ; then # Extract the first word of "apxs", so it can be a program name with args. set dummy apxs; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_path_APXS+:} false; then : $as_echo_n "(cached) " >&6 else case $APXS in [\\/]* | ?:[\\/]*) ac_cv_path_APXS="$APXS" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_path_APXS="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_APXS" && ac_cv_path_APXS="$PATH" ;; esac fi APXS=$ac_cv_path_APXS if test -n "$APXS"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $APXS" >&5 $as_echo "$APXS" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else APXS=${find_apxs} fi if ${TEST} -n "${APXS}" ; then if ${TEST} ! -x "${APXS}" ; then as_fn_error $? "Invalid location for apxs: '${APXS}'" "$LINENO" 5 fi ${APXS} -q PREFIX >/dev/null 2>/dev/null || apxs_support=false if ${TEST} "${apxs_support}" = "false" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find ${APXS}" >&5 $as_echo "could not find ${APXS}" >&6; } as_fn_error $? "You must specify a valid --with-apxs path" "$LINENO" 5 fi apache_dir=`$APXS -q PREFIX` apache_include="-I`$APXS -q INCLUDEDIR`" APA=`${GREP} STANDARD20 ${APXS}` if ${TEST} -z "$APA" ; then WEBSERVER="apache-1.3" APXSCC="`$APXS -q CC`" APXSCFLAGS="`$APXS -q CFLAGS` -DJK_PREFORK" APXSCPPFLAGS="" APXSLDFLAGS="`$APXS -q LDFLAGS_SHLIB`" else WEBSERVER="apache-2.0" APRINCLUDEDIR="" INCTEMP="`$APXS -q APR_INCLUDEDIR` `$APXS -q APU_INCLUDEDIR`" for INC in ${INCTEMP}; do APRINCLUDEDIR="${APRINCLUDEDIR} -I${INC}" done { $as_echo "$as_me:${as_lineno-$LINENO}: result: APRINCLUDEDIR is $APRINCLUDEDIR" >&5 $as_echo "APRINCLUDEDIR is $APRINCLUDEDIR" >&6; } APXSCC="`$APXS -q CC`" APXSCFLAGS="`${APXS} -q CFLAGS` `${APXS} -q EXTRA_CFLAGS` -DHAVE_APR ${APRINCLUDEDIR}" APXSCPPFLAGS="`${APXS} -q EXTRA_CPPFLAGS`" APXSLDFLAGS="`$APXS -q LDFLAGS`" APACHE_CONFIG_VARS="`${APXS} -q exp_installbuilddir`/config_vars.mk" LIBTOOL=`$APXS -q LIBTOOL` fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: building connector for \"$WEBSERVER\"" >&5 $as_echo "building connector for \"$WEBSERVER\"" >&6; } if ${TEST} -z "${CC}" ; then CC="${APXSCC}" else if ${TEST} "${CC}" != "$APXSCC" ; then WARN_CC=1 fi fi fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no apxs given" >&5 $as_echo "no apxs given" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 $as_echo_n "checking whether the C compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 $as_echo_n "checking for C compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if ${ac_cv_objext+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if ${ac_cv_c_compiler_gnu+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if ${ac_cv_prog_cc_g+:} false; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if ${ac_cv_prog_cc_c89+:} false; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 $as_echo_n "checking whether $CC understands -c and -o together... " >&6; } if ${am_cv_prog_cc_c_o+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 $as_echo "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if ${am_cv_CC_dependencies_compiler_type+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if ${ac_cv_path_SED+:} false; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if ${ac_cv_path_GREP+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if ${ac_cv_path_EGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 $as_echo_n "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case "$ECHO" in printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 $as_echo "printf" >&6; } ;; print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 $as_echo "print -r" >&6; } ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 $as_echo "cat" >&6; } ;; esac # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if ${lt_cv_path_LD+:} false; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if ${lt_cv_prog_gnu_ld+:} false; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld SAVE_LIBTOOL="$LIBTOOL" enable_dlopen=yes case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.2' macro_revision='1.3337' ltmain="$ac_aux_dir/ltmain.sh" # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if ${lt_cv_path_NM+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if ${lt_cv_nm_interface+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if ${lt_cv_sys_max_cmd_len+:} false; then : $as_echo_n "(cached) " >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 $as_echo_n "checking how to convert $build file names to $host format... " >&6; } if ${lt_cv_to_host_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 $as_echo "$lt_cv_to_host_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 $as_echo_n "checking how to convert $build file names to toolchain format... " >&6; } if ${lt_cv_to_tool_file_cmd+:} false; then : $as_echo_n "(cached) " >&6 else #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 $as_echo "$lt_cv_to_tool_file_cmd" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if ${lt_cv_ld_reload_flag+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test "$GCC" != yes; then reload_cmds=false fi ;; darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if ${lt_cv_deplibs_check_method+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin. if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 $as_echo "$DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 $as_echo "$ac_ct_DLLTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 $as_echo_n "checking how to associate runtime and link libraries... " >&6; } if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 $as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_AR+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} : ${AR_FLAGS=cru} { $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 $as_echo_n "checking for archiver @FILE support... " >&6; } if ${lt_cv_ar_at_file+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 $as_echo "$lt_cv_ar_at_file" >&6; } if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_STRIP+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if ${lt_cv_sys_global_symbol_pipe+:} false; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 $as_echo_n "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test "${with_sysroot+set}" = set; then : withval=$with_sysroot; else with_sysroot=no fi lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5 $as_echo "${with_sysroot}" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 $as_echo "${lt_sysroot:-no}" >&6; } # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if ${lt_cv_cc_needs_belf+:} false; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 $as_echo "$MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_MANIFEST_TOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 $as_echo "$ac_ct_MANIFEST_TOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 $as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if ${lt_cv_path_mainfest_tool+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 $as_echo "$lt_cv_path_mainfest_tool" >&6; } if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_LIPO+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if ${lt_cv_apple_cc_single_mod+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if ${lt_cv_ld_exported_symbols_list+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 $as_echo_n "checking for -force_load linker flag... " >&6; } if ${lt_cv_ld_force_load+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR cru libconftest.a conftest.o" >&5 $AR cru libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 $as_echo "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if ${ac_cv_header_stdc+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done # Set options enable_win32_dll=no # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=yes fi # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if ${lt_cv_objdir+:} false; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if ${lt_cv_path_MAGIC_CMD+:} false; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if ${lt_cv_prog_compiler_pic+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 $as_echo "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if ${lt_cv_prog_compiler_pic_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if ${lt_cv_prog_compiler_static_works+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if ${lt_cv_prog_compiler_c_o+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='${wl}--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' link_all_deplibs=yes ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi link_all_deplibs=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else if ${lt_cv_aix_libpath_+:} false; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_="/usr/lib:/lib" fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test "$lt_cv_ld_force_load" = "yes"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 $as_echo_n "checking if $CC understands -b... " >&6; } if ${lt_cv_prog_compiler__b+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler__b=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 $as_echo "$lt_cv_prog_compiler__b" >&6; } if test x"$lt_cv_prog_compiler__b" = xyes; then archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 $as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if ${lt_cv_irix_exported_symbol+:} false; then : $as_echo_n "(cached) " >&6 else save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_irix_exported_symbol=yes else lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 $as_echo "$lt_cv_irix_exported_symbol" >&6; } if test "$lt_cv_irix_exported_symbol" = yes; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } if ${lt_cv_archive_cmds_need_lc+:} false; then : $as_echo_n "(cached) " >&6 else $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 $as_echo "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([A-Za-z]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if ${lt_cv_shlibpath_overrides_runpath+:} false; then : $as_echo_n "(cached) " >&6 else lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if ${ac_cv_lib_dld_shl_load+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if ${ac_cv_lib_dl_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if ${ac_cv_lib_svld_dlopen+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if ${ac_cv_lib_dld_dld_link+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if ${lt_cv_dlopen_self_static+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC="$lt_save_CC" ac_config_commands="$ac_config_commands libtool" # Only expand once: if ${TEST} -n "${SAVE_LIBTOOL}" ; then LIBTOOL="$SAVE_LIBTOOL" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: LIBTOOL=\"$LIBTOOL\"" >&5 $as_echo "LIBTOOL=\"$LIBTOOL\"" >&6; } # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char" >&5 $as_echo_n "checking size of char... " >&6; } if ${ac_cv_sizeof_char+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (char))" "ac_cv_sizeof_char" "$ac_includes_default"; then : else if test "$ac_cv_type_char" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (char) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_char=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5 $as_echo "$ac_cv_sizeof_char" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_CHAR $ac_cv_sizeof_char _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 $as_echo_n "checking size of int... " >&6; } if ${ac_cv_sizeof_int+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default"; then : else if test "$ac_cv_type_int" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_int=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 $as_echo "$ac_cv_sizeof_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 $as_echo_n "checking size of long... " >&6; } if ${ac_cv_sizeof_long+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long))" "ac_cv_sizeof_long" "$ac_includes_default"; then : else if test "$ac_cv_type_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 $as_echo "$ac_cv_sizeof_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG $ac_cv_sizeof_long _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 $as_echo_n "checking size of short... " >&6; } if ${ac_cv_sizeof_short+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default"; then : else if test "$ac_cv_type_short" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (short) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_short=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 $as_echo "$ac_cv_sizeof_short" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_SHORT $ac_cv_sizeof_short _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long double" >&5 $as_echo_n "checking size of long double... " >&6; } if ${ac_cv_sizeof_long_double+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long double))" "ac_cv_sizeof_long_double" "$ac_includes_default"; then : else if test "$ac_cv_type_long_double" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long double) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_double=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_double" >&5 $as_echo "$ac_cv_sizeof_long_double" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_DOUBLE $ac_cv_sizeof_long_double _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 $as_echo_n "checking size of long long... " >&6; } if ${ac_cv_sizeof_long_long+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then : else if test "$ac_cv_type_long_long" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (long long) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_long_long=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 $as_echo "$ac_cv_sizeof_long_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long _ACEOF # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of longlong" >&5 $as_echo_n "checking size of longlong... " >&6; } if ${ac_cv_sizeof_longlong+:} false; then : $as_echo_n "(cached) " >&6 else if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (longlong))" "ac_cv_sizeof_longlong" "$ac_includes_default"; then : else if test "$ac_cv_type_longlong" = yes; then { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (longlong) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_longlong=0 fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_longlong" >&5 $as_echo "$ac_cv_sizeof_longlong" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONGLONG $ac_cv_sizeof_longlong _ACEOF # Now we need to find what jk_uint32_t (sizeof == 4) will be. # The first match is our preference. if test "$ac_cv_sizeof_int" = "4"; then int32_t_fmt='#define JK_INT32_T_FMT "d"' uint32_t_fmt='#define JK_UINT32_T_FMT "u"' uint32_t_hex_fmt='#define JK_UINT32_T_HEX_FMT "x"' int32_value="int" elif test "$ac_cv_sizeof_long" = "4"; then int32_t_fmt='#define JK_INT32_T_FMT "ld"' uint32_t_fmt='#define JK_UINT32_T_FMT "lu"' uint32_t_hex_fmt='#define JK_UINT32_T_HEX_FMT "lx"' int32_value="long" else int32_t_fmt='#error could not detect a 32-bit integer type' uint32_t_fmt='#error could not detect a 32-bit integer type' uint32_t_hex_fmt='#error could not detect a 32-bit integer type' as_fn_error $? "could not detect a 32-bit integer type" "$LINENO" 5 fi # Now we need to find what jk_uint64_t (sizeof == 8) will be. # The first match is our preference. if test "$ac_cv_sizeof_int" = "8"; then int64_t_fmt='#define JK_INT64_T_FMT "d"' uint64_t_fmt='#define JK_UINT64_T_FMT "u"' uint64_t_hex_fmt='#define JK_UINT64_T_HEX_FMT "x"' int64_value="int" elif test "$ac_cv_sizeof_long" = "8"; then int64_t_fmt='#define JK_INT64_T_FMT "ld"' uint64_t_fmt='#define JK_UINT64_T_FMT "lu"' uint64_t_hex_fmt='#define JK_UINT64_T_HEX_FMT "lx"' int64_value="long" elif test "$ac_cv_sizeof_long_long" = "8"; then # Linux, Solaris, FreeBSD all support ll with printf. # BSD 4.4 originated 'q'. Solaris is more popular and # doesn't support 'q'. Solaris wins. Exceptions can # go to the OS-dependent section. int64_t_fmt='#define JK_INT64_T_FMT "lld"' uint64_t_fmt='#define JK_UINT64_T_FMT "llu"' uint64_t_hex_fmt='#define JK_UINT64_T_HEX_FMT "llx"' int64_value="long long" elif test "$ac_cv_sizeof_long_double" = "8"; then int64_t_fmt='#define JK_INT64_T_FMT "Ld"' uint64_t_fmt='#define JK_UINT64_T_FMT "Lu"' uint64_t_hex_fmt='#define JK_UINT64_T_HEX_FMT "Lx"' int64_value="long double" elif test "$ac_cv_sizeof_longlong" = "8"; then int64_t_fmt='#define JK_INT64_T_FMT "qd"' uint64_t_fmt='#define JK_UINT64_T_FMT "qu"' uint64_t_hex_fmt='#define JK_UINT64_T_HEX_FMT "qx"' int64_value="__int64" else int64_t_fmt='#error could not detect a 64-bit integer type' uint64_t_fmt='#error could not detect a 64-bit integer type' uint64_t_hex_fmt='#error could not detect a 64-bit integer type' as_fn_error $? "could not detect a 64-bit integer type" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of pid_t" >&5 $as_echo_n "checking size of pid_t... " >&6; } if ${ac_cv_sizeof_pid_t+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_sizeof_pid_t=8 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include main() { FILE *f=fopen("conftestval","w"); if (!f) exit(1); fprintf(f, "%d\n", sizeof(pid_t)); exit(0); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_sizeof_pid_t=`cat conftestval` else ac_cv_sizeof_pid_t=0 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_pid_t" >&5 $as_echo "$ac_cv_sizeof_pid_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_PID_T $ac_cv_sizeof_pid_t _ACEOF if test "$ac_cv_sizeof_pid_t" = "$ac_cv_sizeof_short"; then pid_t_fmt='#define JK_PID_T_FMT "hd"' elif test "$ac_cv_sizeof_pid_t" = "$ac_cv_sizeof_int"; then pid_t_fmt='#define JK_PID_T_FMT "d"' elif test "$ac_cv_sizeof_pid_t" = "$ac_cv_sizeof_long"; then pid_t_fmt='#define JK_PID_T_FMT "ld"' elif test "$ac_cv_sizeof_pid_t" = "$ac_cv_sizeof_long_long"; then pid_t_fmt='#define JK_PID_T_FMT JK_INT64_T_FMT' else pid_t_fmt='#error Can not determine the proper size for pid_t' fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of pthread_t" >&5 $as_echo_n "checking size of pthread_t... " >&6; } if ${ac_cv_sizeof_pthread_t+:} false; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : ac_cv_sizeof_pthread_t=8 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include main() { FILE *f=fopen("conftestval","w"); if (!f) exit(1); fprintf(f, "%d\n", sizeof(pthread_t)); exit(0); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : ac_cv_sizeof_pthread_t=`cat conftestval` else ac_cv_sizeof_pthread_t=0 fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_pthread_t" >&5 $as_echo "$ac_cv_sizeof_pthread_t" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_PTHREAD_T $ac_cv_sizeof_pthread_t _ACEOF if test "$ac_cv_sizeof_pthread_t" = "$ac_cv_sizeof_short"; then pthread_t_fmt='#define JK_PTHREAD_T_FMT "hu"' pthread_t_value="short" elif test "$ac_cv_sizeof_pthread_t" = "$ac_cv_sizeof_int"; then pthread_t_fmt='#define JK_PTHREAD_T_FMT "u"' pthread_t_value="int" elif test "$ac_cv_sizeof_pthread_t" = "$ac_cv_sizeof_long"; then pthread_t_fmt='#define JK_PTHREAD_T_FMT "lu"' pthread_t_value="long" elif test "$ac_cv_sizeof_pthread_t" = "$ac_cv_sizeof_long_long"; then pthread_t_fmt='#define JK_PTHREAD_T_FMT "llu"' pthread_t_value="long long" else pthread_t_fmt='#error Can not determine the proper size for pthread_t' fi # Basically, we have tried to figure out the correct format strings # for pid_t which varies between platforms, but we don't always get # it right. If you find that we don't get it right for your platform, # you can override our decision below. case $host in *-solaris*) if test "$ac_cv_sizeof_pid_t" = "$ac_cv_sizeof_long"; then pid_t_fmt='#define JK_PID_T_FMT "ld"' fi ;; esac ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf" if test "x$ac_cv_func_snprintf" = xyes; then : $as_echo "#define HAVE_SNPRINTF 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf" if test "x$ac_cv_func_vsnprintf" = xyes; then : $as_echo "#define HAVE_VSNPRINTF 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "flock" "ac_cv_func_flock" if test "x$ac_cv_func_flock" = xyes; then : $as_echo "#define HAVE_FLOCK 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lsocket" >&5 $as_echo_n "checking for setsockopt in -lsocket... " >&6; } if ${ac_cv_lib_socket_setsockopt+:} false; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char setsockopt (); int main () { return setsockopt (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_socket_setsockopt=yes else ac_cv_lib_socket_setsockopt=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_setsockopt" >&5 $as_echo "$ac_cv_lib_socket_setsockopt" >&6; } if test "x$ac_cv_lib_socket_setsockopt" = xyes; then : LIBS="$LIBS -lsocket" fi for ac_header in sys/filio.h do : ac_fn_c_check_header_mongrel "$LINENO" "sys/filio.h" "ac_cv_header_sys_filio_h" "$ac_includes_default" if test "x$ac_cv_header_sys_filio_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_SYS_FILIO_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use SO_RCVTIMEO with setsockopt()" >&5 $as_echo_n "checking whether to use SO_RCVTIMEO with setsockopt()... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main(void) { int s; struct timeval tv; tv.tv_sec = 3; tv.tv_usec = 0; #ifndef SO_RCVTIMEO exit(3); #else if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) exit(2); /* fails on Solaris 2.6,8,9,10 and some Linuxes because SO_RCVTIMEO|SO_SNDTIMEO are defined but not implemented */ if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, (const void *)&tv, sizeof(tv)) == -1) exit(1); exit(0); #endif } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define USE_SO_RCVTIMEO 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use SO_SNDTIMEO with setsockopt()" >&5 $as_echo_n "checking whether to use SO_SNDTIMEO with setsockopt()... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main(void) { int s; struct timeval tv; tv.tv_sec = 3; tv.tv_usec = 0; #ifndef SO_SNDTIMEO exit(3); #else if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) exit(2); /* fails on Solaris 2.6,8,9,10 and some Linuxes because SO_RCVTIMEO|SO_SNDTIMEO are defined but not implemented */ if (setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, (const void *)&tv, sizeof(tv)) == -1) exit(1); exit(0); #endif } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define USE_SO_SNDTIMEO 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi # Check whether --enable-sock-cloexec was given. if test "${enable_sock_cloexec+set}" = set; then : enableval=$enable_sock_cloexec; case "${enableval}" in y | Y | YES | yes | TRUE | true ) { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use SOCK_CLOEXEC with socket()" >&5 $as_echo_n "checking whether to use SOCK_CLOEXEC with socket()... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main(void) { int s; #ifndef SOCK_CLOEXEC exit(3); #else if ((s = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0)) == -1) exit(2); exit(0); #endif } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define USE_SOCK_CLOEXEC 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ;; esac else { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use SOCK_CLOEXEC with socket()" >&5 $as_echo_n "checking whether to use SOCK_CLOEXEC with socket()... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main(void) { int s; #ifndef SOCK_CLOEXEC exit(3); #else if ((s = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0)) == -1) exit(2); exit(0); #endif } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define USE_SOCK_CLOEXEC 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi for ac_header in poll.h do : ac_fn_c_check_header_mongrel "$LINENO" "poll.h" "ac_cv_header_poll_h" "$ac_includes_default" if test "x$ac_cv_header_poll_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_POLL_H 1 _ACEOF fi done ac_fn_c_check_func "$LINENO" "poll" "ac_cv_func_poll" if test "x$ac_cv_func_poll" = xyes; then : $as_echo "#define HAVE_POLL 1" >>confdefs.h fi for ac_header in netinet/in.h do : ac_fn_c_check_header_mongrel "$LINENO" "netinet/in.h" "ac_cv_header_netinet_in_h" "$ac_includes_default" if test "x$ac_cv_header_netinet_in_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NETINET_IN_H 1 _ACEOF fi done for ac_header in netdb.h do : ac_fn_c_check_header_mongrel "$LINENO" "netdb.h" "ac_cv_header_netdb_h" "$ac_includes_default" if test "x$ac_cv_header_netdb_h" = xyes; then : cat >>confdefs.h <<_ACEOF #define HAVE_NETDB_H 1 _ACEOF fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IPv6 with socket()" >&5 $as_echo_n "checking for IPv6 with socket()... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main(void) { int s; if ((s = socket(AF_INET6, SOCK_STREAM, 0)) == -1) exit(2); exit(0); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_AF_INET6 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct sockaddr_storage" >&5 $as_echo_n "checking for struct sockaddr_storage... " >&6; } if test "$cross_compiling" = yes; then : { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run test program while cross compiling See \`config.log' for more details" "$LINENO" 5; } else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include int main(void) { struct sockaddr_storage sa; exit(sizeof(sa) == 0); } _ACEOF if ac_fn_c_try_run "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } $as_echo "#define HAVE_SOCKADDR_STORAGE 1" >>confdefs.h else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi ac_fn_c_check_func "$LINENO" "getaddrinfo" "ac_cv_func_getaddrinfo" if test "x$ac_cv_func_getaddrinfo" = xyes; then : $as_echo "#define HAVE_GETADDRINFO 1" >>confdefs.h fi ac_fn_c_check_func "$LINENO" "gethostbyname_r" "ac_cv_func_gethostbyname_r" if test "x$ac_cv_func_gethostbyname_r" = xyes; then : $as_echo "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for target platform" >&5 $as_echo_n "checking for target platform... " >&6; } #PLATFORM=`${CONFIG_SHELL-/bin/sh} $ac_config_guess` PLATFORM=$host case "$PLATFORM" in *beos*) OS_APACHE="beos" OS_APACHE_DIR=$OS_APACHE ;; *pc-os2_emx*) OS_APACHE="os2" OS_APACHE_DIR=$OS_APACHE ;; bs2000*) OS_APACHE="unix" OS_APACHE_DIR=bs2000 # only the OS_APACHE_DIR is platform specific. ;; *) OS_APACHE="unix" OS_APACHE_DIR=$OS_APACHE;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OS_APACHE" >&5 $as_echo "$OS_APACHE" >&6; } apache_dir_is_src="false" # Check whether --with-apache was given. if test "${with_apache+set}" = set; then : withval=$with_apache; if ${TEST} ! -z "$WEBSERVER" ; then as_fn_error $? "Sorry cannot use --with-apxs=${APXS} and --with-apache=${withval} together, please choose one of both" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Apache source directory (assume static build)" >&5 $as_echo_n "checking for Apache source directory (assume static build)... " >&6; } if ${TEST} -n "${withval}" && ${TEST} -d "${withval}" ; then if ${TEST} -d "${withval}/src" ; then # handle the case where people use relative paths to # the apache source directory by pre-pending the current # build directory to the path. there are probably # errors with this if configure is run while in a # different directory than what you are in at the time if ${TEST} -n "`${ECHO} ${withval}|${GREP} \"^\.\.\"`" ; then withval=`pwd`/${withval} fi apache_dir=${withval} apache_dir_is_src="true" { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${apache_dir}" >&5 $as_echo "${apache_dir}" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Apache include directory" >&5 $as_echo_n "checking for Apache include directory... " >&6; } if ${TEST} -d "${withval}/src/include" ; then # read osdir from the existing apache. osdir=`${GREP} '^OSDIR=' ${withval}/src/Makefile.config | ${SED} -e 's:^OSDIR=.*/os:os:'` if ${TEST} -z "${osdir}" ; then osdir=os/unix fi apache_include="-I${withval}/src/include \ -I${withval}/src/${osdir}" WEBSERVER="apache-1.3" LIB_JK_TYPE=mod_jk.a CFLAGS="${CFLAGS} -DJK_PREFORK" { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${apache_include}, version 1.3" >&5 $as_echo "${apache_include}, version 1.3" >&6; } else as_fn_error $? "Sorry Apache 1.2.x is no longer supported." "$LINENO" 5 fi else if ${TEST} -d "${withval}/include" ; then # osdir for Apache20. WEBSERVER="apache-2.0" apache_dir=${withval} apache_dir_is_src="true" LIB_JK_TYPE=lib_jk.la apache_include="-I${withval}/include -I${withval}/srclib/apr/include -I${withval}/os/${OS_APACHE_DIR} -I${withval}/srclib/apr-util/include" { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${apache_dir}" >&5 $as_echo "${apache_dir}" >&6; } fi fi fi if ${TEST} -z "$WEBSERVER" ; then as_fn_error $? "Directory $apache_dir is not a valid Apache source distribution" "$LINENO" 5 fi # VT: Now, which one I'm supposed to use? Let's figure it out later configure_apache=true configure_src=true { $as_echo "$as_me:${as_lineno-$LINENO}: result: building connector for \"$WEBSERVER\"" >&5 $as_echo "building connector for \"$WEBSERVER\"" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no apache given" >&5 $as_echo "no apache given" >&6; } fi APACHE_DIR=${apache_dir} # Check whether --enable-netscape was given. if test "${enable_netscape+set}" = set; then : enableval=$enable_netscape; if ${TEST} ! -z "$WEBSERVER" ; then as_fn_error $? "Sorry cannot use --with-apxs=${APXS} or --with-apache=${withval} with --with-netscape, please choose one or the other." "$LINENO" 5 fi WEBSERVER="netscape" { $as_echo "$as_me:${as_lineno-$LINENO}: result: building connector for \"$WEBSERVER\"" >&5 $as_echo "building connector for \"$WEBSERVER\"" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no netscape given" >&5 $as_echo "no netscape given" >&6; } fi CFLAGS="${CFLAGS}" # Check whether --enable-EAPI was given. if test "${enable_EAPI+set}" = set; then : enableval=$enable_EAPI; case "${enableval}" in y | Y | YES | yes | TRUE | true ) CFLAGS="${CFLAGS} -DEAPI" { $as_echo "$as_me:${as_lineno-$LINENO}: result: ...Enabling EAPI Support..." >&5 $as_echo "...Enabling EAPI Support..." >&6; } ;; esac fi CFLAGS="${CFLAGS}" # Check whether --enable-maintainer-mode was given. if test "${enable_maintainer_mode+set}" = set; then : enableval=$enable_maintainer_mode; case "${enableval}" in y | Y | YES | yes | TRUE | true ) CFLAGS="${CFLAGS} -DDEBUG -Wall" { $as_echo "$as_me:${as_lineno-$LINENO}: result: ...Enabling Maintainer mode..." >&5 $as_echo "...Enabling Maintainer mode..." >&6; } ;; esac fi CFLAGS="${CFLAGS}" # Check whether --enable-prefork was given. if test "${enable_prefork+set}" = set; then : enableval=$enable_prefork; case "${enableval}" in y | Y | YES | yes | TRUE | true ) CFLAGS="${CFLAGS} -DJK_PREFORK" { $as_echo "$as_me:${as_lineno-$LINENO}: result: ...Enabling Prefork mode..." >&5 $as_echo "...Enabling Prefork mode..." >&6; } ;; esac fi CFLAGS="${CFLAGS}" # Check whether --enable-trace was given. if test "${enable_trace+set}" = set; then : enableval=$enable_trace; case "${enableval}" in no ) CFLAGS="${CFLAGS} -DJK_PRODUCTION" { $as_echo "$as_me:${as_lineno-$LINENO}: result: ...Exclude trace log code..." >&5 $as_echo "...Exclude trace log code..." >&6; } ;; esac fi CFLAGS="${CFLAGS}" # Check whether --enable-api-compatibility was given. if test "${enable_api_compatibility+set}" = set; then : enableval=$enable_api_compatibility; case "${enableval}" in y | Y | YES | yes | TRUE | true ) CFLAGS="${CFLAGS} -DAPI_COMPATIBILITY" { $as_echo "$as_me:${as_lineno-$LINENO}: result: ...Only using compatible httpd API..." >&5 $as_echo "...Only using compatible httpd API..." >&6; } ;; esac fi CFLAGS="${CFLAGS}" # Check whether --enable-flock was given. if test "${enable_flock+set}" = set; then : enableval=$enable_flock; case "${enableval}" in y | Y | YES | yes | TRUE | true ) CFLAGS="${CFLAGS} -DJK_USE_FLOCK" { $as_echo "$as_me:${as_lineno-$LINENO}: result: ...Enabling flock() shared memory locking..." >&5 $as_echo "...Enabling flock() shared memory locking..." >&6; } ;; esac fi if ${TEST} -n "${CFLAGS}" ; then APXSCFLAGS="${APXSCFLAGS} ${CFLAGS}" fi if ${TEST} -n "${LDFLAGS}" ; then APXSLDFLAGS="${APXSLDFLAGS} ${LDFLAGS}" fi jk_new_val="" jk_val_changed=0 for i in $APXSLDFLAGS; do case $i in -Wl,*) jk_new_val="$jk_new_val $i" ;; *) jk_new_val="$jk_new_val -Wl,$i" jk_val_changed=1 ;; esac done if test $jk_val_changed = "1"; then { $as_echo "$as_me:${as_lineno-$LINENO}: tokens in APXSLDFLAGS have been prefixed with '-Wl,'" >&5 $as_echo "$as_me: tokens in APXSLDFLAGS have been prefixed with '-Wl,'" >&6;} APXSLDFLAGS=$jk_new_val fi if ${TEST} -z "$WEBSERVER" ; then as_fn_error $? "Cannot find the WebServer" "$LINENO" 5 fi WEBSERVER="common ${WEBSERVER}" if ${TEST} "${apache_dir_is_src}" = "false"; then MAKE_DYNAMIC_APACHE_TRUE= MAKE_DYNAMIC_APACHE_FALSE='#' else MAKE_DYNAMIC_APACHE_TRUE='#' MAKE_DYNAMIC_APACHE_FALSE= fi if ${TEST} "${apache_dir_is_src}" = "false" ; then APACHE20_OEXT=.c LIB_JK_TYPE=mod_jk.so INSTALL_TYPE=install_dynamic else APACHE20_OEXT=.lo INSTALL_TYPE=install_static fi ac_config_files="$ac_config_files Makefile apache-1.3/Makefile apache-1.3/Makefile.apxs apache-2.0/Makefile apache-2.0/Makefile.apxs common/Makefile common/list.mk common/jk_types.h" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 $as_echo_n "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 $as_echo "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${MAKE_DYNAMIC_APACHE_TRUE}" && test -z "${MAKE_DYNAMIC_APACHE_FALSE}"; then as_fn_error $? "conditional \"MAKE_DYNAMIC_APACHE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by mod_jk $as_me 1.2.41, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ mod_jk config.status 1.2.41 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" Copyright (C) 2012 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in SED \ GREP \ EGREP \ FGREP \ SHELL \ ECHO \ LD \ PATH_SEPARATOR \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ nm_file_list_spec \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "common/config.h") CONFIG_HEADERS="$CONFIG_HEADERS common/config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "apache-1.3/Makefile") CONFIG_FILES="$CONFIG_FILES apache-1.3/Makefile" ;; "apache-1.3/Makefile.apxs") CONFIG_FILES="$CONFIG_FILES apache-1.3/Makefile.apxs" ;; "apache-2.0/Makefile") CONFIG_FILES="$CONFIG_FILES apache-2.0/Makefile" ;; "apache-2.0/Makefile.apxs") CONFIG_FILES="$CONFIG_FILES apache-2.0/Makefile.apxs" ;; "common/Makefile") CONFIG_FILES="$CONFIG_FILES common/Makefile" ;; "common/list.mk") CONFIG_FILES="$CONFIG_FILES common/list.mk" ;; "common/jk_types.h") CONFIG_FILES="$CONFIG_FILES common/jk_types.h" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="" # ### BEGIN LIBTOOL CONFIG # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # DLL creation program. DLLTOOL=$lt_DLLTOOL # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive. AR_FLAGS=$lt_AR_FLAGS # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and in which our libraries should be installed. lt_sysroot=$lt_sysroot # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) if test x"$xsi_shell" = xyes; then sed -e '/^func_dirname ()$/,/^} # func_dirname /c\ func_dirname ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ } # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_basename ()$/,/^} # func_basename /c\ func_basename ()\ {\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\ func_dirname_and_basename ()\ {\ \ case ${1} in\ \ */*) func_dirname_result="${1%/*}${2}" ;;\ \ * ) func_dirname_result="${3}" ;;\ \ esac\ \ func_basename_result="${1##*/}"\ } # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_stripname ()$/,/^} # func_stripname /c\ func_stripname ()\ {\ \ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\ \ # positional parameters, so assign one to ordinary parameter first.\ \ func_stripname_result=${3}\ \ func_stripname_result=${func_stripname_result#"${1}"}\ \ func_stripname_result=${func_stripname_result%"${2}"}\ } # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\ func_split_long_opt ()\ {\ \ func_split_long_opt_name=${1%%=*}\ \ func_split_long_opt_arg=${1#*=}\ } # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\ func_split_short_opt ()\ {\ \ func_split_short_opt_arg=${1#??}\ \ func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\ } # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\ func_lo2o ()\ {\ \ case ${1} in\ \ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\ \ *) func_lo2o_result=${1} ;;\ \ esac\ } # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_xform ()$/,/^} # func_xform /c\ func_xform ()\ {\ func_xform_result=${1%.*}.lo\ } # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_arith ()$/,/^} # func_arith /c\ func_arith ()\ {\ func_arith_result=$(( $* ))\ } # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_len ()$/,/^} # func_len /c\ func_len ()\ {\ func_len_result=${#1}\ } # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$lt_shell_append" = xyes; then sed -e '/^func_append ()$/,/^} # func_append /c\ func_append ()\ {\ eval "${1}+=\\${2}"\ } # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\ func_append_quoted ()\ {\ \ func_quote_for_eval "${2}"\ \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"\ } # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5 $as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;} fi mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi if ${TEST} -n "${WARN_CC}" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ===========================================" >&5 $as_echo "$as_me: WARNING: ===========================================" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Using CC from environment:" >&5 $as_echo "$as_me: WARNING: Using CC from environment:" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: CC=\"$CC\"" >&5 $as_echo "$as_me: WARNING: CC=\"$CC\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: instead of CC from apxs:" >&5 $as_echo "$as_me: WARNING: instead of CC from apxs:" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: CC=\"$APXSCC\"" >&5 $as_echo "$as_me: WARNING: CC=\"$APXSCC\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: If \"make\" throws an error of the form" >&5 $as_echo "$as_me: WARNING: If \"make\" throws an error of the form" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"libtool: compile: unable to infer tagged configuration\"" >&5 $as_echo "$as_me: WARNING: \"libtool: compile: unable to infer tagged configuration\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"libtool: compile: specify a tag with \`--tag'\"" >&5 $as_echo "$as_me: WARNING: \"libtool: compile: specify a tag with \`--tag'\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: try running configure without setting CC," >&5 $as_echo "$as_me: WARNING: try running configure without setting CC," >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: or at least CC should start with \"$APXSCC\"" >&5 $as_echo "$as_me: WARNING: or at least CC should start with \"$APXSCC\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: ===========================================" >&5 $as_echo "$as_me: WARNING: ===========================================" >&2;} fi tomcat-connectors-1.2.41-src/native/Makefile.in0000644000000000000020000007050412555256562017671 0ustar rootbin# Makefile.in generated by automake 1.14.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2013 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. VPATH = @srcdir@ am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)' am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ subdir = . DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/configure $(am__configure_deps) \ $(top_srcdir)/common/config.h.in \ $(top_srcdir)/apache-1.3/Makefile.in \ $(top_srcdir)/apache-1.3/Makefile.apxs.in \ $(top_srcdir)/apache-2.0/Makefile.in \ $(top_srcdir)/apache-2.0/Makefile.apxs.in \ $(top_srcdir)/common/Makefile.in \ $(top_srcdir)/common/list.mk.in \ $(top_srcdir)/common/jk_types.h.in scripts/build/unix/compile \ scripts/build/unix/config.guess scripts/build/unix/config.sub \ scripts/build/unix/install-sh scripts/build/unix/missing \ scripts/build/unix/ltmain.sh \ $(top_srcdir)/scripts/build/unix/compile \ $(top_srcdir)/scripts/build/unix/config.guess \ $(top_srcdir)/scripts/build/unix/config.sub \ $(top_srcdir)/scripts/build/unix/install-sh \ $(top_srcdir)/scripts/build/unix/ltmain.sh \ $(top_srcdir)/scripts/build/unix/missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/scripts/build/jk_common.m4 \ $(top_srcdir)/../support/os_apache.m4 \ $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/common/config.h CONFIG_CLEAN_FILES = apache-1.3/Makefile apache-1.3/Makefile.apxs \ apache-2.0/Makefile apache-2.0/Makefile.apxs common/Makefile \ common/list.mk common/jk_types.h CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-recursive dvi-recursive html-recursive info-recursive \ install-data-recursive install-dvi-recursive \ install-exec-recursive install-html-recursive \ install-info-recursive install-pdf-recursive \ install-ps-recursive install-recursive installcheck-recursive \ installdirs-recursive pdf-recursive ps-recursive \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_distdir) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ APACHE20_OEXT = @APACHE20_OEXT@ APACHE_CONFIG_VARS = @APACHE_CONFIG_VARS@ APACHE_DIR = @APACHE_DIR@ APXS = @APXS@ APXSCFLAGS = @APXSCFLAGS@ APXSCPPFLAGS = @APXSCPPFLAGS@ APXSLDFLAGS = @APXSLDFLAGS@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CP = @CP@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DLLTOOL = @DLLTOOL@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INSTALL_TYPE = @INSTALL_TYPE@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIB_JK_TYPE = @LIB_JK_TYPE@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR = @MKDIR@ MKDIR_P = @MKDIR_P@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PERL = @PERL@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ TEST = @TEST@ VERSION = @VERSION@ WEBSERVER = @WEBSERVER@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ apache_include = @apache_include@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ int32_t_fmt = @int32_t_fmt@ int32_value = @int32_value@ int64_t_fmt = @int64_t_fmt@ int64_value = @int64_value@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ pid_t_fmt = @pid_t_fmt@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ pthread_t_fmt = @pthread_t_fmt@ pthread_t_value = @pthread_t_value@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target = @target@ target_alias = @target_alias@ target_cpu = @target_cpu@ target_os = @target_os@ target_vendor = @target_vendor@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ uint32_t_fmt = @uint32_t_fmt@ uint32_t_hex_fmt = @uint32_t_hex_fmt@ uint64_t_fmt = @uint64_t_fmt@ uint64_t_hex_fmt = @uint64_t_hex_fmt@ # # Tell automake what it should do AUTOMAKE_OPTIONS = foreign MAINTAINERCLEANFILES = config.cache config.status config.log \ config.nice Makefile.in configure common/config.h.in \ common/config.h aclocal.m4 SUBDIRS = @WEBSERVER@ all: all-recursive .SUFFIXES: am--refresh: Makefile @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --foreign Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): common/config.h: common/stamp-h1 @test -f $@ || rm -f common/stamp-h1 @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) common/stamp-h1 common/stamp-h1: $(top_srcdir)/common/config.h.in $(top_builddir)/config.status @rm -f common/stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status common/config.h $(top_srcdir)/common/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f common/stamp-h1 touch $@ distclean-hdr: -rm -f common/config.h common/stamp-h1 apache-1.3/Makefile: $(top_builddir)/config.status $(top_srcdir)/apache-1.3/Makefile.in cd $(top_builddir) && $(SHELL) ./config.status $@ apache-1.3/Makefile.apxs: $(top_builddir)/config.status $(top_srcdir)/apache-1.3/Makefile.apxs.in cd $(top_builddir) && $(SHELL) ./config.status $@ apache-2.0/Makefile: $(top_builddir)/config.status $(top_srcdir)/apache-2.0/Makefile.in cd $(top_builddir) && $(SHELL) ./config.status $@ apache-2.0/Makefile.apxs: $(top_builddir)/config.status $(top_srcdir)/apache-2.0/Makefile.apxs.in cd $(top_builddir) && $(SHELL) ./config.status $@ common/Makefile: $(top_builddir)/config.status $(top_srcdir)/common/Makefile.in cd $(top_builddir) && $(SHELL) ./config.status $@ common/list.mk: $(top_builddir)/config.status $(top_srcdir)/common/list.mk.in cd $(top_builddir) && $(SHELL) ./config.status $@ common/jk_types.h: $(top_builddir)/config.status $(top_srcdir)/common/jk_types.h.in cd $(top_builddir) && $(SHELL) ./config.status $@ mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. # To change the values of 'make' variables: instead of editing Makefiles, # (1) if the variable is set in 'config.status', edit 'config.status' # (which will cause the Makefiles to be regenerated when you run 'make'); # (2) otherwise, pass the desired values on the 'make' command line. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ $(am__define_uniq_tagged_files); \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: ctags-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ lzip -dc $(distdir).tar.lz | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=.. --prefix="$$dc_install_base" \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__post_remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-hdr \ distclean-libtool distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \ dist-xz dist-zip distcheck distclean distclean-generic \ distclean-hdr distclean-libtool distclean-tags distcleancheck \ distdir distuninstallcheck dvi dvi-am html html-am info \ info-am install install-am install-data install-data-am \ install-dvi install-dvi-am install-exec install-exec-am \ install-html install-html-am install-info install-info-am \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ uninstall-am all: target="all"; \ list='$(SUBDIRS)'; \ for i in $$list; do \ echo "Making $$target in $$i"; \ if test "$$i" != "."; then \ (cd $$i && $(MAKE) $$target) || exit 1; \ fi; \ done; apidocs: common/*.h ../../scandoc/scandoc.pl -i ../../scandoc/template.pl -p \ ./docs/api/ -dproject="mod_jk Library" common/*.h common/*.c # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: tomcat-connectors-1.2.41-src/native/iis/0000755000000000000020000000000012555256552016401 5ustar rootbintomcat-connectors-1.2.41-src/native/iis/isapi.dsw0000644000000000000020000000201611416061212020202 0ustar rootbinMicrosoft Developer Studio Workspace File, Format Version 6.00 # WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! ############################################################################### Project: "dftables"=".\pcre\dftables.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ }}} ############################################################################### Project: "isapi"=".\isapi.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name pcre End Project Dependency }}} ############################################################################### Project: "pcre"=".\pcre\pcre.dsp" - Package Owner=<4> Package=<5> {{{ }}} Package=<4> {{{ Begin Project Dependency Project_Dep_Name dftables End Project Dependency }}} ############################################################################### Global: Package=<5> {{{ }}} Package=<3> {{{ }}} ############################################################################### tomcat-connectors-1.2.41-src/native/iis/isapi.def0000644000000000000020000000164511446407563020172 0ustar rootbin; Licensed to the Apache Software Foundation (ASF) under one or more ; contributor license agreements. See the NOTICE file distributed with ; this work for additional information regarding copyright ownership. ; The ASF licenses this file to You under the Apache License, Version 2.0 ; (the "License"); you may not use this file except in compliance with ; the License. You may obtain a copy of the License at ; ; http://www.apache.org/licenses/LICENSE-2.0 ; ; Unless required by applicable law or agreed to in writing, software ; distributed under the License is distributed on an "AS IS" BASIS, ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; See the License for the specific language governing permissions and ; limitations under the License. ; LIBRARY "isapi_redirect" EXPORTS HttpFilterProc GetFilterVersion GetExtensionVersion HttpExtensionProc TerminateFilter TerminateExtension tomcat-connectors-1.2.41-src/native/iis/isapi_redirect.reg0000644000000000000020000000067612446110725022065 0ustar rootbinREGEDIT4 [HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0] "extension_uri"="/jakarta/isapi_redirect.dll" "log_file"="C:\\tomcat\\logs\\isapi_redirect.%Y-%m-%d.log" "log_level"="info" "worker_file"="C:\\tomcat\\conf\\workers.properties" "worker_mount_file"="C:\\tomcat\\conf\\uriworkermap.properties" "log_rotationtime"="86400" "strip_session"="false" "reject_unsafe"="false" "enable_chunked_encoding"="false" tomcat-connectors-1.2.41-src/native/iis/isapi_install.vbs0000644000000000000020000001450710666607673021764 0ustar rootbin' ' Licensed to the Apache Software Foundation (ASF) under one or more ' contributor license agreements. See the NOTICE file distributed with ' this work for additional information regarding copyright ownership. ' The ASF licenses this file to You under the Apache License, Version 2.0 ' (the "License"); you may not use this file except in compliance with ' the License. You may obtain a copy of the License at ' ' http://www.apache.org/licenses/LICENSE-2.0 ' ' Unless required by applicable law or agreed to in writing, software ' distributed under the License is distributed on an "AS IS" BASIS, ' WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ' See the License for the specific language governing permissions and ' limitations under the License. ' ' ========================================================================= ' Description: Install script for Tomcat ISAPI redirector ' Author: Peter S. Horne ' Version: $Revision: 572120 $ ' ========================================================================= ' ' This script automatically installs the tomcat isapi_redirector for use in ' both out-of and in-process installations on IIS/Win2K. See the command line ' usage section for usage instructions. ' ' Check the command line ' set args = wscript.arguments if args.count <> 6 then info "" info "Tomcat ISAPI Redirector Installation Utility" info "usage: isapi_install " info " server: The Web Server Name (for example 'Default Web Site')" info " fdir: the full path to the directory that contains the isapi filter" info " worker: Full path and file name of the worker properties file" info " mount: Full path and file name of the worker mount properties file" info " log: Full path and file name of the log file" info " level: The log level emerg | info" info "(Re-runs are ok and will change/reset settings)" info "" fail "Incorrect Arguments" end if ' Setup the args serverName = args(0) filterDir = args(1) filterName = "jakarta" filterLib = "\isapi_redirect.dll" workerFile = args(2) mountFile = args(3) logFile = args(4) logLevel = args(5) ' ' Get a shell ' dim shell set shell = WScript.CreateObject("WScript.Shell") ' ' Find the indicated server from all the servers in the service ' Note: they aren't all Web! ' set service = GetObject("IIS://LocalHost/W3SVC" ) serverId = "" for each thing in service if thing.Class = "IIsWebServer" then if thing.ServerComment = serverName then set server = thing serverId = thing.name exit for end if end if next if serverId = "" then fail "Server " + serverName + " not found." info "Found Server <" + serverName + "> at index [" + serverId + "]." ' ' Stop everything to release any dlls - needed for a re-install ' ' info "Stopping server <" + serverName + ">..." ' server.stop ' info "Done" ' ' Get a handle to the filters for the server - we process all errors ' On Error Resume Next dim filters set filters = GetObject("IIS://LocalHost/W3SVC/" + serverId + "/Filters") if err then err.clear info "Filters not found for server - creating" set filters = server.create( "IIsFilters", "Filters" ) filters.setInfo if err then fail "Error Creating Filters" end if info "Got Filters" ' ' Create the filter - if it fails then delete it and try again ' name = filterName info "Creating Filter - " + filterName dim filter set filter = filters.Create( "IISFilter", filterName ) if err then err.clear info "Filter exists - deleting" filters.delete "IISFilter", filterName if err then fail "Error Deleting Filter" set filter = filters.Create( "IISFilter", filterName ) if err then fail "Error Creating Filter" end if info "Created Filter" ' ' Set the filter info and save it ' filter.FilterPath = filterDir + filterLib filter.FilterEnabled=true filter.description = filterName filter.notifyOrderHigh = true filter.setInfo ' ' Set the load order - only if it's not in the list already ' on error goto 0 loadOrders = filters.FilterLoadOrder list = Split( loadOrders, "," ) found = false for each item in list if Trim( item ) = filterName then found = true next if found = false then info "Filter is not in load order - adding now." if len(loadOrders) <> 0 then loadOrders = loadOrders + "," filters.FilterLoadOrder = loadOrders + filterName filters.setInfo info "Filter added." else info "Filter already exists in load order - no update required." end if ' ' Set the registry up ' regRoot = "HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0\" err.clear on error resume next shell.RegDelete( regRoot ) if err then info "Entering Registry Information for the first time" else info "Deleted existing Registry Setting" end if on error goto 0 info "Updating Registry" shell.RegWrite regRoot + "extension_uri", "/jakarta/isapi_redirect.dll" shell.RegWrite regRoot + "log_file", logFile shell.RegWrite regRoot + "log_level", logLevel shell.RegWrite regRoot + "worker_file", workerFile shell.RegWrite regRoot + "worker_mount_file", mountFile info "Registry Settings Created" ' ' Finally, create the virtual directory matching th extension uri ' on error goto 0 set root = GetObject( "IIS://LocalHost/W3SVC/" + serverID + "/ROOT" ) on error resume next set vdir = root.Create("IISWebVirtualDir", filterName ) if err then info "Directory exists - deleting" on error resume next root.delete "IISWebVirtualDir", filterName root.setInfo if err then fail "Error Deleting Directory" set vdir = root.create("IISWebVirtualDir", filterName ) if err then fail "Error Creating Directory" end if info "Directory Created" ' Set the directory information - make it an application directory info "Setting Directory Information" vdir.AppCreate2 1 vdir.AccessExecute = TRUE vdir.AppFriendlyName = filterName vdir.AccessRead = false vdir.ContentIndexed = false vdir.Path = filterDir vdir.setInfo if err then fail "Error saving new directory" info "Directory Saved" ' ' Re Start ' ' info "Starting server <" + serverName + ">..." ' server.start ' info "Done" info "All done... Bye." wscript.quit(0) ' ' Helper function for snafus ' function fail( message ) wscript.echo "E: " + message wscript.quit(1) end function ' ' Helper function for info ' function info( message ) wscript.echo " " + message end function tomcat-connectors-1.2.41-src/native/iis/pcre/0000755000000000000020000000000012555256552017332 5ustar rootbintomcat-connectors-1.2.41-src/native/iis/pcre/dftables.dsp0000644000000000000020000001055211416061212021607 0ustar rootbin# Microsoft Developer Studio Project File - Name="dftables" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Console Application" 0x0103 CFG=dftables - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "dftables.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 "dftables.mak" CFG="dftables - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "dftables - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "dftables - Win32 Debug" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "dftables - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MD /W3 /O2 /D "_WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fd"Release\dftables" /FD /c # ADD CPP /nologo /MD /W3 /wd4996 /O2 /D "_WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fd"Release\dftables" /FD /c # ADD BASE RSC /l 0x809 /d "NDEBUG" # ADD RSC /l 0x809 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib /nologo /subsystem:console /pdb:"Release\dftables.pdb" # SUBTRACT BASE LINK32 /pdb:none # ADD LINK32 kernel32.lib /nologo /subsystem:console /pdb:"Release\dftables.pdb" /opt:ref # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "dftables - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "_WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fd"Debug\dftables" /FD /c # ADD CPP /nologo /MDd /W3 /wd4996 /EHsc /Zi /Od /D "_WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /Fd"Debug\dftables" /FD /c # ADD BASE RSC /l 0x809 /d "_DEBUG" # ADD RSC /l 0x809 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"Debug\dftables.pdb" /debug /pdbtype:sept # SUBTRACT BASE LINK32 /pdb:none # ADD LINK32 kernel32.lib /nologo /subsystem:console /incremental:no /pdb:"Debug\dftables.pdb" /debug # SUBTRACT LINK32 /pdb:none !ENDIF # Begin Target # Name "dftables - Win32 Release" # Name "dftables - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "" # Begin Source File SOURCE=.\dftables.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hw" # Begin Source File SOURCE=.\config.hw !IF "$(CFG)" == "dftables - Win32 Release" # Begin Custom Build - Creating pcre config.h from config.hw InputPath=.\config.hw ".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" type .\config.hw > .\config.h # End Custom Build !ELSEIF "$(CFG)" == "dftables - Win32 Debug" # Begin Custom Build - Creating pcre config.h from config.hw InputPath=.\config.hw ".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" type .\config.hw > .\config.h # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=.\internal.h # End Source File # Begin Source File SOURCE=.\maketables.c # PROP Exclude_From_Build 1 # End Source File # Begin Source File SOURCE=.\pcre.hw !IF "$(CFG)" == "dftables - Win32 Release" # Begin Custom Build - Creating pcre.h from pcre.hw InputPath=.\pcre.hw ".\pcre.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" type .\pcre.hw > .\pcre.h # End Custom Build !ELSEIF "$(CFG)" == "dftables - Win32 Debug" # Begin Custom Build - Creating pcre.h from pcre.hw InputPath=.\pcre.hw ".\pcre.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" type .\pcre.hw > .\pcre.h # End Custom Build !ENDIF # End Source File # End Group # End Target # End Project tomcat-connectors-1.2.41-src/native/iis/pcre/config.in0000644000000000000020000001065210517277132021124 0ustar rootbin /* On Unix systems config.in is converted by configure into config.h. PCRE is written in Standard C, but there are a few non-standard things it can cope with, allowing it to run on SunOS4 and other "close to standard" systems. On a non-Unix system you should just copy this file into config.h, and set up the macros the way you need them. You should normally change the definitions of HAVE_STRERROR and HAVE_MEMMOVE to 1. Unfortunately, because of the way autoconf works, these cannot be made the defaults. If your system has bcopy() and not memmove(), change the definition of HAVE_BCOPY instead of HAVE_MEMMOVE. If your system has neither bcopy() nor memmove(), leave them both as 0; an emulation function will be used. */ /* If you are compiling for a system that uses EBCDIC instead of ASCII character codes, define this macro as 1. On systems that can use "configure", this can be done via --enable-ebcdic. */ #ifndef EBCDIC #define EBCDIC 0 #endif /* If you are compiling for a system that needs some magic to be inserted before the definition of an exported function, define this macro to contain the relevant magic. It apears at the start of every exported function. */ #define EXPORT /* Define to empty if the "const" keyword does not work. */ #undef const /* Define to "unsigned" if doesn't define size_t. */ #undef size_t /* The following two definitions are mainly for the benefit of SunOS4, which doesn't have the strerror() or memmove() functions that should be present in all Standard C libraries. The macros HAVE_STRERROR and HAVE_MEMMOVE should normally be defined with the value 1 for other systems, but unfortunately we can't make this the default because "configure" files generated by autoconf will only change 0 to 1; they won't change 1 to 0 if the functions are not found. */ #define HAVE_STRERROR 0 #define HAVE_MEMMOVE 0 /* There are some non-Unix systems that don't even have bcopy(). If this macro is false, an emulation is used. If HAVE_MEMMOVE is set to 1, the value of HAVE_BCOPY is not relevant. */ #define HAVE_BCOPY 0 /* The value of NEWLINE determines the newline character. The default is to leave it up to the compiler, but some sites want to force a particular value. On Unix systems, "configure" can be used to override this default. */ #ifndef NEWLINE #define NEWLINE '\n' #endif /* The value of LINK_SIZE determines the number of bytes used to store links as offsets within the compiled regex. The default is 2, which allows for compiled patterns up to 64K long. This covers the vast majority of cases. However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows for longer patterns in extreme cases. On Unix systems, "configure" can be used to override this default. */ #ifndef LINK_SIZE #define LINK_SIZE 2 #endif /* The value of MATCH_LIMIT determines the default number of times the match() function can be called during a single execution of pcre_exec(). (There is a runtime method of setting a different limit.) The limit exists in order to catch runaway regular expressions that take for ever to determine that they do not match. The default is set very large so that it does not accidentally catch legitimate cases. On Unix systems, "configure" can be used to override this default default. */ #ifndef MATCH_LIMIT #define MATCH_LIMIT 10000000 #endif /* When calling PCRE via the POSIX interface, additional working storage is required for holding the pointers to capturing substrings because PCRE requires three integers per substring, whereas the POSIX interface provides only two. If the number of expected substrings is small, the wrapper function uses space on the stack, because this is faster than using malloc() for each call. The threshold above which the stack is no longer use is defined by POSIX_MALLOC_ THRESHOLD. On Unix systems, "configure" can be used to override this default. */ #ifndef POSIX_MALLOC_THRESHOLD #define POSIX_MALLOC_THRESHOLD 10 #endif /* PCRE uses recursive function calls to handle backtracking while matching. This can sometimes be a problem on systems that have stacks of limited size. Define NO_RECURSE to get a version that doesn't use recursion in the match() function; instead it creates its own stack by steam using pcre_recurse_malloc to get memory. For more detail, see comments and other stuff just above the match() function. On Unix systems, "configure" can be used to set this in the Makefile (use --disable-stack-for-recursion). */ /* #define NO_RECURSE */ /* End */ tomcat-connectors-1.2.41-src/native/iis/pcre/pcre.def0000644000000000000020000000041710517277132020736 0ustar rootbinEXPORTS pcre_malloc DATA pcre_free DATA pcre_compile pcre_copy_substring pcre_exec pcre_get_substring pcre_get_substring_list pcre_free_substring pcre_free_substring_list pcre_info pcre_fullinfo pcre_maketables pcre_study pcre_version regcomp regexec regerror regfree tomcat-connectors-1.2.41-src/native/iis/pcre/pgrep.c0000644000000000000020000001137510517277132020613 0ustar rootbin/************************************************* * PCRE grep program * *************************************************/ #include #include #include #include #include "config.h" #include "pcre.h" #define FALSE 0 #define TRUE 1 typedef int BOOL; /************************************************* * Global variables * *************************************************/ static pcre *pattern; static pcre_extra *hints; static BOOL count_only = FALSE; static BOOL filenames_only = FALSE; static BOOL invert = FALSE; static BOOL number = FALSE; static BOOL silent = FALSE; static BOOL whole_lines = FALSE; #if ! HAVE_STRERROR /************************************************* * Provide strerror() for non-ANSI libraries * *************************************************/ /* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror() in their libraries, but can provide the same facility by this simple alternative function. */ extern int sys_nerr; extern char *sys_errlist[]; char * strerror(int n) { if (n < 0 || n >= sys_nerr) return "unknown error number"; return sys_errlist[n]; } #endif /* HAVE_STRERROR */ /************************************************* * Grep an individual file * *************************************************/ static int pgrep(FILE *in, char *name) { int rc = 1; int linenumber = 0; int count = 0; int offsets[99]; char buffer[BUFSIZ]; while (fgets(buffer, sizeof(buffer), in) != NULL) { BOOL match; int length = (int)strlen(buffer); if (length > 0 && buffer[length-1] == '\n') buffer[--length] = 0; linenumber++; match = pcre_exec(pattern, hints, buffer, length, 0, 0, offsets, 99) >= 0; if (match && whole_lines && offsets[1] != length) match = FALSE; if (match != invert) { if (count_only) count++; else if (filenames_only) { fprintf(stdout, "%s\n", (name == NULL)? "" : name); return 0; } else if (silent) return 0; else { if (name != NULL) fprintf(stdout, "%s:", name); if (number) fprintf(stdout, "%d:", linenumber); fprintf(stdout, "%s\n", buffer); } rc = 0; } } if (count_only) { if (name != NULL) fprintf(stdout, "%s:", name); fprintf(stdout, "%d\n", count); } return rc; } /************************************************* * Usage function * *************************************************/ static int usage(int rc) { fprintf(stderr, "Usage: pgrep [-Vchilnsvx] pattern [file] ...\n"); return rc; } /************************************************* * Main program * *************************************************/ int main(int argc, char **argv) { int i; int rc = 1; int options = 0; int errptr; const char *error; BOOL filenames = TRUE; /* Process the options */ for (i = 1; i < argc; i++) { char *s; if (argv[i][0] != '-') break; s = argv[i] + 1; while (*s != 0) { switch (*s++) { case 'c': count_only = TRUE; break; case 'h': filenames = FALSE; break; case 'i': options |= PCRE_CASELESS; break; case 'l': filenames_only = TRUE; case 'n': number = TRUE; break; case 's': silent = TRUE; break; case 'v': invert = TRUE; break; case 'x': whole_lines = TRUE; options |= PCRE_ANCHORED; break; case 'V': fprintf(stderr, "PCRE version %s\n", pcre_version()); break; default: fprintf(stderr, "pgrep: unknown option %c\n", s[-1]); return usage(2); } } } /* There must be at least a regexp argument */ if (i >= argc) return usage(0); /* Compile the regular expression. */ pattern = pcre_compile(argv[i++], options, &error, &errptr, NULL); if (pattern == NULL) { fprintf(stderr, "pgrep: error in regex at offset %d: %s\n", errptr, error); return 2; } /* Study the regular expression, as we will be running it may times */ hints = pcre_study(pattern, 0, &error); if (error != NULL) { fprintf(stderr, "pgrep: error while studing regex: %s\n", error); return 2; } /* If there are no further arguments, do the business on stdin and exit */ if (i >= argc) return pgrep(stdin, NULL); /* Otherwise, work through the remaining arguments as files. If there is only one, don't give its name on the output. */ if (i == argc - 1) filenames = FALSE; if (filenames_only) filenames = TRUE; for (; i < argc; i++) { FILE *in = fopen(argv[i], "r"); if (in == NULL) { fprintf(stderr, "%s: failed to open: %s\n", argv[i], strerror(errno)); rc = 2; } else { int frc = pgrep(in, filenames? argv[i] : NULL); if (frc == 0 && rc == 1) rc = 0; fclose(in); } } return rc; } /* End */ tomcat-connectors-1.2.41-src/native/iis/pcre/internal.h0000644000000000000020000010024010517277132021305 0ustar rootbin/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. See the file doc/Tech.Notes for some information on the internals. Written by: Philip Hazel Copyright (c) 1997-2004 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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 header contains definitions that are shared between the different modules, but which are not relevant to the outside. */ /* Get the definitions provided by running "configure" */ #include "config.h" /* Standard C headers plus the external interface definition. The only time setjmp and stdarg are used is when NO_RECURSE is set. */ #include #include #include #include #include #include #include #include #ifndef PCRE_SPY #define PCRE_DEFINITION /* Win32 __declspec(export) trigger for .dll */ #endif /* We need to have types that specify unsigned 16-bit and 32-bit integers. We cannot determine these outside the compilation (e.g. by running a program as part of "configure") because PCRE is often cross-compiled for use on other systems. Instead we make use of the maximum sizes that are available at preprocessor time in standard C environments. */ #if USHRT_MAX == 65535 typedef unsigned short pcre_uint16; #elif UINT_MAX == 65535 typedef unsigned int pcre_uint16; #else #error Cannot determine a type for 16-bit unsigned integers #endif #if UINT_MAX == 4294967295 typedef unsigned int pcre_uint32; #elif ULONG_MAX == 4294967295 typedef unsigned long int pcre_uint32; #else #error Cannot determine a type for 32-bit unsigned integers #endif /* All character handling must be done as unsigned characters. Otherwise there are problems with top-bit-set characters and functions such as isspace(). However, we leave the interface to the outside world as char *, because that should make things easier for callers. We define a short type for unsigned char to save lots of typing. I tried "uchar", but it causes problems on Digital Unix, where it is defined in sys/types, so use "uschar" instead. */ typedef unsigned char uschar; /* Include the public PCRE header */ #include "pcre.h" /* When compiling for use with the Virtual Pascal compiler, these functions need to have their names changed. PCRE must be compiled with the -DVPCOMPAT option on the command line. */ #ifdef VPCOMPAT #define strncmp(s1,s2,m) _strncmp(s1,s2,m) #define memcpy(d,s,n) _memcpy(d,s,n) #define memmove(d,s,n) _memmove(d,s,n) #define memset(s,c,n) _memset(s,c,n) #else /* VPCOMPAT */ /* To cope with SunOS4 and other systems that lack memmove() but have bcopy(), define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY is set. Otherwise, include an emulating function for those systems that have neither (there some non-Unix environments where this is the case). This assumes that all calls to memmove are moving strings upwards in store, which is the case in PCRE. */ #if ! HAVE_MEMMOVE #undef memmove /* some systems may have a macro */ #if HAVE_BCOPY #define memmove(a, b, c) bcopy(b, a, c) #else /* HAVE_BCOPY */ void * pcre_memmove(unsigned char *dest, const unsigned char *src, size_t n) { int i; dest += n; src += n; for (i = 0; i < n; ++i) *(--dest) = *(--src); } #define memmove(a, b, c) pcre_memmove(a, b, c) #endif /* not HAVE_BCOPY */ #endif /* not HAVE_MEMMOVE */ #endif /* not VPCOMPAT */ /* PCRE keeps offsets in its compiled code as 2-byte quantities (always stored in big-endian order) by default. These are used, for example, to link from the start of a subpattern to its alternatives and its end. The use of 2 bytes per offset limits the size of the compiled regex to around 64K, which is big enough for almost everybody. However, I received a request for an even bigger limit. For this reason, and also to make the code easier to maintain, the storing and loading of offsets from the byte string is now handled by the macros that are defined here. The macros are controlled by the value of LINK_SIZE. This defaults to 2 in the config.h file, but can be overridden by using -D on the command line. This is automated on Unix systems via the "configure" command. */ #if LINK_SIZE == 2 #define PUT(a,n,d) \ (a[n] = (d) >> 8), \ (a[(n)+1] = (d) & 255) #define GET(a,n) \ (((a)[n] << 8) | (a)[(n)+1]) #define MAX_PATTERN_SIZE (1 << 16) #elif LINK_SIZE == 3 #define PUT(a,n,d) \ (a[n] = (d) >> 16), \ (a[(n)+1] = (d) >> 8), \ (a[(n)+2] = (d) & 255) #define GET(a,n) \ (((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2]) #define MAX_PATTERN_SIZE (1 << 24) #elif LINK_SIZE == 4 #define PUT(a,n,d) \ (a[n] = (d) >> 24), \ (a[(n)+1] = (d) >> 16), \ (a[(n)+2] = (d) >> 8), \ (a[(n)+3] = (d) & 255) #define GET(a,n) \ (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3]) #define MAX_PATTERN_SIZE (1 << 30) /* Keep it positive */ #else #error LINK_SIZE must be either 2, 3, or 4 #endif /* Convenience macro defined in terms of the others */ #define PUTINC(a,n,d) PUT(a,n,d), a += LINK_SIZE /* PCRE uses some other 2-byte quantities that do not change when the size of offsets changes. There are used for repeat counts and for other things such as capturing parenthesis numbers in back references. */ #define PUT2(a,n,d) \ a[n] = (d) >> 8; \ a[(n)+1] = (d) & 255 #define GET2(a,n) \ (((a)[n] << 8) | (a)[(n)+1]) #define PUT2INC(a,n,d) PUT2(a,n,d), a += 2 /* In case there is no definition of offsetof() provided - though any proper Standard C system should have one. */ #ifndef offsetof #define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field)) #endif /* These are the public options that can change during matching. */ #define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL) /* Private options flags start at the most significant end of the four bytes, but skip the top bit so we can use ints for convenience without getting tangled with negative values. The public options defined in pcre.h start at the least significant end. Make sure they don't overlap, though now that we have expanded to four bytes, there is plenty of space. */ #define PCRE_FIRSTSET 0x40000000 /* first_byte is set */ #define PCRE_REQCHSET 0x20000000 /* req_byte is set */ #define PCRE_STARTLINE 0x10000000 /* start after \n for multiline */ #define PCRE_ICHANGED 0x08000000 /* i option changes within regex */ #define PCRE_NOPARTIAL 0x04000000 /* can't use partial with this regex */ /* Options for the "extra" block produced by pcre_study(). */ #define PCRE_STUDY_MAPPED 0x01 /* a map of starting chars exists */ /* Masks for identifying the public options which are permitted at compile time, run time or study time, respectively. */ #define PUBLIC_OPTIONS \ (PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \ PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \ PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT) #define PUBLIC_EXEC_OPTIONS \ (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NO_UTF8_CHECK| \ PCRE_PARTIAL) #define PUBLIC_STUDY_OPTIONS 0 /* None defined */ /* Magic number to provide a small check against being handed junk. */ #define MAGIC_NUMBER 0x50435245UL /* 'PCRE' */ /* Negative values for the firstchar and reqchar variables */ #define REQ_UNSET (-2) #define REQ_NONE (-1) /* Flags added to firstbyte or reqbyte; a "non-literal" item is either a variable-length repeat, or a anything other than literal characters. */ #define REQ_CASELESS 0x0100 /* indicates caselessness */ #define REQ_VARY 0x0200 /* reqbyte followed non-literal item */ /* Miscellaneous definitions */ typedef int BOOL; #define FALSE 0 #define TRUE 1 /* Escape items that are just an encoding of a particular data value. Note that ESC_n is defined as yet another macro, which is set in config.h to either \n (the default) or \r (which some people want). */ #ifndef ESC_e #define ESC_e 27 #endif #ifndef ESC_f #define ESC_f '\f' #endif #ifndef ESC_n #define ESC_n NEWLINE #endif #ifndef ESC_r #define ESC_r '\r' #endif /* We can't officially use ESC_t because it is a POSIX reserved identifier (presumably because of all the others like size_t). */ #ifndef ESC_tee #define ESC_tee '\t' #endif /* These are escaped items that aren't just an encoding of a particular data value such as \n. They must have non-zero values, as check_escape() returns their negation. Also, they must appear in the same order as in the opcode definitions below, up to ESC_z. There's a dummy for OP_ANY because it corresponds to "." rather than an escape sequence. The final one must be ESC_REF as subsequent values are used for \1, \2, \3, etc. There is are two tests in the code for an escape greater than ESC_b and less than ESC_Z to detect the types that may be repeated. These are the types that consume characters. If any new escapes are put in between that don't consume a character, that code will have to change. */ enum { ESC_A = 1, ESC_G, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s, ESC_W, ESC_w, ESC_dum1, ESC_C, ESC_P, ESC_p, ESC_X, ESC_Z, ESC_z, ESC_E, ESC_Q, ESC_REF }; /* Flag bits and data types for the extended class (OP_XCLASS) for classes that contain UTF-8 characters with values greater than 255. */ #define XCL_NOT 0x01 /* Flag: this is a negative class */ #define XCL_MAP 0x02 /* Flag: a 32-byte map is present */ #define XCL_END 0 /* Marks end of individual items */ #define XCL_SINGLE 1 /* Single item (one multibyte char) follows */ #define XCL_RANGE 2 /* A range (two multibyte chars) follows */ #define XCL_PROP 3 /* Unicode property (one property code) follows */ #define XCL_NOTPROP 4 /* Unicode inverted property (ditto) */ /* Opcode table: OP_BRA must be last, as all values >= it are used for brackets that extract substrings. Starting from 1 (i.e. after OP_END), the values up to OP_EOD must correspond in order to the list of escapes immediately above. Note that whenever this list is updated, the two macro definitions that follow must also be updated to match. */ enum { OP_END, /* 0 End of pattern */ /* Values corresponding to backslashed metacharacters */ OP_SOD, /* 1 Start of data: \A */ OP_SOM, /* 2 Start of match (subject + offset): \G */ OP_NOT_WORD_BOUNDARY, /* 3 \B */ OP_WORD_BOUNDARY, /* 4 \b */ OP_NOT_DIGIT, /* 5 \D */ OP_DIGIT, /* 6 \d */ OP_NOT_WHITESPACE, /* 7 \S */ OP_WHITESPACE, /* 8 \s */ OP_NOT_WORDCHAR, /* 9 \W */ OP_WORDCHAR, /* 10 \w */ OP_ANY, /* 11 Match any character */ OP_ANYBYTE, /* 12 Match any byte (\C); different to OP_ANY for UTF-8 */ OP_NOTPROP, /* 13 \P (not Unicode property) */ OP_PROP, /* 14 \p (Unicode property) */ OP_EXTUNI, /* 15 \X (extended Unicode sequence */ OP_EODN, /* 16 End of data or \n at end of data: \Z. */ OP_EOD, /* 17 End of data: \z */ OP_OPT, /* 18 Set runtime options */ OP_CIRC, /* 19 Start of line - varies with multiline switch */ OP_DOLL, /* 20 End of line - varies with multiline switch */ OP_CHAR, /* 21 Match one character, casefully */ OP_CHARNC, /* 22 Match one character, caselessly */ OP_NOT, /* 23 Match anything but the following char */ OP_STAR, /* 24 The maximizing and minimizing versions of */ OP_MINSTAR, /* 25 all these opcodes must come in pairs, with */ OP_PLUS, /* 26 the minimizing one second. */ OP_MINPLUS, /* 27 This first set applies to single characters */ OP_QUERY, /* 28 */ OP_MINQUERY, /* 29 */ OP_UPTO, /* 30 From 0 to n matches */ OP_MINUPTO, /* 31 */ OP_EXACT, /* 32 Exactly n matches */ OP_NOTSTAR, /* 33 The maximizing and minimizing versions of */ OP_NOTMINSTAR, /* 34 all these opcodes must come in pairs, with */ OP_NOTPLUS, /* 35 the minimizing one second. */ OP_NOTMINPLUS, /* 36 This set applies to "not" single characters */ OP_NOTQUERY, /* 37 */ OP_NOTMINQUERY, /* 38 */ OP_NOTUPTO, /* 39 From 0 to n matches */ OP_NOTMINUPTO, /* 40 */ OP_NOTEXACT, /* 41 Exactly n matches */ OP_TYPESTAR, /* 42 The maximizing and minimizing versions of */ OP_TYPEMINSTAR, /* 43 all these opcodes must come in pairs, with */ OP_TYPEPLUS, /* 44 the minimizing one second. These codes must */ OP_TYPEMINPLUS, /* 45 be in exactly the same order as those above. */ OP_TYPEQUERY, /* 46 This set applies to character types such as \d */ OP_TYPEMINQUERY, /* 47 */ OP_TYPEUPTO, /* 48 From 0 to n matches */ OP_TYPEMINUPTO, /* 49 */ OP_TYPEEXACT, /* 50 Exactly n matches */ OP_CRSTAR, /* 51 The maximizing and minimizing versions of */ OP_CRMINSTAR, /* 52 all these opcodes must come in pairs, with */ OP_CRPLUS, /* 53 the minimizing one second. These codes must */ OP_CRMINPLUS, /* 54 be in exactly the same order as those above. */ OP_CRQUERY, /* 55 These are for character classes and back refs */ OP_CRMINQUERY, /* 56 */ OP_CRRANGE, /* 57 These are different to the three sets above. */ OP_CRMINRANGE, /* 58 */ OP_CLASS, /* 59 Match a character class, chars < 256 only */ OP_NCLASS, /* 60 Same, but the bitmap was created from a negative class - the difference is relevant only when a UTF-8 character > 255 is encountered. */ OP_XCLASS, /* 61 Extended class for handling UTF-8 chars within the class. This does both positive and negative. */ OP_REF, /* 62 Match a back reference */ OP_RECURSE, /* 63 Match a numbered subpattern (possibly recursive) */ OP_CALLOUT, /* 64 Call out to external function if provided */ OP_ALT, /* 65 Start of alternation */ OP_KET, /* 66 End of group that doesn't have an unbounded repeat */ OP_KETRMAX, /* 67 These two must remain together and in this */ OP_KETRMIN, /* 68 order. They are for groups the repeat for ever. */ /* The assertions must come before ONCE and COND */ OP_ASSERT, /* 69 Positive lookahead */ OP_ASSERT_NOT, /* 70 Negative lookahead */ OP_ASSERTBACK, /* 71 Positive lookbehind */ OP_ASSERTBACK_NOT, /* 72 Negative lookbehind */ OP_REVERSE, /* 73 Move pointer back - used in lookbehind assertions */ /* ONCE and COND must come after the assertions, with ONCE first, as there's a test for >= ONCE for a subpattern that isn't an assertion. */ OP_ONCE, /* 74 Once matched, don't back up into the subpattern */ OP_COND, /* 75 Conditional group */ OP_CREF, /* 76 Used to hold an extraction string number (cond ref) */ OP_BRAZERO, /* 77 These two must remain together and in this */ OP_BRAMINZERO, /* 78 order. */ OP_BRANUMBER, /* 79 Used for extracting brackets whose number is greater than can fit into an opcode. */ OP_BRA /* 80 This and greater values are used for brackets that extract substrings up to EXTRACT_BASIC_MAX. After that, use is made of OP_BRANUMBER. */ }; /* WARNING WARNING WARNING: There is an implicit assumption in pcre.c and study.c that all opcodes are less than 128 in value. This makes handling UTF-8 character sequences easier. */ /* The highest extraction number before we have to start using additional bytes. (Originally PCRE didn't have support for extraction counts highter than this number.) The value is limited by the number of opcodes left after OP_BRA, i.e. 255 - OP_BRA. We actually set it a bit lower to leave room for additional opcodes. */ #define EXTRACT_BASIC_MAX 100 /* This macro defines textual names for all the opcodes. There are used only for debugging, in pcre.c when DEBUG is defined, and also in pcretest.c. The macro is referenced only in printint.c. */ #define OP_NAME_LIST \ "End", "\\A", "\\G", "\\B", "\\b", "\\D", "\\d", \ "\\S", "\\s", "\\W", "\\w", "Any", "Anybyte", \ "notprop", "prop", "extuni", \ "\\Z", "\\z", \ "Opt", "^", "$", "char", "charnc", "not", \ "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ "*", "*?", "+", "+?", "?", "??", "{", "{", "{", \ "*", "*?", "+", "+?", "?", "??", "{", "{", \ "class", "nclass", "xclass", "Ref", "Recurse", "Callout", \ "Alt", "Ket", "KetRmax", "KetRmin", "Assert", "Assert not", \ "AssertB", "AssertB not", "Reverse", "Once", "Cond", "Cond ref",\ "Brazero", "Braminzero", "Branumber", "Bra" /* This macro defines the length of fixed length operations in the compiled regex. The lengths are used when searching for specific things, and also in the debugging printing of a compiled regex. We use a macro so that it can be incorporated both into pcre.c and pcretest.c without being publicly exposed. As things have been extended, some of these are no longer fixed lenths, but are minima instead. For example, the length of a single-character repeat may vary in UTF-8 mode. The code that uses this table must know about such things. */ #define OP_LENGTHS \ 1, /* End */ \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* \A, \G, \B, \B, \D, \d, \S, \s, \W, \w */ \ 1, 1, /* Any, Anybyte */ \ 2, 2, 1, /* NOTPROP, PROP, EXTUNI */ \ 1, 1, 2, 1, 1, /* \Z, \z, Opt, ^, $ */ \ 2, /* Char - the minimum length */ \ 2, /* Charnc - the minimum length */ \ 2, /* not */ \ /* Positive single-char repeats ** These are */ \ 2, 2, 2, 2, 2, 2, /* *, *?, +, +?, ?, ?? ** minima in */ \ 4, 4, 4, /* upto, minupto, exact ** UTF-8 mode */ \ /* Negative single-char repeats - only for chars < 256 */ \ 2, 2, 2, 2, 2, 2, /* NOT *, *?, +, +?, ?, ?? */ \ 4, 4, 4, /* NOT upto, minupto, exact */ \ /* Positive type repeats */ \ 2, 2, 2, 2, 2, 2, /* Type *, *?, +, +?, ?, ?? */ \ 4, 4, 4, /* Type upto, minupto, exact */ \ /* Character class & ref repeats */ \ 1, 1, 1, 1, 1, 1, /* *, *?, +, +?, ?, ?? */ \ 5, 5, /* CRRANGE, CRMINRANGE */ \ 33, /* CLASS */ \ 33, /* NCLASS */ \ 0, /* XCLASS - variable length */ \ 3, /* REF */ \ 1+LINK_SIZE, /* RECURSE */ \ 2+2*LINK_SIZE, /* CALLOUT */ \ 1+LINK_SIZE, /* Alt */ \ 1+LINK_SIZE, /* Ket */ \ 1+LINK_SIZE, /* KetRmax */ \ 1+LINK_SIZE, /* KetRmin */ \ 1+LINK_SIZE, /* Assert */ \ 1+LINK_SIZE, /* Assert not */ \ 1+LINK_SIZE, /* Assert behind */ \ 1+LINK_SIZE, /* Assert behind not */ \ 1+LINK_SIZE, /* Reverse */ \ 1+LINK_SIZE, /* Once */ \ 1+LINK_SIZE, /* COND */ \ 3, /* CREF */ \ 1, 1, /* BRAZERO, BRAMINZERO */ \ 3, /* BRANUMBER */ \ 1+LINK_SIZE /* BRA */ \ /* A magic value for OP_CREF to indicate the "in recursion" condition. */ #define CREF_RECURSE 0xffff /* The texts of compile-time error messages are defined as macros here so that they can be accessed by the POSIX wrapper and converted into error codes. Yes, I could have used error codes in the first place, but didn't feel like changing just to accommodate the POSIX wrapper. */ #define ERR1 "\\ at end of pattern" #define ERR2 "\\c at end of pattern" #define ERR3 "unrecognized character follows \\" #define ERR4 "numbers out of order in {} quantifier" #define ERR5 "number too big in {} quantifier" #define ERR6 "missing terminating ] for character class" #define ERR7 "invalid escape sequence in character class" #define ERR8 "range out of order in character class" #define ERR9 "nothing to repeat" #define ERR10 "operand of unlimited repeat could match the empty string" #define ERR11 "internal error: unexpected repeat" #define ERR12 "unrecognized character after (?" #define ERR13 "POSIX named classes are supported only within a class" #define ERR14 "missing )" #define ERR15 "reference to non-existent subpattern" #define ERR16 "erroffset passed as NULL" #define ERR17 "unknown option bit(s) set" #define ERR18 "missing ) after comment" #define ERR19 "parentheses nested too deeply" #define ERR20 "regular expression too large" #define ERR21 "failed to get memory" #define ERR22 "unmatched parentheses" #define ERR23 "internal error: code overflow" #define ERR24 "unrecognized character after (?<" #define ERR25 "lookbehind assertion is not fixed length" #define ERR26 "malformed number after (?(" #define ERR27 "conditional group contains more than two branches" #define ERR28 "assertion expected after (?(" #define ERR29 "(?R or (?digits must be followed by )" #define ERR30 "unknown POSIX class name" #define ERR31 "POSIX collating elements are not supported" #define ERR32 "this version of PCRE is not compiled with PCRE_UTF8 support" #define ERR33 "spare error" #define ERR34 "character value in \\x{...} sequence is too large" #define ERR35 "invalid condition (?(0)" #define ERR36 "\\C not allowed in lookbehind assertion" #define ERR37 "PCRE does not support \\L, \\l, \\N, \\U, or \\u" #define ERR38 "number after (?C is > 255" #define ERR39 "closing ) for (?C expected" #define ERR40 "recursive call could loop indefinitely" #define ERR41 "unrecognized character after (?P" #define ERR42 "syntax error after (?P" #define ERR43 "two named groups have the same name" #define ERR44 "invalid UTF-8 string" #define ERR45 "support for \\P, \\p, and \\X has not been compiled" #define ERR46 "malformed \\P or \\p sequence" #define ERR47 "unknown property name after \\P or \\p" /* The real format of the start of the pcre block; the index of names and the code vector run on as long as necessary after the end. We store an explicit offset to the name table so that if a regex is compiled on one host, saved, and then run on another where the size of pointers is different, all might still be well. For the case of compiled-on-4 and run-on-8, we include an extra pointer that is always NULL. For future-proofing, we also include a few dummy fields - even though you can never get this planning right! NOTE NOTE NOTE: Because people can now save and re-use compiled patterns, any additions to this structure should be made at the end, and something earlier (e.g. a new flag in the options or one of the dummy fields) should indicate that the new fields are present. Currently PCRE always sets the dummy fields to zero. NOTE NOTE NOTE: */ typedef struct real_pcre { pcre_uint32 magic_number; pcre_uint32 size; /* Total that was malloced */ pcre_uint32 options; pcre_uint32 dummy1; /* For future use, maybe */ pcre_uint16 top_bracket; pcre_uint16 top_backref; pcre_uint16 first_byte; pcre_uint16 req_byte; pcre_uint16 name_table_offset; /* Offset to name table that follows */ pcre_uint16 name_entry_size; /* Size of any name items */ pcre_uint16 name_count; /* Number of name items */ pcre_uint16 dummy2; /* For future use, maybe */ const unsigned char *tables; /* Pointer to tables or NULL for std */ const unsigned char *nullpad; /* NULL padding */ } real_pcre; /* The format of the block used to store data from pcre_study(). The same remark (see NOTE above) about extending this structure applies. */ typedef struct pcre_study_data { pcre_uint32 size; /* Total that was malloced */ pcre_uint32 options; uschar start_bits[32]; } pcre_study_data; /* Structure for passing "static" information around between the functions doing the compiling, so that they are thread-safe. */ typedef struct compile_data { const uschar *lcc; /* Points to lower casing table */ const uschar *fcc; /* Points to case-flipping table */ const uschar *cbits; /* Points to character type table */ const uschar *ctypes; /* Points to table of type maps */ const uschar *start_code; /* The start of the compiled code */ const uschar *start_pattern; /* The start of the pattern */ uschar *name_table; /* The name/number table */ int names_found; /* Number of entries so far */ int name_entry_size; /* Size of each entry */ int top_backref; /* Maximum back reference */ unsigned int backref_map; /* Bitmap of low back refs */ int req_varyopt; /* "After variable item" flag for reqbyte */ BOOL nopartial; /* Set TRUE if partial won't work */ } compile_data; /* Structure for maintaining a chain of pointers to the currently incomplete branches, for testing for left recursion. */ typedef struct branch_chain { struct branch_chain *outer; uschar *current; } branch_chain; /* Structure for items in a linked list that represents an explicit recursive call within the pattern. */ typedef struct recursion_info { struct recursion_info *prevrec; /* Previous recursion record (or NULL) */ int group_num; /* Number of group that was called */ const uschar *after_call; /* "Return value": points after the call in the expr */ const uschar *save_start; /* Old value of md->start_match */ int *offset_save; /* Pointer to start of saved offsets */ int saved_max; /* Number of saved offsets */ } recursion_info; /* When compiling in a mode that doesn't use recursive calls to match(), a structure is used to remember local variables on the heap. It is defined in pcre.c, close to the match() function, so that it is easy to keep it in step with any changes of local variable. However, the pointer to the current frame must be saved in some "static" place over a longjmp(). We declare the structure here so that we can put a pointer in the match_data structure. NOTE: This isn't used for a "normal" compilation of pcre. */ struct heapframe; /* Structure for passing "static" information around between the functions doing the matching, so that they are thread-safe. */ typedef struct match_data { unsigned long int match_call_count; /* As it says */ unsigned long int match_limit;/* As it says */ int *offset_vector; /* Offset vector */ int offset_end; /* One past the end */ int offset_max; /* The maximum usable for return data */ const uschar *lcc; /* Points to lower casing table */ const uschar *ctypes; /* Points to table of type maps */ BOOL offset_overflow; /* Set if too many extractions */ BOOL notbol; /* NOTBOL flag */ BOOL noteol; /* NOTEOL flag */ BOOL utf8; /* UTF8 flag */ BOOL endonly; /* Dollar not before final \n */ BOOL notempty; /* Empty string match not wanted */ BOOL partial; /* PARTIAL flag */ BOOL hitend; /* Hit the end of the subject at some point */ const uschar *start_code; /* For use when recursing */ const uschar *start_subject; /* Start of the subject string */ const uschar *end_subject; /* End of the subject string */ const uschar *start_match; /* Start of this match attempt */ const uschar *end_match_ptr; /* Subject position at end match */ int end_offset_top; /* Highwater mark at end of match */ int capture_last; /* Most recent capture number */ int start_offset; /* The start offset value */ recursion_info *recursive; /* Linked list of recursion data */ void *callout_data; /* To pass back to callouts */ struct heapframe *thisframe; /* Used only when compiling for no recursion */ } match_data; /* Bit definitions for entries in the pcre_ctypes table. */ #define ctype_space 0x01 #define ctype_letter 0x02 #define ctype_digit 0x04 #define ctype_xdigit 0x08 #define ctype_word 0x10 /* alphameric or '_' */ #define ctype_meta 0x80 /* regexp meta char or zero (end pattern) */ /* Offsets for the bitmap tables in pcre_cbits. Each table contains a set of bits for a class map. Some classes are built by combining these tables. */ #define cbit_space 0 /* [:space:] or \s */ #define cbit_xdigit 32 /* [:xdigit:] */ #define cbit_digit 64 /* [:digit:] or \d */ #define cbit_upper 96 /* [:upper:] */ #define cbit_lower 128 /* [:lower:] */ #define cbit_word 160 /* [:word:] or \w */ #define cbit_graph 192 /* [:graph:] */ #define cbit_print 224 /* [:print:] */ #define cbit_punct 256 /* [:punct:] */ #define cbit_cntrl 288 /* [:cntrl:] */ #define cbit_length 320 /* Length of the cbits table */ /* Offsets of the various tables from the base tables pointer, and total length. */ #define lcc_offset 0 #define fcc_offset 256 #define cbits_offset 512 #define ctypes_offset (cbits_offset + cbit_length) #define tables_length (ctypes_offset + 256) /* End of internal.h */ tomcat-connectors-1.2.41-src/native/iis/pcre/INSTALL0000644000000000000020000001756110517277132020366 0ustar rootbinBasic Installation ================== These are generic installation instructions that apply to systems that can run the `configure' shell script - Unix systems and any that imitate it. They are not specific to PCRE. There are PCRE-specific instructions for non-Unix systems in the file NON-UNIX-USE. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. tomcat-connectors-1.2.41-src/native/iis/pcre/maketables.c0000644000000000000020000001206510517277132021603 0ustar rootbin/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by: Philip Hazel Copyright (c) 1997-2003 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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 file is compiled on its own as part of the PCRE library. However, it is also included in the compilation of dftables.c, in which case the macro DFTABLES is defined. */ #ifndef DFTABLES #include "internal.h" #endif /************************************************* * Create PCRE character tables * *************************************************/ /* This function builds a set of character tables for use by PCRE and returns a pointer to them. They are build using the ctype functions, and consequently their contents will depend upon the current locale setting. When compiled as part of the library, the store is obtained via pcre_malloc(), but when compiled inside dftables, use malloc(). Arguments: none Returns: pointer to the contiguous block of data */ const unsigned char * pcre_maketables(void) { unsigned char *yield, *p; int i; #ifndef DFTABLES yield = (unsigned char*)(pcre_malloc)(tables_length); #else yield = (unsigned char*)malloc(tables_length); #endif if (yield == NULL) return NULL; p = yield; /* First comes the lower casing table */ for (i = 0; i < 256; i++) *p++ = tolower(i); /* Next the case-flipping table */ for (i = 0; i < 256; i++) *p++ = islower(i)? toupper(i) : tolower(i); /* Then the character class tables. Don't try to be clever and save effort on exclusive ones - in some locales things may be different. Note that the table for "space" includes everything "isspace" gives, including VT in the default locale. This makes it work for the POSIX class [:space:]. */ memset(p, 0, cbit_length); for (i = 0; i < 256; i++) { if (isdigit(i)) { p[cbit_digit + i/8] |= 1 << (i&7); p[cbit_word + i/8] |= 1 << (i&7); } if (isupper(i)) { p[cbit_upper + i/8] |= 1 << (i&7); p[cbit_word + i/8] |= 1 << (i&7); } if (islower(i)) { p[cbit_lower + i/8] |= 1 << (i&7); p[cbit_word + i/8] |= 1 << (i&7); } if (i == '_') p[cbit_word + i/8] |= 1 << (i&7); if (isspace(i)) p[cbit_space + i/8] |= 1 << (i&7); if (isxdigit(i))p[cbit_xdigit + i/8] |= 1 << (i&7); if (isgraph(i)) p[cbit_graph + i/8] |= 1 << (i&7); if (isprint(i)) p[cbit_print + i/8] |= 1 << (i&7); if (ispunct(i)) p[cbit_punct + i/8] |= 1 << (i&7); if (iscntrl(i)) p[cbit_cntrl + i/8] |= 1 << (i&7); } p += cbit_length; /* Finally, the character type table. In this, we exclude VT from the white space chars, because Perl doesn't recognize it as such for \s and for comments within regexes. */ for (i = 0; i < 256; i++) { int x = 0; if (i != 0x0b && isspace(i)) x += ctype_space; if (isalpha(i)) x += ctype_letter; if (isdigit(i)) x += ctype_digit; if (isxdigit(i)) x += ctype_xdigit; if (isalnum(i) || i == '_') x += ctype_word; /* Note: strchr includes the terminating zero in the characters it considers. In this instance, that is ok because we want binary zero to be flagged as a meta-character, which in this sense is any character that terminates a run of data characters. */ if (strchr("*+?{^.$|()[", i) != 0) x += ctype_meta; *p++ = x; } return yield; } /* End of maketables.c */ tomcat-connectors-1.2.41-src/native/iis/pcre/COPYING0000644000000000000020000000402310517277132020355 0ustar rootbinPCRE LICENCE ------------ PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Release 5 of PCRE is distributed under the terms of the "BSD" licence, as specified below. The documentation for PCRE, supplied in the "doc" directory, is distributed under the same terms as the software itself. Written by: Philip Hazel University of Cambridge Computing Service, Cambridge, England. Phone: +44 1223 334714. Copyright (c) 1997-2004 University of Cambridge All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. End tomcat-connectors-1.2.41-src/native/iis/pcre/printint.c0000644000000000000020000003072210517277132021342 0ustar rootbin/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. See the file Tech.Notes for some information on the internals. Written by: Philip Hazel Copyright (c) 1997-2004 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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 module contains a debugging function for printing out the internal form of a compiled regular expression. It is kept in a separate file so that it can be #included both in the pcretest program, and in the library itself when compiled with the debugging switch. */ static const char *OP_names[] = { OP_NAME_LIST }; /************************************************* * Print single- or multi-byte character * *************************************************/ /* These tables are actually copies of ones in pcre.c. If we compile the library with debugging, they are included twice, but that isn't really a problem - compiling with debugging is pretty rare and these are very small. */ static const int utf8_t3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; static const uschar utf8_t4[] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; static int print_char(FILE *f, uschar *ptr, BOOL utf8) { int c = *ptr; if (!utf8 || (c & 0xc0) != 0xc0) { if (isprint(c)) fprintf(f, "%c", c); else fprintf(f, "\\x%02x", c); return 0; } else { int i; int a = utf8_t4[c & 0x3f]; /* Number of additional bytes */ int s = 6*a; c = (c & utf8_t3[a]) << s; for (i = 1; i <= a; i++) { /* This is a check for malformed UTF-8; it should only occur if the sanity check has been turned off. Rather than swallow random bytes, just stop if we hit a bad one. Print it with \X instead of \x as an indication. */ if ((ptr[i] & 0xc0) != 0x80) { fprintf(f, "\\X{%x}", c); return i - 1; } /* The byte is OK */ s -= 6; c |= (ptr[i] & 0x3f) << s; } if (c < 128) fprintf(f, "\\x%02x", c); else fprintf(f, "\\x{%x}", c); return a; } } #ifdef SUPPORT_UCP /************************************************* * Find Unicode property name * *************************************************/ static const char * get_ucpname(int property) { int i; for (i = sizeof(utt)/sizeof(ucp_type_table); i >= 0; i--) { if (property == utt[i].value) break; } return (i >= 0)? utt[i].name : "??"; } #endif /* SUPPORT_UCP */ /************************************************* * Print compiled regex * *************************************************/ /* Make this function work for a regex with integers either byte order. However, we assume that what we are passed is a compiled regex. */ static void print_internals(pcre *external_re, FILE *f) { real_pcre *re = (real_pcre *)external_re; uschar *codestart, *code; BOOL utf8; unsigned int options = re->options; int offset = re->name_table_offset; int count = re->name_count; int size = re->name_entry_size; if (re->magic_number != MAGIC_NUMBER) { offset = ((offset << 8) & 0xff00) | ((offset >> 8) & 0xff); count = ((count << 8) & 0xff00) | ((count >> 8) & 0xff); size = ((size << 8) & 0xff00) | ((size >> 8) & 0xff); options = ((options << 24) & 0xff000000) | ((options << 8) & 0x00ff0000) | ((options >> 8) & 0x0000ff00) | ((options >> 24) & 0x000000ff); } code = codestart = (uschar *)re + offset + count * size; utf8 = (options & PCRE_UTF8) != 0; for(;;) { uschar *ccode; int c; int extra = 0; fprintf(f, "%3d ", code - codestart); if (*code >= OP_BRA) { if (*code - OP_BRA > EXTRACT_BASIC_MAX) fprintf(f, "%3d Bra extra\n", GET(code, 1)); else fprintf(f, "%3d Bra %d\n", GET(code, 1), *code - OP_BRA); code += OP_lengths[OP_BRA]; continue; } switch(*code) { case OP_END: fprintf(f, " %s\n", OP_names[*code]); fprintf(f, "------------------------------------------------------------------\n"); return; case OP_OPT: fprintf(f, " %.2x %s", code[1], OP_names[*code]); break; case OP_CHAR: { fprintf(f, " "); do { code++; code += 1 + print_char(f, code, utf8); } while (*code == OP_CHAR); fprintf(f, "\n"); continue; } break; case OP_CHARNC: { fprintf(f, " NC "); do { code++; code += 1 + print_char(f, code, utf8); } while (*code == OP_CHARNC); fprintf(f, "\n"); continue; } break; case OP_KETRMAX: case OP_KETRMIN: case OP_ALT: case OP_KET: case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: case OP_ONCE: case OP_COND: case OP_REVERSE: fprintf(f, "%3d %s", GET(code, 1), OP_names[*code]); break; case OP_BRANUMBER: printf("%3d %s", GET2(code, 1), OP_names[*code]); break; case OP_CREF: if (GET2(code, 1) == CREF_RECURSE) fprintf(f, " Cond recurse"); else fprintf(f, "%3d %s", GET2(code,1), OP_names[*code]); break; case OP_STAR: case OP_MINSTAR: case OP_PLUS: case OP_MINPLUS: case OP_QUERY: case OP_MINQUERY: case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEQUERY: case OP_TYPEMINQUERY: fprintf(f, " "); if (*code >= OP_TYPESTAR) { fprintf(f, "%s", OP_names[code[1]]); #ifdef SUPPORT_UCP if (code[1] == OP_PROP || code[1] == OP_NOTPROP) { fprintf(f, " %s ", get_ucpname(code[2])); extra = 1; } #endif } else extra = print_char(f, code+1, utf8); fprintf(f, "%s", OP_names[*code]); break; case OP_EXACT: case OP_UPTO: case OP_MINUPTO: fprintf(f, " "); extra = print_char(f, code+3, utf8); fprintf(f, "{"); if (*code != OP_EXACT) fprintf(f, ","); fprintf(f, "%d}", GET2(code,1)); if (*code == OP_MINUPTO) fprintf(f, "?"); break; case OP_TYPEEXACT: case OP_TYPEUPTO: case OP_TYPEMINUPTO: fprintf(f, " %s", OP_names[code[3]]); #ifdef SUPPORT_UCP if (code[3] == OP_PROP || code[3] == OP_NOTPROP) { fprintf(f, " %s ", get_ucpname(code[4])); extra = 1; } #endif fprintf(f, "{"); if (*code != OP_TYPEEXACT) fprintf(f, "0,"); fprintf(f, "%d}", GET2(code,1)); if (*code == OP_TYPEMINUPTO) fprintf(f, "?"); break; case OP_NOT: if (isprint(c = code[1])) fprintf(f, " [^%c]", c); else fprintf(f, " [^\\x%02x]", c); break; case OP_NOTSTAR: case OP_NOTMINSTAR: case OP_NOTPLUS: case OP_NOTMINPLUS: case OP_NOTQUERY: case OP_NOTMINQUERY: if (isprint(c = code[1])) fprintf(f, " [^%c]", c); else fprintf(f, " [^\\x%02x]", c); fprintf(f, "%s", OP_names[*code]); break; case OP_NOTEXACT: case OP_NOTUPTO: case OP_NOTMINUPTO: if (isprint(c = code[3])) fprintf(f, " [^%c]{", c); else fprintf(f, " [^\\x%02x]{", c); if (*code != OP_NOTEXACT) fprintf(f, ","); fprintf(f, "%d}", GET2(code,1)); if (*code == OP_NOTMINUPTO) fprintf(f, "?"); break; case OP_RECURSE: fprintf(f, "%3d %s", GET(code, 1), OP_names[*code]); break; case OP_REF: fprintf(f, " \\%d", GET2(code,1)); ccode = code + OP_lengths[*code]; goto CLASS_REF_REPEAT; case OP_CALLOUT: fprintf(f, " %s %d %d %d", OP_names[*code], code[1], GET(code,2), GET(code, 2 + LINK_SIZE)); break; #ifdef SUPPORT_UCP case OP_PROP: case OP_NOTPROP: fprintf(f, " %s %s", OP_names[*code], get_ucpname(code[1])); break; #endif /* OP_XCLASS can only occur in UTF-8 mode. However, there's no harm in having this code always here, and it makes it less messy without all those #ifdefs. */ case OP_CLASS: case OP_NCLASS: case OP_XCLASS: { int i, min, max; BOOL printmap; fprintf(f, " ["); if (*code == OP_XCLASS) { extra = GET(code, 1); ccode = code + LINK_SIZE + 1; printmap = (*ccode & XCL_MAP) != 0; if ((*ccode++ & XCL_NOT) != 0) fprintf(f, "^"); } else { printmap = TRUE; ccode = code + 1; } /* Print a bit map */ if (printmap) { for (i = 0; i < 256; i++) { if ((ccode[i/8] & (1 << (i&7))) != 0) { int j; for (j = i+1; j < 256; j++) if ((ccode[j/8] & (1 << (j&7))) == 0) break; if (i == '-' || i == ']') fprintf(f, "\\"); if (isprint(i)) fprintf(f, "%c", i); else fprintf(f, "\\x%02x", i); if (--j > i) { if (j != i + 1) fprintf(f, "-"); if (j == '-' || j == ']') fprintf(f, "\\"); if (isprint(j)) fprintf(f, "%c", j); else fprintf(f, "\\x%02x", j); } i = j; } } ccode += 32; } /* For an XCLASS there is always some additional data */ if (*code == OP_XCLASS) { int ch; while ((ch = *ccode++) != XCL_END) { #ifdef SUPPORT_UCP if (ch == XCL_PROP) { fprintf(f, "\\p{%s}", get_ucpname(*ccode++)); } else if (ch == XCL_NOTPROP) { fprintf(f, "\\P{%s}", get_ucpname(*ccode++)); } else #endif { ccode += 1 + print_char(f, ccode, TRUE); if (ch == XCL_RANGE) { fprintf(f, "-"); ccode += 1 + print_char(f, ccode, TRUE); } } } } /* Indicate a non-UTF8 class which was created by negation */ fprintf(f, "]%s", (*code == OP_NCLASS)? " (neg)" : ""); /* Handle repeats after a class or a back reference */ CLASS_REF_REPEAT: switch(*ccode) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRPLUS: case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: fprintf(f, "%s", OP_names[*ccode]); extra += OP_lengths[*ccode]; break; case OP_CRRANGE: case OP_CRMINRANGE: min = GET2(ccode,1); max = GET2(ccode,3); if (max == 0) fprintf(f, "{%d,}", min); else fprintf(f, "{%d,%d}", min, max); if (*ccode == OP_CRMINRANGE) fprintf(f, "?"); extra += OP_lengths[*ccode]; break; } } break; /* Anything else is just an item with no data*/ default: fprintf(f, " %s", OP_names[*code]); break; } code += OP_lengths[*code] + extra; fprintf(f, "\n"); } } /* End of printint.c */ tomcat-connectors-1.2.41-src/native/iis/pcre/libpcre.def0000644000000000000020000000205711446407632021431 0ustar rootbin; Licensed to the Apache Software Foundation (ASF) under one or more ; contributor license agreements. See the NOTICE file distributed with ; this work for additional information regarding copyright ownership. ; The ASF licenses this file to You under the Apache License, Version 2.0 ; (the "License"); you may not use this file except in compliance with ; the License. You may obtain a copy of the License at ; ; http://www.apache.org/licenses/LICENSE-2.0 ; ; Unless required by applicable law or agreed to in writing, software ; distributed under the License is distributed on an "AS IS" BASIS, ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; See the License for the specific language governing permissions and ; limitations under the License. ; LIBRARY libpcre EXPORTS pcre_malloc pcre_free pcre_config pcre_callout pcre_compile pcre_copy_substring pcre_exec pcre_get_substring pcre_get_stringnumber pcre_get_substring_list pcre_free_substring pcre_free_substring_list pcre_info pcre_fullinfo pcre_maketables pcre_study pcre_version tomcat-connectors-1.2.41-src/native/iis/pcre/perltest0000755000000000000020000001216210517277132021115 0ustar rootbin#! /usr/bin/perl # Program for testing regular expressions with perl to check that PCRE handles # them the same. This is the version that supports /8 for UTF-8 testing. As it # stands, it requires at least Perl 5.8 for UTF-8 support. For Perl 5.6, it # can be used as is for non-UTF-8 testing, but you have to uncomment the # "use utf8" lines in order to to UTF-8 stuff (and you mustn't uncomment them # for non-UTF-8 use). # Function for turning a string into a string of printing chars. There are # currently problems with UTF-8 strings; this fudges round them. sub pchars { my($t) = ""; if ($utf8) { # use utf8; <=============== For UTF-8 in Perl 5.6 @p = unpack('U*', $_[0]); foreach $c (@p) { if ($c >= 32 && $c < 127) { $t .= chr $c; } else { $t .= sprintf("\\x{%02x}", $c); } } } else { foreach $c (split(//, $_[0])) { if (ord $c >= 32 && ord $c < 127) { $t .= $c; } else { $t .= sprintf("\\x%02x", ord $c); } } } $t; } # Read lines from named file or stdin and write to named file or stdout; lines # consist of a regular expression, in delimiters and optionally followed by # options, followed by a set of test data, terminated by an empty line. # Sort out the input and output files if (@ARGV > 0) { open(INFILE, "<$ARGV[0]") || die "Failed to open $ARGV[0]\n"; $infile = "INFILE"; } else { $infile = "STDIN"; } if (@ARGV > 1) { open(OUTFILE, ">$ARGV[1]") || die "Failed to open $ARGV[1]\n"; $outfile = "OUTFILE"; } else { $outfile = "STDOUT"; } printf($outfile "Perl $] Regular Expressions\n\n"); # Main loop NEXT_RE: for (;;) { printf " re> " if $infile eq "STDIN"; last if ! ($_ = <$infile>); printf $outfile "$_" if $infile ne "STDIN"; next if ($_ eq ""); $pattern = $_; while ($pattern !~ /^\s*(.).*\1/s) { printf " > " if $infile eq "STDIN"; last if ! ($_ = <$infile>); printf $outfile "$_" if $infile ne "STDIN"; $pattern .= $_; } chomp($pattern); $pattern =~ s/\s+$//; # The private /+ modifier means "print $' afterwards". $showrest = ($pattern =~ s/\+(?=[a-z]*$)//); # The private /8 modifier means "operate in UTF-8". Currently, Perl # has bugs that we try to work around using this flag. $utf8 = ($pattern =~ s/8(?=[a-z]*$)//); # Check that the pattern is valid if ($utf8) { # use utf8; <=============== For UTF-8 in Perl 5.6 eval "\$_ =~ ${pattern}"; } else { eval "\$_ =~ ${pattern}"; } if ($@) { printf $outfile "Error: $@"; next NEXT_RE; } # If the /g modifier is present, we want to put a loop round the matching; # otherwise just a single "if". $cmd = ($pattern =~ /g[a-z]*$/)? "while" : "if"; # If the pattern is actually the null string, Perl uses the most recently # executed (and successfully compiled) regex is used instead. This is a # nasty trap for the unwary! The PCRE test suite does contain null strings # in places - if they are allowed through here all sorts of weird and # unexpected effects happen. To avoid this, we replace such patterns with # a non-null pattern that has the same effect. $pattern = "/(?#)/$2" if ($pattern =~ /^(.)\1(.*)$/); # Read data lines and test them for (;;) { printf "data> " if $infile eq "STDIN"; last NEXT_RE if ! ($_ = <$infile>); chomp; printf $outfile "$_\n" if $infile ne "STDIN"; s/\s+$//; s/^\s+//; last if ($_ eq ""); $x = eval "\"$_\""; # To get escapes processed # Empty array for holding results, then do the matching. @subs = (); $pushes = "push \@subs,\$&;" . "push \@subs,\$1;" . "push \@subs,\$2;" . "push \@subs,\$3;" . "push \@subs,\$4;" . "push \@subs,\$5;" . "push \@subs,\$6;" . "push \@subs,\$7;" . "push \@subs,\$8;" . "push \@subs,\$9;" . "push \@subs,\$10;" . "push \@subs,\$11;" . "push \@subs,\$12;" . "push \@subs,\$13;" . "push \@subs,\$14;" . "push \@subs,\$15;" . "push \@subs,\$16;" . "push \@subs,\$'; }"; if ($utf8) { # use utf8; <=============== For UTF-8 in Perl 5.6 eval "${cmd} (\$x =~ ${pattern}) {" . $pushes; } else { eval "${cmd} (\$x =~ ${pattern}) {" . $pushes; } if ($@) { printf $outfile "Error: $@\n"; next NEXT_RE; } elsif (scalar(@subs) == 0) { printf $outfile "No match\n"; } else { while (scalar(@subs) != 0) { printf $outfile (" 0: %s\n", &pchars($subs[0])); printf $outfile (" 0+ %s\n", &pchars($subs[17])) if $showrest; $last_printed = 0; for ($i = 1; $i <= 16; $i++) { if (defined $subs[$i]) { while ($last_printed++ < $i-1) { printf $outfile ("%2d: \n", $last_printed); } printf $outfile ("%2d: %s\n", $i, &pchars($subs[$i])); $last_printed = $i; } } splice(@subs, 0, 18); } } } } # printf $outfile "\n"; # End tomcat-connectors-1.2.41-src/native/iis/pcre/NWGNUmakefile0000644000000000000020000001111110517277132021635 0ustar rootbin# # NWGNUmakefile for DfTables.nlm (Apache2) # Declare the sub-directories to be built here # SUBDIRS = \ $(EOLIST) # # Get the 'head' of the build environment. This includes default targets and # paths to tools # include $(APR_WORK)\build\NWGNUhead.inc PCRE = $(AP_WORK)/srclib/pcre # # build this level's files FILES_prebuild_headers = \ $(PCRE)/config.h \ $(PCRE)/pcre.h \ $(EOLIST) $(PCRE)/%.h: $(subst /,\,$(PCRE))\%.hw @echo Creating $(subst /,\,$@) copy $< $(subst /,\,$(PCRE))\$(@F) # # Make sure all needed macro's are defined # # # These directories will be at the beginning of the include list, followed by # INCDIRS # XINCDIRS += \ $(AP_WORK)/os/netware \ $(APR)/include/arch/netware \ $(EOLIST) # # These flags will come after CFLAGS # XCFLAGS += \ $(EOLIST) # # These defines will come after DEFINES # XDEFINES += \ $(EOLIST) # # These flags will be added to the link.opt file # XLFLAGS += \ $(EOLIST) # # These values will be appended to the correct variables based on the value of # RELEASE # ifeq "$(RELEASE)" "debug" XINCDIRS += \ $(EOLIST) XCFLAGS += \ $(EOLIST) XDEFINES += \ $(EOLIST) XLFLAGS += \ $(EOLIST) endif ifeq "$(RELEASE)" "noopt" XINCDIRS += \ $(EOLIST) XCFLAGS += \ $(EOLIST) XDEFINES += \ $(EOLIST) XLFLAGS += \ $(EOLIST) endif ifeq "$(RELEASE)" "release" XINCDIRS += \ $(EOLIST) XCFLAGS += \ $(EOLIST) XDEFINES += \ $(EOLIST) XLFLAGS += \ $(EOLIST) endif # # These are used by the link target if an NLM is being generated # This is used by the link 'name' directive to name the nlm. If left blank # TARGET_nlm (see below) will be used. # NLM_NAME = dftables # # This is used by the link '-desc ' directive. # If left blank, NLM_NAME will be used. # NLM_DESCRIPTION = Generate character tables #$(FILES_prebuild_headers) # This is used by the '-threadname' directive. If left blank, # NLM_NAME Thread will be used. # NLM_THREAD_NAME = dftables # # If this is specified, it will override VERSION value in # $(APR_WORK)\build\NWGNUenvironment.inc # NLM_VERSION = 1,0,0 # # If this is specified, it will override the default of 64K # NLM_STACK_SIZE = 8192 # # If this is specified it will be used by the link '-entry' directive # NLM_ENTRY_SYM =_LibCPrelude # # If this is specified it will be used by the link '-exit' directive # NLM_EXIT_SYM =_LibCPostlude # # If this is specified it will be used by the link '-check' directive # NLM_CHECK_SYM = # # If this is specified it will be used by the link '-flags' directive # NLM_FLAGS = PSEUDOPREEMPTION # # If this is specified it will be linked in with the XDCData option in the def # file instead of the default of $(APR)/misc/netware/apr.xdc. XDCData can # be disabled by setting APACHE_UNIPROC in the environment # XDCDATA = # # Declare all target files (you must add your files here) # # # If there is an NLM target, put it here # TARGET_nlm = \ $(OBJDIR)/dftables.nlm \ $(EOLIST) # # If there is an LIB target, put it here # TARGET_lib = \ $(EOLIST) # # These are the OBJ files needed to create the NLM target above. # Paths must all use the '/' character # FILES_nlm_objs = \ $(FILES_prebuild_headers) \ $(OBJDIR)/dftables.o \ $(EOLIST) # # These are the LIB files needed to create the NLM target above. # These will be added as a library command in the link.opt file. # FILES_nlm_libs = \ libcpre.o \ $(EOLIST) # # These are the modules that the above NLM target depends on to load. # These will be added as a module command in the link.opt file. # FILES_nlm_modules = \ Libc \ $(EOLIST) # # If the nlm has a msg file, put it's path here # FILE_nlm_msg = # # If the nlm has a hlp file put it's path here # FILE_nlm_hlp = # # If this is specified, it will override $(NWOS)\copyright.txt. # FILE_nlm_copyright = # # Any additional imports go here # FILES_nlm_Ximports = \ @libc.imp \ $(EOLIST) # # Any symbols exported to here # FILES_nlm_exports = \ $(EOLIST) # # These are the OBJ files needed to create the LIB target above. # Paths must all use the '/' character # FILES_lib_objs = \ $(EOLIST) # # implement targets and dependancies (leave this section alone) # libs :: $(OBJDIR) $(TARGET_lib) nlms :: libs $(TARGET_nlm) # # Updated this target to create necessary directories and copy files to the # correct place. (See $(APR_WORK)\build\NWGNUhead.inc for examples) # install :: nlms FORCE # # Any specialized rules here # # # Include the 'tail' makefile that has targets that depend on variables defined # in this makefile # include $(APR_WORK)\build\NWGNUtail.inc # End of NWGNUmakefile for DfTables.nlm (Apache2) tomcat-connectors-1.2.41-src/native/iis/pcre/AUTHORS0000644000000000000020000000026310517277132020374 0ustar rootbinWritten by: Philip Hazel University of Cambridge Computing Service, Cambridge, England. Phone: +44 1223 334714. Copyright (c) 1997-2004 University of Cambridge tomcat-connectors-1.2.41-src/native/iis/pcre/ucp.c0000644000000000000020000001014510517277132020257 0ustar rootbin/************************************************* * libucp - Unicode Property Table handler * *************************************************/ /* This function provides a fast way of obtaining the basic Unicode properties of a character, using a compact binary tree that occupies less than 100K bytes. Copyright (c) 2004 University of Cambridge ------------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. ------------------------------------------------------------------------------- */ #include "ucp.h" /* Exported interface */ #include "ucpinternal.h" /* Internal table details */ #include "ucptable.c" /* The table itself */ /************************************************* * Search table and return data * *************************************************/ /* Two values are returned: the category is ucp_C, ucp_L, etc. The detailed character type is ucp_Lu, ucp_Nd, etc. Arguments: c the character value type_ptr the detailed character type is returned here case_ptr for letters, the opposite case is returned here, if there is one, else zero Returns: the character type category or -1 if not found */ static int ucp_findchar(const int c, int *type_ptr, int *case_ptr) { cnode *node = ucp_table; register int cc = c; int case_offset; for (;;) { register int d = node->f1 | ((node->f0 & f0_chhmask) << 16); if (cc == d) break; if (cc < d) { if ((node->f0 & f0_leftexists) == 0) return -1; node ++; } else { register int roffset = (node->f2 & f2_rightmask) >> f2_rightshift; if (roffset == 0) return -1; node += 1 << (roffset - 1); } } switch ((*type_ptr = ((node->f0 & f0_typemask) >> f0_typeshift))) { case ucp_Cc: case ucp_Cf: case ucp_Cn: case ucp_Co: case ucp_Cs: return ucp_C; break; case ucp_Ll: case ucp_Lu: case_offset = node->f2 & f2_casemask; if ((case_offset & 0x0100) != 0) case_offset |= 0xfffff000; *case_ptr = (case_offset == 0)? 0 : cc + case_offset; return ucp_L; case ucp_Lm: case ucp_Lo: case ucp_Lt: *case_ptr = 0; return ucp_L; break; case ucp_Mc: case ucp_Me: case ucp_Mn: return ucp_M; break; case ucp_Nd: case ucp_Nl: case ucp_No: return ucp_N; break; case ucp_Pc: case ucp_Pd: case ucp_Pe: case ucp_Pf: case ucp_Pi: case ucp_Ps: case ucp_Po: return ucp_P; break; case ucp_Sc: case ucp_Sk: case ucp_Sm: case ucp_So: return ucp_S; break; case ucp_Zl: case ucp_Zp: case ucp_Zs: return ucp_Z; break; default: /* "Should never happen" */ return -1; break; } } /* End of ucp.c */ tomcat-connectors-1.2.41-src/native/iis/pcre/LICENCE0000644000000000000020000000402310517277132020307 0ustar rootbinPCRE LICENCE ------------ PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Release 5 of PCRE is distributed under the terms of the "BSD" licence, as specified below. The documentation for PCRE, supplied in the "doc" directory, is distributed under the same terms as the software itself. Written by: Philip Hazel University of Cambridge Computing Service, Cambridge, England. Phone: +44 1223 334714. Copyright (c) 1997-2004 University of Cambridge All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. End tomcat-connectors-1.2.41-src/native/iis/pcre/NON-UNIX-USE0000644000000000000020000002270110517277132021115 0ustar rootbinCompiling PCRE on non-Unix systems ---------------------------------- See below for comments on Cygwin or MinGW and OpenVMS usage. I (Philip Hazel) have no knowledge of Windows or VMS sytems and how their libraries work. The items in the PCRE Makefile that relate to anything other than Unix-like systems have been contributed by PCRE users. There are some other comments and files in the Contrib directory on the ftp site that you may find useful. See ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib If you want to compile PCRE for a non-Unix system (or perhaps, more strictly, for a system that does not support "configure" and "make" files), note that PCRE consists entirely of code written in Standard C, and so should compile successfully on any system that has a Standard C compiler and library. GENERIC INSTRUCTIONS The following are generic comments about building PCRE. The interspersed indented commands are suggestions from Mark Tetrode as to which commands you might use on a Windows system to build a static library. (1) Copy or rename the file config.in as config.h, and change the macros that define HAVE_STRERROR and HAVE_MEMMOVE to define them as 1 rather than 0. Unfortunately, because of the way Unix autoconf works, the default setting has to be 0. You may also want to make changes to other macros in config.h. In particular, if you want to force a specific value for newline, you can define the NEWLINE macro. The default is to use '\n', thereby using whatever value your compiler gives to '\n'. rem Mark Tetrode's commands copy config.in config.h rem Use write, because notepad cannot handle UNIX files. Change values. write config.h (2) Copy or rename the file pcre.in as pcre.h, and change the macro definitions for PCRE_MAJOR, PCRE_MINOR, and PCRE_DATE near its start to the values set in configure.in. rem Mark Tetrode's commands copy pcre.in pcre.h rem Read values from configure.in write configure.in rem Change values write pcre.h (3) Compile dftables.c as a stand-alone program, and then run it with the single argument "chartables.c". This generates a set of standard character tables and writes them to that file. rem Mark Tetrode's commands rem Compile & run cl -DSUPPORT_UTF8 dftables.c dftables.exe > chartables.c (4) Compile maketables.c, get.c, study.c and pcre.c and link them all together into an object library in whichever form your system keeps such libraries. This is the pcre library (chartables.c is included by means of an #include directive). If your system has static and shared libraries, you may have to do this once for each type. rem Mark Tetrode's commands, for a static library rem Compile & lib cl -DSUPPORT_UTF8 -DPOSIX_MALLOC_THRESHOLD=10 /c maketables.c get.c study.c pcre.c lib /OUT:pcre.lib maketables.obj get.obj study.obj pcre.obj (5) Similarly, compile pcreposix.c and link it (on its own) as the pcreposix library. rem Mark Tetrode's commands, for a static library rem Compile & lib cl -DSUPPORT_UTF8 -DPOSIX_MALLOC_THRESHOLD=10 /c pcreposix.c lib /OUT:pcreposix.lib pcreposix.obj (6) Compile the test program pcretest.c. This needs the functions in the pcre and pcreposix libraries when linking. rem Mark Tetrode's commands rem compile & link cl pcretest.c pcre.lib pcreposix.lib (7) Run pcretest on the testinput files in the testdata directory, and check that the output matches the corresponding testoutput files. You must use the -i option when checking testinput2. Note that the supplied files are in Unix format, with just LF characters as line terminators. You may need to edit them to change this if your system uses a different convention. rem Mark Tetrode's commands rem Make a change, i.e. space, backspace, and save again - do this for all rem to change UNIX to Win, \n to \n\r write testoutput1 write testoutput2 write testoutput3 write testoutput4 write testoutput5 pcretest testdata\testinput1 testdata\myoutput1 windiff testdata\testoutput1 testdata\myoutput1 pcretest -i testdata\testinput2 testdata\myoutput2 windiff testdata\testoutput2 testdata\myoutput2 pcretest testdata\testinput3 testdata\myoutput3 windiff testdata\testoutput3 testdata\myoutput3 pcretest testdata\testinput4 testdata\myoutput4 windiff testdata\testoutput4 testdata\myoutput4 pcretest testdata\testinput5 testdata\myoutput5 windiff testdata\testoutput5 testdata\myoutput5 FURTHER REMARKS If you have a system without "configure" but where you can use a Makefile, edit Makefile.in to create Makefile, substituting suitable values for the variables at the head of the file. Some help in building a Win32 DLL of PCRE in GnuWin32 environments was contributed by Paul Sokolovsky. These environments are Mingw32 (http://www.xraylith.wisc.edu/~khan/software/gnu-win32/) and CygWin (http://sourceware.cygnus.com/cygwin/). Paul comments: For CygWin, set CFLAGS=-mno-cygwin, and do 'make dll'. You'll get pcre.dll (containing pcreposix also), libpcre.dll.a, and dynamically linked pgrep and pcretest. If you have /bin/sh, run RunTest (three main test go ok, locale not supported). Changes to do MinGW with autoconf 2.50 were supplied by Fred Cox , who comments as follows: If you are using the PCRE DLL, the normal Unix style configure && make && make check && make install should just work[*]. If you want to statically link against the .a file, you must define PCRE_STATIC before including pcre.h, otherwise the pcre_malloc and pcre_free exported functions will be declared __declspec(dllimport), with hilarious results. See the configure.in and pcretest.c for how it is done for the static test. Also, there will only be a libpcre.la, not a libpcreposix.la, as you would expect from the Unix version. The single DLL includes the pcreposix interface. [*] But note that the supplied test files are in Unix format, with just LF characters as line terminators. You will have to edit them to change to CR LF terminators. A script for building PCRE using Borland's C++ compiler for use with VPASCAL was contributed by Alexander Tokarev. It is called makevp.bat. These are some further comments about Win32 builds from Mark Evans. They were contributed before Fred Cox's changes were made, so it is possible that they may no longer be relevant. "The documentation for Win32 builds is a bit shy. Under MSVC6 I followed their instructions to the letter, but there were still some things missing. (1) Must #define STATIC for entire project if linking statically. (I see no reason to use DLLs for code this compact.) This of course is a project setting in MSVC under Preprocessor. (2) Missing some #ifdefs relating to the function pointers pcre_malloc and pcre_free. See my solution below. (The stubs may not be mandatory but they made me feel better.)" ========================= #ifdef _WIN32 #include void* malloc_stub(size_t N) { return malloc(N); } void free_stub(void* p) { free(p); } void *(*pcre_malloc)(size_t) = &malloc_stub; void (*pcre_free)(void *) = &free_stub; #else void *(*pcre_malloc)(size_t) = malloc; void (*pcre_free)(void *) = free; #endif ========================= BUILDING PCRE ON OPENVMS Dan Mooney sent the following comments about building PCRE on OpenVMS: "It was quite easy to compile and link the library. I don't have a formal make file but the attached file [reproduced below] contains the OpenVMS DCL commands I used to build the library. I had to add #define POSIX_MALLOC_THRESHOLD 10 to pcre.h since it was not defined anywhere. The library was built on: O/S: HP OpenVMS v7.3-1 Compiler: Compaq C v6.5-001-48BCD Linker: vA13-01 The test results did not match 100% due to the issues you mention in your documentation regarding isprint(), iscntrl(), isgraph() and ispunct(). I modified some of the character tables temporarily and was able to get the results to match. Tests using the fr locale did not match since I don't have that locale loaded. The study size was always reported to be 3 less than the value in the standard test output files." ========================= $! This DCL procedure builds PCRE on OpenVMS $! $! I followed the instructions in the non-unix-use file in the distribution. $! $ COMPILE == "CC/LIST/NOMEMBER_ALIGNMENT/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES $ COMPILE DFTABLES.C $ LINK/EXE=DFTABLES.EXE DFTABLES.OBJ $ RUN DFTABLES.EXE/OUTPUT=CHARTABLES.C $ COMPILE MAKETABLES.C $ COMPILE GET.C $ COMPILE STUDY.C $! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol $! did not seem to be defined anywhere. $! I edited pcre.h and added #DEFINE SUPPORT_UTF8 to enable UTF8 support. $ COMPILE PCRE.C $ LIB/CREATE PCRE MAKETABLES.OBJ, GET.OBJ, STUDY.OBJ, PCRE.OBJ $! I had to set POSIX_MALLOC_THRESHOLD to 10 in PCRE.H since the symbol $! did not seem to be defined anywhere. $ COMPILE PCREPOSIX.C $ LIB/CREATE PCREPOSIX PCREPOSIX.OBJ $ COMPILE PCRETEST.C $ LINK/EXE=PCRETEST.EXE PCRETEST.OBJ, PCRE/LIB, PCREPOSIX/LIB $! C programs that want access to command line arguments must be $! defined as a symbol $ PCRETEST :== "$ SYS$ROADSUSERS:[DMOONEY.REGEXP]PCRETEST.EXE" $! Arguments must be enclosed in quotes. $ PCRETEST "-C" $! Test results: $! $! The test results did not match 100%. The functions isprint(), iscntrl(), $! isgraph() and ispunct() on OpenVMS must not produce the same results $! as the system that built the test output files provided with the $! distribution. $! $! The study size did not match and was always 3 less on OpenVMS. $! $! Locale could not be set to fr $! ========================= **** tomcat-connectors-1.2.41-src/native/iis/pcre/pcre.hw0000644000000000000020000002251010517277132020614 0ustar rootbin/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* In its original form, this is the .in file that is transformed by "configure" into pcre.h. Copyright (c) 1997-2004 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. ----------------------------------------------------------------------------- */ #ifndef _PCRE_H #define _PCRE_H /* The file pcre.h is build by "configure" or copied from pcre.hw Do not edit it; instead make changes to pcre.in and/or pcre.hw */ #define PCRE_MAJOR 5 #define PCRE_MINOR 0 #define PCRE_DATE 13-Sep-2004 /* Win32 uses DLL by default */ #ifdef _WIN32 # ifdef PCRE_DEFINITION # ifdef DLL_EXPORT # define PCRE_DATA_SCOPE __declspec(dllexport) # endif # else # ifndef PCRE_STATIC # define PCRE_DATA_SCOPE extern __declspec(dllimport) # endif # endif #endif #ifndef PCRE_DATA_SCOPE # define PCRE_DATA_SCOPE extern #endif /* Have to include stdlib.h in order to ensure that size_t is defined; it is needed here for malloc. */ #include /* Allow for C++ users */ #ifdef __cplusplus extern "C" { #endif /* Options */ #define PCRE_CASELESS 0x0001 #define PCRE_MULTILINE 0x0002 #define PCRE_DOTALL 0x0004 #define PCRE_EXTENDED 0x0008 #define PCRE_ANCHORED 0x0010 #define PCRE_DOLLAR_ENDONLY 0x0020 #define PCRE_EXTRA 0x0040 #define PCRE_NOTBOL 0x0080 #define PCRE_NOTEOL 0x0100 #define PCRE_UNGREEDY 0x0200 #define PCRE_NOTEMPTY 0x0400 #define PCRE_UTF8 0x0800 #define PCRE_NO_AUTO_CAPTURE 0x1000 #define PCRE_NO_UTF8_CHECK 0x2000 #define PCRE_AUTO_CALLOUT 0x4000 #define PCRE_PARTIAL 0x8000 /* Exec-time and get/set-time error codes */ #define PCRE_ERROR_NOMATCH (-1) #define PCRE_ERROR_NULL (-2) #define PCRE_ERROR_BADOPTION (-3) #define PCRE_ERROR_BADMAGIC (-4) #define PCRE_ERROR_UNKNOWN_NODE (-5) #define PCRE_ERROR_NOMEMORY (-6) #define PCRE_ERROR_NOSUBSTRING (-7) #define PCRE_ERROR_MATCHLIMIT (-8) #define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ #define PCRE_ERROR_BADUTF8 (-10) #define PCRE_ERROR_BADUTF8_OFFSET (-11) #define PCRE_ERROR_PARTIAL (-12) #define PCRE_ERROR_BADPARTIAL (-13) #define PCRE_ERROR_INTERNAL (-14) #define PCRE_ERROR_BADCOUNT (-15) /* Request types for pcre_fullinfo() */ #define PCRE_INFO_OPTIONS 0 #define PCRE_INFO_SIZE 1 #define PCRE_INFO_CAPTURECOUNT 2 #define PCRE_INFO_BACKREFMAX 3 #define PCRE_INFO_FIRSTBYTE 4 #define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */ #define PCRE_INFO_FIRSTTABLE 5 #define PCRE_INFO_LASTLITERAL 6 #define PCRE_INFO_NAMEENTRYSIZE 7 #define PCRE_INFO_NAMECOUNT 8 #define PCRE_INFO_NAMETABLE 9 #define PCRE_INFO_STUDYSIZE 10 #define PCRE_INFO_DEFAULT_TABLES 11 /* Request types for pcre_config() */ #define PCRE_CONFIG_UTF8 0 #define PCRE_CONFIG_NEWLINE 1 #define PCRE_CONFIG_LINK_SIZE 2 #define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3 #define PCRE_CONFIG_MATCH_LIMIT 4 #define PCRE_CONFIG_STACKRECURSE 5 #define PCRE_CONFIG_UNICODE_PROPERTIES 6 /* Bit flags for the pcre_extra structure */ #define PCRE_EXTRA_STUDY_DATA 0x0001 #define PCRE_EXTRA_MATCH_LIMIT 0x0002 #define PCRE_EXTRA_CALLOUT_DATA 0x0004 #define PCRE_EXTRA_TABLES 0x0008 /* Types */ struct real_pcre; /* declaration; the definition is private */ typedef struct real_pcre pcre; /* The structure for passing additional data to pcre_exec(). This is defined in such as way as to be extensible. Always add new fields at the end, in order to remain compatible. */ typedef struct pcre_extra { unsigned long int flags; /* Bits for which fields are set */ void *study_data; /* Opaque data from pcre_study() */ unsigned long int match_limit; /* Maximum number of calls to match() */ void *callout_data; /* Data passed back in callouts */ const unsigned char *tables; /* Pointer to character tables */ } pcre_extra; /* The structure for passing out data via the pcre_callout_function. We use a structure so that new fields can be added on the end in future versions, without changing the API of the function, thereby allowing old clients to work without modification. */ typedef struct pcre_callout_block { int version; /* Identifies version of block */ /* ------------------------ Version 0 ------------------------------- */ int callout_number; /* Number compiled into pattern */ int *offset_vector; /* The offset vector */ const char *subject; /* The subject being matched */ int subject_length; /* The length of the subject */ int start_match; /* Offset to start of this match attempt */ int current_position; /* Where we currently are in the subject */ int capture_top; /* Max current capture */ int capture_last; /* Most recently closed capture */ void *callout_data; /* Data passed in with the call */ /* ------------------- Added for Version 1 -------------------------- */ int pattern_position; /* Offset to next item in the pattern */ int next_item_length; /* Length of next item in the pattern */ /* ------------------------------------------------------------------ */ } pcre_callout_block; /* Indirection for store get and free functions. These can be set to alternative malloc/free functions if required. Special ones are used in the non-recursive case for "frames". There is also an optional callout function that is triggered by the (?) regex item. Some magic is required for Win32 DLL; it is null on other OS. For Virtual Pascal, these have to be different again. */ #ifndef VPCOMPAT PCRE_DATA_SCOPE void *(*pcre_malloc)(size_t); PCRE_DATA_SCOPE void (*pcre_free)(void *); PCRE_DATA_SCOPE void *(*pcre_stack_malloc)(size_t); PCRE_DATA_SCOPE void (*pcre_stack_free)(void *); PCRE_DATA_SCOPE int (*pcre_callout)(pcre_callout_block *); #else /* VPCOMPAT */ extern void *pcre_malloc(size_t); extern void pcre_free(void *); extern void *pcre_stack_malloc(size_t); extern void pcre_stack_free(void *); extern int pcre_callout(pcre_callout_block *); #endif /* VPCOMPAT */ /* Exported PCRE functions */ extern pcre *pcre_compile(const char *, int, const char **, int *, const unsigned char *); extern int pcre_config(int, void *); extern int pcre_copy_named_substring(const pcre *, const char *, int *, int, const char *, char *, int); extern int pcre_copy_substring(const char *, int *, int, int, char *, int); extern int pcre_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int); extern void pcre_free_substring(const char *); extern void pcre_free_substring_list(const char **); extern int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *); extern int pcre_get_named_substring(const pcre *, const char *, int *, int, const char *, const char **); extern int pcre_get_stringnumber(const pcre *, const char *); extern int pcre_get_substring(const char *, int *, int, int, const char **); extern int pcre_get_substring_list(const char *, int *, int, const char ***); extern int pcre_info(const pcre *, int *, int *); extern const unsigned char *pcre_maketables(void); extern pcre_extra *pcre_study(const pcre *, int, const char **); extern const char *pcre_version(void); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* End of pcre.h */ tomcat-connectors-1.2.41-src/native/iis/pcre/ucpinternal.h0000644000000000000020000000673310517277132022031 0ustar rootbin/************************************************* * libucp - Unicode Property Table handler * *************************************************/ /* Internal header file defining the layout of compact nodes in the tree. */ typedef struct cnode { unsigned short int f0; unsigned short int f1; unsigned short int f2; } cnode; /* Things for the f0 field */ #define f0_leftexists 0x8000 /* Left child exists */ #define f0_typemask 0x3f00 /* Type bits */ #define f0_typeshift 8 /* Type shift */ #define f0_chhmask 0x00ff /* Character high bits */ /* Things for the f2 field */ #define f2_rightmask 0xf000 /* Mask for right offset bits */ #define f2_rightshift 12 /* Shift for right offset */ #define f2_casemask 0x0fff /* Mask for case offset */ /* The tree consists of a vector of structures of type cnode, with the root node as the first element. The three short ints (16-bits) are used as follows: (f0) (1) The 0x8000 bit of f0 is set if a left child exists. The child's node is the next node in the vector. (2) The 0x4000 bits of f0 is spare. (3) The 0x3f00 bits of f0 contain the character type; this is a number defined by the enumeration in ucp.h (e.g. ucp_Lu). (4) The bottom 8 bits of f0 contain the most significant byte of the character's 24-bit codepoint. (f1) (1) The f1 field contains the two least significant bytes of the codepoint. (f2) (1) The 0xf000 bits of f2 contain zero if there is no right child of this node. Otherwise, they contain one plus the exponent of the power of two of the offset to the right node (e.g. a value of 3 means 8). The units of the offset are node items. (2) The 0x0fff bits of f2 contain the signed offset from this character to its alternate cased value. They are zero if there is no such character. ----------------------------------------------------------------------------- ||.|.| type (6) | ms char (8) || ls char (16) ||....| case offset (12) || ----------------------------------------------------------------------------- | | | | |-> spare | | exponent of right |-> left child exists child offset The upper/lower casing information is set only for characters that come in pairs. There are (at present) four non-one-to-one mappings in the Unicode data. These are ignored. They are: 1FBE Greek Prosgegrammeni (lower, with upper -> capital iota) 2126 Ohm 212A Kelvin 212B Angstrom Certainly for the last three, having an alternate case would seem to be a mistake. I don't know any Greek, so cannot comment on the first one. When searching the tree, proceed as follows: (1) Start at the first node. (2) Extract the character value from f1 and the bottom 8 bits of f0; (3) Compare with the character being sought. If equal, we are done. (4) If the test character is smaller, inspect the f0_leftexists flag. If it is not set, the character is not in the tree. If it is set, move to the next node, and go to (2). (5) If the test character is bigger, extract the f2_rightmask bits from f2, and shift them right by f2_rightshift. If the result is zero, the character is not in the tree. Otherwise, calculate the number of nodes to skip by shifting the value 1 left by this number minus one. Go to (2). */ /* End of internal.h */ tomcat-connectors-1.2.41-src/native/iis/pcre/get.c0000644000000000000020000002745010517277132020256 0ustar rootbin/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. See the file Tech.Notes for some information on the internals. Written by: Philip Hazel Copyright (c) 1997-2003 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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 module contains some convenience functions for extracting substrings from the subject string after a regex match has succeeded. The original idea for these functions came from Scott Wimer. */ /* Include the internals header, which itself includes Standard C headers plus the external pcre header. */ #include "internal.h" /************************************************* * Find number for named string * *************************************************/ /* This function is used by the two extraction functions below, as well as being generally available. Arguments: code the compiled regex stringname the name whose number is required Returns: the number of the named parentheses, or a negative number (PCRE_ERROR_NOSUBSTRING) if not found */ int pcre_get_stringnumber(const pcre *code, const char *stringname) { int rc; int entrysize; int top, bot; uschar *nametable; if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0) return rc; if (top <= 0) return PCRE_ERROR_NOSUBSTRING; if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0) return rc; if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0) return rc; bot = 0; while (top > bot) { int mid = (top + bot) / 2; uschar *entry = nametable + entrysize*mid; int c = strcmp(stringname, (char *)(entry + 2)); if (c == 0) return (entry[0] << 8) + entry[1]; if (c > 0) bot = mid + 1; else top = mid; } return PCRE_ERROR_NOSUBSTRING; } /************************************************* * Copy captured string to given buffer * *************************************************/ /* This function copies a single captured substring into a given buffer. Note that we use memcpy() rather than strncpy() in case there are binary zeros in the string. Arguments: subject the subject string that was matched ovector pointer to the offsets table stringcount the number of substrings that were captured (i.e. the yield of the pcre_exec call, unless that was zero, in which case it should be 1/3 of the offset table size) stringnumber the number of the required substring buffer where to put the substring size the size of the buffer Returns: if successful: the length of the copied string, not including the zero that is put on the end; can be zero if not successful: PCRE_ERROR_NOMEMORY (-6) buffer too small PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ int pcre_copy_substring(const char *subject, int *ovector, int stringcount, int stringnumber, char *buffer, int size) { int yield; if (stringnumber < 0 || stringnumber >= stringcount) return PCRE_ERROR_NOSUBSTRING; stringnumber *= 2; yield = ovector[stringnumber+1] - ovector[stringnumber]; if (size < yield + 1) return PCRE_ERROR_NOMEMORY; memcpy(buffer, subject + ovector[stringnumber], yield); buffer[yield] = 0; return yield; } /************************************************* * Copy named captured string to given buffer * *************************************************/ /* This function copies a single captured substring into a given buffer, identifying it by name. Arguments: code the compiled regex subject the subject string that was matched ovector pointer to the offsets table stringcount the number of substrings that were captured (i.e. the yield of the pcre_exec call, unless that was zero, in which case it should be 1/3 of the offset table size) stringname the name of the required substring buffer where to put the substring size the size of the buffer Returns: if successful: the length of the copied string, not including the zero that is put on the end; can be zero if not successful: PCRE_ERROR_NOMEMORY (-6) buffer too small PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ int pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, char *buffer, int size) { int n = pcre_get_stringnumber(code, stringname); if (n <= 0) return n; return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size); } /************************************************* * Copy all captured strings to new store * *************************************************/ /* This function gets one chunk of store and builds a list of pointers and all of the captured substrings in it. A NULL pointer is put on the end of the list. Arguments: subject the subject string that was matched ovector pointer to the offsets table stringcount the number of substrings that were captured (i.e. the yield of the pcre_exec call, unless that was zero, in which case it should be 1/3 of the offset table size) listptr set to point to the list of pointers Returns: if successful: 0 if not successful: PCRE_ERROR_NOMEMORY (-6) failed to get store */ int pcre_get_substring_list(const char *subject, int *ovector, int stringcount, const char ***listptr) { int i; int size = sizeof(char *); int double_count = stringcount * 2; char **stringlist; char *p; for (i = 0; i < double_count; i += 2) size += sizeof(char *) + ovector[i+1] - ovector[i] + 1; stringlist = (char **)(pcre_malloc)(size); if (stringlist == NULL) return PCRE_ERROR_NOMEMORY; *listptr = (const char **)stringlist; p = (char *)(stringlist + stringcount + 1); for (i = 0; i < double_count; i += 2) { int len = ovector[i+1] - ovector[i]; memcpy(p, subject + ovector[i], len); *stringlist++ = p; p += len; *p++ = 0; } *stringlist = NULL; return 0; } /************************************************* * Free store obtained by get_substring_list * *************************************************/ /* This function exists for the benefit of people calling PCRE from non-C programs that can call its functions, but not free() or (pcre_free)() directly. Argument: the result of a previous pcre_get_substring_list() Returns: nothing */ void pcre_free_substring_list(const char **pointer) { (pcre_free)((void *)pointer); } /************************************************* * Copy captured string to new store * *************************************************/ /* This function copies a single captured substring into a piece of new store Arguments: subject the subject string that was matched ovector pointer to the offsets table stringcount the number of substrings that were captured (i.e. the yield of the pcre_exec call, unless that was zero, in which case it should be 1/3 of the offset table size) stringnumber the number of the required substring stringptr where to put a pointer to the substring Returns: if successful: the length of the string, not including the zero that is put on the end; can be zero if not successful: PCRE_ERROR_NOMEMORY (-6) failed to get store PCRE_ERROR_NOSUBSTRING (-7) substring not present */ int pcre_get_substring(const char *subject, int *ovector, int stringcount, int stringnumber, const char **stringptr) { int yield; char *substring; if (stringnumber < 0 || stringnumber >= stringcount) return PCRE_ERROR_NOSUBSTRING; stringnumber *= 2; yield = ovector[stringnumber+1] - ovector[stringnumber]; substring = (char *)(pcre_malloc)(yield + 1); if (substring == NULL) return PCRE_ERROR_NOMEMORY; memcpy(substring, subject + ovector[stringnumber], yield); substring[yield] = 0; *stringptr = substring; return yield; } /************************************************* * Copy named captured string to new store * *************************************************/ /* This function copies a single captured substring, identified by name, into new store. Arguments: code the compiled regex subject the subject string that was matched ovector pointer to the offsets table stringcount the number of substrings that were captured (i.e. the yield of the pcre_exec call, unless that was zero, in which case it should be 1/3 of the offset table size) stringname the name of the required substring stringptr where to put the pointer Returns: if successful: the length of the copied string, not including the zero that is put on the end; can be zero if not successful: PCRE_ERROR_NOMEMORY (-6) couldn't get memory PCRE_ERROR_NOSUBSTRING (-7) no such captured substring */ int pcre_get_named_substring(const pcre *code, const char *subject, int *ovector, int stringcount, const char *stringname, const char **stringptr) { int n = pcre_get_stringnumber(code, stringname); if (n <= 0) return n; return pcre_get_substring(subject, ovector, stringcount, n, stringptr); } /************************************************* * Free store obtained by get_substring * *************************************************/ /* This function exists for the benefit of people calling PCRE from non-C programs that can call its functions, but not free() or (pcre_free)() directly. Argument: the result of a previous pcre_get_substring() Returns: nothing */ void pcre_free_substring(const char *pointer) { (pcre_free)((void *)pointer); } /* End of get.c */ tomcat-connectors-1.2.41-src/native/iis/pcre/dll.mk0000644000000000000020000000366710517277132020443 0ustar rootbin# dll.mk - auxilary Makefile to easy build dll's for mingw32 target # ver. 0.6 of 1999-03-25 # # Homepage of this makefile - http://www.is.lg.ua/~paul/devel/ # Homepage of original mingw32 project - # http://www.fu.is.saga-u.ac.jp/~colin/gcc.html # # How to use: # This makefile can: # 1. Create automatical .def file from list of objects # 2. Create .dll from objects and .def file, either automatical, or your # hand-written (maybe) file, which must have same basename as dll # WARNING! There MUST be object, which name match dll's name. Make sux. # 3. Create import library from .def (as for .dll, only its name required, # not dll itself) # By convention implibs for dll have .dll.a suffix, e.g. libstuff.dll.a # Why not just libstuff.a? 'Cos that's name for static lib, ok? # Process divided into 3 phases because: # 1. Pre-existent .def possible # 2. Generating implib is enough time-consuming # # Variables: # DLL_LDLIBS - libs for linking dll # DLL_LDFLAGS - flags for linking dll # # By using $(DLL_SUFFIX) instead of 'dll', e.g. stuff.$(DLL_SUFFIX) # you may help porting makefiles to other platforms # # Put this file in your make's include path (e.g. main include dir, for # more information see include section in make doc). Put in the beginning # of your own Makefile line "include dll.mk". Specify dependences, e.g.: # # Do all stuff in one step # libstuff.dll.a: $(OBJECTS) stuff.def # stuff.def: $(OBJECTS) # # Steps separated, pre-provided .def, link with user32 # # DLL_LDLIBS=-luser32 # stuff.dll: $(OBJECTS) # libstuff.dll.a: $(OBJECTS) DLLWRAP=dllwrap DLLTOOL=dlltool DLL_SUFFIX=dll .SUFFIXES: .o .$(DLL_SUFFIX) _%.def: %.o $(DLLTOOL) --export-all --output-def $@ $^ %.$(DLL_SUFFIX): %.o $(DLLWRAP) --dllname $(notdir $@) --driver-name $(CC) --def $*.def -o $@ $(filter %.o,$^) $(DLL_LDFLAGS) $(DLL_LDLIBS) lib%.$(DLL_SUFFIX).a:%.def $(DLLTOOL) --dllname $(notdir $*.dll) --def $< --output-lib $@ # End tomcat-connectors-1.2.41-src/native/iis/pcre/dftables.x860000644000000000000020000000466711450342437021471 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. CPP=cl.exe RSC=rc.exe OUTDIR=. INTDIR=.\Release_x86 # Begin Custom Macros OutDir=. # End Custom Macros ALL : "$(OUTDIR)\dftables.exe" CLEAN : -@erase "$(INTDIR)\dftables.idb" -@erase "$(INTDIR)\dftables.obj" -@erase "$(OUTDIR)\dftables.exe" "$(INTDIR)" : if not exist "$(INTDIR)/$(NULL)" mkdir "$(INTDIR)" BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\dftables.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=kernel32.lib $(EXTRA_LIBS) /nologo /subsystem:console /incremental:no /pdb:"$(OUTDIR)\Release\dftables.pdb" /machine:I386 /out:"$(OUTDIR)\dftables.exe" /opt:ref LINK32_OBJS= \ "$(INTDIR)\dftables.obj" "$(OUTDIR)\dftables.exe" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << CPP_PROJ=-nologo -MD -W3 -O2 -Ob2 -Oy- -Zi -EHsc /D "_WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\dftables" /FD /wd4996 /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << !IF "$(CFG)" == "dftables_x86" SOURCE=.\dftables.c "$(INTDIR)\dftables.obj" : $(SOURCE) "$(INTDIR)" ".\config.h" ".\pcre.h" SOURCE=.\config.hw InputPath=.\config.hw ".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" < .\config.h << SOURCE=.\maketables.c SOURCE=.\pcre.hw InputPath=.\pcre.hw ".\pcre.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" < .\pcre.h << !ENDIF tomcat-connectors-1.2.41-src/native/iis/pcre/pcretest.c0000644000000000000020000014463110517277132021331 0ustar rootbin/************************************************* * PCRE testing program * *************************************************/ /* This program was hacked up as a tester for PCRE. I really should have written it more tidily in the first place. Will I ever learn? It has grown and been extended and consequently is now rather untidy in places. ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. ----------------------------------------------------------------------------- */ #include #include #include #include #include #include #include /* We need the internal info for displaying the results of pcre_study(). Also for getting the opcodes for showing compiled code. */ #define PCRE_SPY /* For Win32 build, import data, not export */ #include "internal.h" /* It is possible to compile this test program without including support for testing the POSIX interface, though this is not available via the standard Makefile. */ #if !defined NOPOSIX #include "pcreposix.h" #endif #ifndef CLOCKS_PER_SEC #ifdef CLK_TCK #define CLOCKS_PER_SEC CLK_TCK #else #define CLOCKS_PER_SEC 100 #endif #endif #define LOOPREPEAT 500000 #define BUFFER_SIZE 30000 #define PBUFFER_SIZE BUFFER_SIZE #define DBUFFER_SIZE BUFFER_SIZE static FILE *outfile; static int log_store = 0; static int callout_count; static int callout_extra; static int callout_fail_count; static int callout_fail_id; static int first_callout; static int show_malloc; static int use_utf8; static size_t gotten_store; static uschar *pbuffer = NULL; static const int utf8_table1[] = { 0x0000007f, 0x000007ff, 0x0000ffff, 0x001fffff, 0x03ffffff, 0x7fffffff}; static const int utf8_table2[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; static const int utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; /************************************************* * Print compiled regex * *************************************************/ /* The code for doing this is held in a separate file that is also included in pcre.c when it is compiled with the debug switch. It defines a function called print_internals(), which uses a table of opcode lengths defined by the macro OP_LENGTHS, whose name must be OP_lengths. It also uses a table that translates Unicode property names to numbers; this is kept in a separate file. */ static uschar OP_lengths[] = { OP_LENGTHS }; #include "ucp.h" #include "ucptypetable.c" #include "printint.c" /************************************************* * Read number from string * *************************************************/ /* We don't use strtoul() because SunOS4 doesn't have it. Rather than mess around with conditional compilation, just do the job by hand. It is only used for unpicking the -o argument, so just keep it simple. Arguments: str string to be converted endptr where to put the end pointer Returns: the unsigned long */ static int get_value(unsigned char *str, unsigned char **endptr) { int result = 0; while(*str != 0 && isspace(*str)) str++; while (isdigit(*str)) result = result * 10 + (int)(*str++ - '0'); *endptr = str; return(result); } /************************************************* * Convert character value to UTF-8 * *************************************************/ /* This function takes an integer value in the range 0 - 0x7fffffff and encodes it as a UTF-8 character in 0 to 6 bytes. Arguments: cvalue the character value buffer pointer to buffer for result - at least 6 bytes long Returns: number of characters placed in the buffer -1 if input character is negative 0 if input character is positive but too big (only when int is longer than 32 bits) */ static int ord2utf8(int cvalue, unsigned char *buffer) { register int i, j; for (i = 0; i < sizeof(utf8_table1)/sizeof(int); i++) if (cvalue <= utf8_table1[i]) break; if (i >= sizeof(utf8_table1)/sizeof(int)) return 0; if (cvalue < 0) return -1; buffer += i; for (j = i; j > 0; j--) { *buffer-- = 0x80 | (cvalue & 0x3f); cvalue >>= 6; } *buffer = utf8_table2[i] | cvalue; return i + 1; } /************************************************* * Convert UTF-8 string to value * *************************************************/ /* This function takes one or more bytes that represents a UTF-8 character, and returns the value of the character. Argument: buffer a pointer to the byte vector vptr a pointer to an int to receive the value Returns: > 0 => the number of bytes consumed -6 to 0 => malformed UTF-8 character at offset = (-return) */ static int utf82ord(unsigned char *buffer, int *vptr) { int c = *buffer++; int d = c; int i, j, s; for (i = -1; i < 6; i++) /* i is number of additional bytes */ { if ((d & 0x80) == 0) break; d <<= 1; } if (i == -1) { *vptr = c; return 1; } /* ascii character */ if (i == 0 || i == 6) return 0; /* invalid UTF-8 */ /* i now has a value in the range 1-5 */ s = 6*i; d = (c & utf8_table3[i]) << s; for (j = 0; j < i; j++) { c = *buffer++; if ((c & 0xc0) != 0x80) return -(j+1); s -= 6; d |= (c & 0x3f) << s; } /* Check that encoding was the correct unique one */ for (j = 0; j < sizeof(utf8_table1)/sizeof(int); j++) if (d <= utf8_table1[j]) break; if (j != i) return -(i+1); /* Valid value */ *vptr = d; return i+1; } /************************************************* * Print character string * *************************************************/ /* Character string printing function. Must handle UTF-8 strings in utf8 mode. Yields number of characters printed. If handed a NULL file, just counts chars without printing. */ static int pchars(unsigned char *p, int length, FILE *f) { int c; int yield = 0; while (length-- > 0) { if (use_utf8) { int rc = utf82ord(p, &c); if (rc > 0 && rc <= length + 1) /* Mustn't run over the end */ { length -= rc - 1; p += rc; if (c < 256 && isprint(c)) { if (f != NULL) fprintf(f, "%c", c); yield++; } else { int n; if (f != NULL) fprintf(f, "\\x{%02x}%n", c, &n); yield += n; } continue; } } /* Not UTF-8, or malformed UTF-8 */ if (isprint(c = *(p++))) { if (f != NULL) fprintf(f, "%c", c); yield++; } else { if (f != NULL) fprintf(f, "\\x%02x", c); yield += 4; } } return yield; } /************************************************* * Callout function * *************************************************/ /* Called from PCRE as a result of the (?C) item. We print out where we are in the match. Yield zero unless more callouts than the fail count, or the callout data is not zero. */ static int callout(pcre_callout_block *cb) { FILE *f = (first_callout | callout_extra)? outfile : NULL; int i, pre_start, post_start, subject_length; if (callout_extra) { fprintf(f, "Callout %d: last capture = %d\n", cb->callout_number, cb->capture_last); for (i = 0; i < cb->capture_top * 2; i += 2) { if (cb->offset_vector[i] < 0) fprintf(f, "%2d: \n", i/2); else { fprintf(f, "%2d: ", i/2); (void)pchars((unsigned char *)cb->subject + cb->offset_vector[i], cb->offset_vector[i+1] - cb->offset_vector[i], f); fprintf(f, "\n"); } } } /* Re-print the subject in canonical form, the first time or if giving full datails. On subsequent calls in the same match, we use pchars just to find the printed lengths of the substrings. */ if (f != NULL) fprintf(f, "--->"); pre_start = pchars((unsigned char *)cb->subject, cb->start_match, f); post_start = pchars((unsigned char *)(cb->subject + cb->start_match), cb->current_position - cb->start_match, f); subject_length = pchars((unsigned char *)cb->subject, cb->subject_length, NULL); (void)pchars((unsigned char *)(cb->subject + cb->current_position), cb->subject_length - cb->current_position, f); if (f != NULL) fprintf(f, "\n"); /* Always print appropriate indicators, with callout number if not already shown. For automatic callouts, show the pattern offset. */ if (cb->callout_number == 255) { fprintf(outfile, "%+3d ", cb->pattern_position); if (cb->pattern_position > 99) fprintf(outfile, "\n "); } else { if (callout_extra) fprintf(outfile, " "); else fprintf(outfile, "%3d ", cb->callout_number); } for (i = 0; i < pre_start; i++) fprintf(outfile, " "); fprintf(outfile, "^"); if (post_start > 0) { for (i = 0; i < post_start - 1; i++) fprintf(outfile, " "); fprintf(outfile, "^"); } for (i = 0; i < subject_length - pre_start - post_start + 4; i++) fprintf(outfile, " "); fprintf(outfile, "%.*s", (cb->next_item_length == 0)? 1 : cb->next_item_length, pbuffer + cb->pattern_position); fprintf(outfile, "\n"); first_callout = 0; if (cb->callout_data != NULL) { int callout_data = *((int *)(cb->callout_data)); if (callout_data != 0) { fprintf(outfile, "Callout data = %d\n", callout_data); return callout_data; } } return (cb->callout_number != callout_fail_id)? 0 : (++callout_count >= callout_fail_count)? 1 : 0; } /************************************************* * Local malloc functions * *************************************************/ /* Alternative malloc function, to test functionality and show the size of the compiled re. */ static void *new_malloc(size_t size) { void *block = malloc(size); gotten_store = size; if (show_malloc) fprintf(outfile, "malloc %3d %p\n", size, block); return block; } static void new_free(void *block) { if (show_malloc) fprintf(outfile, "free %p\n", block); free(block); } /* For recursion malloc/free, to test stacking calls */ static void *stack_malloc(size_t size) { void *block = malloc(size); if (show_malloc) fprintf(outfile, "stack_malloc %3d %p\n", size, block); return block; } static void stack_free(void *block) { if (show_malloc) fprintf(outfile, "stack_free %p\n", block); free(block); } /************************************************* * Call pcre_fullinfo() * *************************************************/ /* Get one piece of information from the pcre_fullinfo() function */ static void new_info(pcre *re, pcre_extra *study, int option, void *ptr) { int rc; if ((rc = pcre_fullinfo(re, study, option, ptr)) < 0) fprintf(outfile, "Error %d from pcre_fullinfo(%d)\n", rc, option); } /************************************************* * Byte flipping function * *************************************************/ static long int byteflip(long int value, int n) { if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8); return ((value & 0x000000ff) << 24) | ((value & 0x0000ff00) << 8) | ((value & 0x00ff0000) >> 8) | ((value & 0xff000000) >> 24); } /************************************************* * Main Program * *************************************************/ /* Read lines from named file or stdin and write to named file or stdout; lines consist of a regular expression, in delimiters and optionally followed by options, followed by a set of test data, terminated by an empty line. */ int main(int argc, char **argv) { FILE *infile = stdin; int options = 0; int study_options = 0; int op = 1; int timeit = 0; int showinfo = 0; int showstore = 0; int size_offsets = 45; int size_offsets_max; int *offsets; #if !defined NOPOSIX int posix = 0; #endif int debug = 0; int done = 0; unsigned char *buffer; unsigned char *dbuffer; /* Get buffers from malloc() so that Electric Fence will check their misuse when I am debugging. */ buffer = (unsigned char *)malloc(BUFFER_SIZE); dbuffer = (unsigned char *)malloc(DBUFFER_SIZE); pbuffer = (unsigned char *)malloc(PBUFFER_SIZE); /* The outfile variable is static so that new_malloc can use it. The _setmode() stuff is some magic that I don't understand, but which apparently does good things in Windows. It's related to line terminations. */ #if defined(_WIN32) || defined(WIN32) _setmode( _fileno( stdout ), 0x8000 ); #endif /* defined(_WIN32) || defined(WIN32) */ outfile = stdout; /* Scan options */ while (argc > 1 && argv[op][0] == '-') { unsigned char *endptr; if (strcmp(argv[op], "-s") == 0 || strcmp(argv[op], "-m") == 0) showstore = 1; else if (strcmp(argv[op], "-t") == 0) timeit = 1; else if (strcmp(argv[op], "-i") == 0) showinfo = 1; else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1; else if (strcmp(argv[op], "-o") == 0 && argc > 2 && ((size_offsets = get_value((unsigned char *)argv[op+1], &endptr)), *endptr == 0)) { op++; argc--; } #if !defined NOPOSIX else if (strcmp(argv[op], "-p") == 0) posix = 1; #endif else if (strcmp(argv[op], "-C") == 0) { int rc; printf("PCRE version %s\n", pcre_version()); printf("Compiled with\n"); (void)pcre_config(PCRE_CONFIG_UTF8, &rc); printf(" %sUTF-8 support\n", rc? "" : "No "); (void)pcre_config(PCRE_CONFIG_UNICODE_PROPERTIES, &rc); printf(" %sUnicode properties support\n", rc? "" : "No "); (void)pcre_config(PCRE_CONFIG_NEWLINE, &rc); printf(" Newline character is %s\n", (rc == '\r')? "CR" : "LF"); (void)pcre_config(PCRE_CONFIG_LINK_SIZE, &rc); printf(" Internal link size = %d\n", rc); (void)pcre_config(PCRE_CONFIG_POSIX_MALLOC_THRESHOLD, &rc); printf(" POSIX malloc threshold = %d\n", rc); (void)pcre_config(PCRE_CONFIG_MATCH_LIMIT, &rc); printf(" Default match limit = %d\n", rc); (void)pcre_config(PCRE_CONFIG_STACKRECURSE, &rc); printf(" Match recursion uses %s\n", rc? "stack" : "heap"); exit(0); } else { printf("** Unknown or malformed option %s\n", argv[op]); printf("Usage: pcretest [-d] [-i] [-o ] [-p] [-s] [-t] [ []]\n"); printf(" -C show PCRE compile-time options and exit\n"); printf(" -d debug: show compiled code; implies -i\n" " -i show information about compiled pattern\n" " -m output memory used information\n" " -o set size of offsets vector to \n"); #if !defined NOPOSIX printf(" -p use POSIX interface\n"); #endif printf(" -s output store (memory) used information\n" " -t time compilation and execution\n"); return 1; } op++; argc--; } /* Get the store for the offsets vector, and remember what it was */ size_offsets_max = size_offsets; offsets = (int *)malloc(size_offsets_max * sizeof(int)); if (offsets == NULL) { printf("** Failed to get %d bytes of memory for offsets vector\n", size_offsets_max * sizeof(int)); return 1; } /* Sort out the input and output files */ if (argc > 1) { infile = fopen(argv[op], "rb"); if (infile == NULL) { printf("** Failed to open %s\n", argv[op]); return 1; } } if (argc > 2) { outfile = fopen(argv[op+1], "wb"); if (outfile == NULL) { printf("** Failed to open %s\n", argv[op+1]); return 1; } } /* Set alternative malloc function */ pcre_malloc = new_malloc; pcre_free = new_free; pcre_stack_malloc = stack_malloc; pcre_stack_free = stack_free; /* Heading line, then prompt for first regex if stdin */ fprintf(outfile, "PCRE version %s\n\n", pcre_version()); /* Main loop */ while (!done) { pcre *re = NULL; pcre_extra *extra = NULL; #if !defined NOPOSIX /* There are still compilers that require no indent */ regex_t preg; int do_posix = 0; #endif const char *error; unsigned char *p, *pp, *ppp; unsigned char *to_file = NULL; const unsigned char *tables = NULL; unsigned long int true_size, true_study_size = 0; size_t size, regex_gotten_store; int do_study = 0; int do_debug = debug; int do_G = 0; int do_g = 0; int do_showinfo = showinfo; int do_showrest = 0; int do_flip = 0; int erroroffset, len, delimiter; use_utf8 = 0; if (infile == stdin) printf(" re> "); if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) break; if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); fflush(outfile); p = buffer; while (isspace(*p)) p++; if (*p == 0) continue; /* See if the pattern is to be loaded pre-compiled from a file. */ if (*p == '<' && strchr((char *)(p+1), '<') == NULL) { unsigned long int magic; uschar sbuf[8]; FILE *f; p++; pp = p + (int)strlen((char *)p); while (isspace(pp[-1])) pp--; *pp = 0; f = fopen((char *)p, "rb"); if (f == NULL) { fprintf(outfile, "Failed to open %s: %s\n", p, strerror(errno)); continue; } if (fread(sbuf, 1, 8, f) != 8) goto FAIL_READ; true_size = (sbuf[0] << 24) | (sbuf[1] << 16) | (sbuf[2] << 8) | sbuf[3]; true_study_size = (sbuf[4] << 24) | (sbuf[5] << 16) | (sbuf[6] << 8) | sbuf[7]; re = (real_pcre *)new_malloc(true_size); regex_gotten_store = gotten_store; if (fread(re, 1, true_size, f) != true_size) goto FAIL_READ; magic = ((real_pcre *)re)->magic_number; if (magic != MAGIC_NUMBER) { if (byteflip(magic, sizeof(magic)) == MAGIC_NUMBER) { do_flip = 1; } else { fprintf(outfile, "Data in %s is not a compiled PCRE regex\n", p); fclose(f); continue; } } fprintf(outfile, "Compiled regex%s loaded from %s\n", do_flip? " (byte-inverted)" : "", p); /* Need to know if UTF-8 for printing data strings */ new_info(re, NULL, PCRE_INFO_OPTIONS, &options); use_utf8 = (options & PCRE_UTF8) != 0; /* Now see if there is any following study data */ if (true_study_size != 0) { pcre_study_data *psd; extra = (pcre_extra *)new_malloc(sizeof(pcre_extra) + true_study_size); extra->flags = PCRE_EXTRA_STUDY_DATA; psd = (pcre_study_data *)(((char *)extra) + sizeof(pcre_extra)); extra->study_data = psd; if (fread(psd, 1, true_study_size, f) != true_study_size) { FAIL_READ: fprintf(outfile, "Failed to read data from %s\n", p); if (extra != NULL) new_free(extra); if (re != NULL) new_free(re); fclose(f); continue; } fprintf(outfile, "Study data loaded from %s\n", p); do_study = 1; /* To get the data output if requested */ } else fprintf(outfile, "No study data\n"); fclose(f); goto SHOW_INFO; } /* In-line pattern (the usual case). Get the delimiter and seek the end of the pattern; if is isn't complete, read more. */ delimiter = *p++; if (isalnum(delimiter) || delimiter == '\\') { fprintf(outfile, "** Delimiter must not be alphameric or \\\n"); goto SKIP_DATA; } pp = p; for(;;) { while (*pp != 0) { if (*pp == '\\' && pp[1] != 0) pp++; else if (*pp == delimiter) break; pp++; } if (*pp != 0) break; len = BUFFER_SIZE - (pp - buffer); if (len < 256) { fprintf(outfile, "** Expression too long - missing delimiter?\n"); goto SKIP_DATA; } if (infile == stdin) printf(" > "); if (fgets((char *)pp, len, infile) == NULL) { fprintf(outfile, "** Unexpected EOF\n"); done = 1; goto CONTINUE; } if (infile != stdin) fprintf(outfile, "%s", (char *)pp); } /* If the first character after the delimiter is backslash, make the pattern end with backslash. This is purely to provide a way of testing for the error message when a pattern ends with backslash. */ if (pp[1] == '\\') *pp++ = '\\'; /* Terminate the pattern at the delimiter, and save a copy of the pattern for callouts. */ *pp++ = 0; strcpy((char *)pbuffer, (char *)p); /* Look for options after final delimiter */ options = 0; study_options = 0; log_store = showstore; /* default from command line */ while (*pp != 0) { switch (*pp++) { case 'g': do_g = 1; break; case 'i': options |= PCRE_CASELESS; break; case 'm': options |= PCRE_MULTILINE; break; case 's': options |= PCRE_DOTALL; break; case 'x': options |= PCRE_EXTENDED; break; case '+': do_showrest = 1; break; case 'A': options |= PCRE_ANCHORED; break; case 'C': options |= PCRE_AUTO_CALLOUT; break; case 'D': do_debug = do_showinfo = 1; break; case 'E': options |= PCRE_DOLLAR_ENDONLY; break; case 'F': do_flip = 1; break; case 'G': do_G = 1; break; case 'I': do_showinfo = 1; break; case 'M': log_store = 1; break; case 'N': options |= PCRE_NO_AUTO_CAPTURE; break; #if !defined NOPOSIX case 'P': do_posix = 1; break; #endif case 'S': do_study = 1; break; case 'U': options |= PCRE_UNGREEDY; break; case 'X': options |= PCRE_EXTRA; break; case '8': options |= PCRE_UTF8; use_utf8 = 1; break; case '?': options |= PCRE_NO_UTF8_CHECK; break; case 'L': ppp = pp; while (*ppp != '\n' && *ppp != ' ') ppp++; *ppp = 0; if (setlocale(LC_CTYPE, (const char *)pp) == NULL) { fprintf(outfile, "** Failed to set locale \"%s\"\n", pp); goto SKIP_DATA; } tables = pcre_maketables(); pp = ppp; break; case '>': to_file = pp; while (*pp != 0) pp++; while (isspace(pp[-1])) pp--; *pp = 0; break; case '\n': case ' ': break; default: fprintf(outfile, "** Unknown option '%c'\n", pp[-1]); goto SKIP_DATA; } } /* Handle compiling via the POSIX interface, which doesn't support the timing, showing, or debugging options, nor the ability to pass over local character tables. */ #if !defined NOPOSIX if (posix || do_posix) { int rc; int cflags = 0; if ((options & PCRE_CASELESS) != 0) cflags |= REG_ICASE; if ((options & PCRE_MULTILINE) != 0) cflags |= REG_NEWLINE; rc = regcomp(&preg, (char *)p, cflags); /* Compilation failed; go back for another re, skipping to blank line if non-interactive. */ if (rc != 0) { (void)regerror(rc, &preg, (char *)buffer, BUFFER_SIZE); fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer); goto SKIP_DATA; } } /* Handle compiling via the native interface */ else #endif /* !defined NOPOSIX */ { if (timeit) { register int i; clock_t time_taken; clock_t start_time = clock(); for (i = 0; i < LOOPREPEAT; i++) { re = pcre_compile((char *)p, options, &error, &erroroffset, tables); if (re != NULL) free(re); } time_taken = clock() - start_time; fprintf(outfile, "Compile time %.3f milliseconds\n", (((double)time_taken * 1000.0) / (double)LOOPREPEAT) / (double)CLOCKS_PER_SEC); } re = pcre_compile((char *)p, options, &error, &erroroffset, tables); /* Compilation failed; go back for another re, skipping to blank line if non-interactive. */ if (re == NULL) { fprintf(outfile, "Failed: %s at offset %d\n", error, erroroffset); SKIP_DATA: if (infile != stdin) { for (;;) { if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) { done = 1; goto CONTINUE; } len = (int)strlen((char *)buffer); while (len > 0 && isspace(buffer[len-1])) len--; if (len == 0) break; } fprintf(outfile, "\n"); } goto CONTINUE; } /* Compilation succeeded; print data if required. There are now two info-returning functions. The old one has a limited interface and returns only limited data. Check that it agrees with the newer one. */ if (log_store) fprintf(outfile, "Memory allocation (code space): %d\n", (int)(gotten_store - sizeof(real_pcre) - ((real_pcre *)re)->name_count * ((real_pcre *)re)->name_entry_size)); /* Extract the size for possible writing before possibly flipping it, and remember the store that was got. */ true_size = ((real_pcre *)re)->size; regex_gotten_store = gotten_store; /* If /S was present, study the regexp to generate additional info to help with the matching. */ if (do_study) { if (timeit) { register int i; clock_t time_taken; clock_t start_time = clock(); for (i = 0; i < LOOPREPEAT; i++) extra = pcre_study(re, study_options, &error); time_taken = clock() - start_time; if (extra != NULL) free(extra); fprintf(outfile, " Study time %.3f milliseconds\n", (((double)time_taken * 1000.0) / (double)LOOPREPEAT) / (double)CLOCKS_PER_SEC); } extra = pcre_study(re, study_options, &error); if (error != NULL) fprintf(outfile, "Failed to study: %s\n", error); else if (extra != NULL) true_study_size = ((pcre_study_data *)(extra->study_data))->size; } /* If the 'F' option was present, we flip the bytes of all the integer fields in the regex data block and the study block. This is to make it possible to test PCRE's handling of byte-flipped patterns, e.g. those compiled on a different architecture. */ if (do_flip) { real_pcre *rre = (real_pcre *)re; rre->magic_number = byteflip(rre->magic_number, sizeof(rre->magic_number)); rre->size = byteflip(rre->size, sizeof(rre->size)); rre->options = byteflip(rre->options, sizeof(rre->options)); rre->top_bracket = byteflip(rre->top_bracket, sizeof(rre->top_bracket)); rre->top_backref = byteflip(rre->top_backref, sizeof(rre->top_backref)); rre->first_byte = byteflip(rre->first_byte, sizeof(rre->first_byte)); rre->req_byte = byteflip(rre->req_byte, sizeof(rre->req_byte)); rre->name_table_offset = byteflip(rre->name_table_offset, sizeof(rre->name_table_offset)); rre->name_entry_size = byteflip(rre->name_entry_size, sizeof(rre->name_entry_size)); rre->name_count = byteflip(rre->name_count, sizeof(rre->name_count)); if (extra != NULL) { pcre_study_data *rsd = (pcre_study_data *)(extra->study_data); rsd->size = byteflip(rsd->size, sizeof(rsd->size)); rsd->options = byteflip(rsd->options, sizeof(rsd->options)); } } /* Extract information from the compiled data if required */ SHOW_INFO: if (do_showinfo) { unsigned long int get_options, all_options; int old_first_char, old_options, old_count; int count, backrefmax, first_char, need_char; int nameentrysize, namecount; const uschar *nametable; if (do_debug) { fprintf(outfile, "------------------------------------------------------------------\n"); print_internals(re, outfile); } new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options); new_info(re, NULL, PCRE_INFO_SIZE, &size); new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count); new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax); new_info(re, NULL, PCRE_INFO_FIRSTBYTE, &first_char); new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char); new_info(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nameentrysize); new_info(re, NULL, PCRE_INFO_NAMECOUNT, &namecount); new_info(re, NULL, PCRE_INFO_NAMETABLE, (void *)&nametable); old_count = pcre_info(re, &old_options, &old_first_char); if (count < 0) fprintf(outfile, "Error %d from pcre_info()\n", count); else { if (old_count != count) fprintf(outfile, "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count, old_count); if (old_first_char != first_char) fprintf(outfile, "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n", first_char, old_first_char); if (old_options != (int)get_options) fprintf(outfile, "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n", get_options, old_options); } if (size != regex_gotten_store) fprintf(outfile, "Size disagreement: pcre_fullinfo=%d call to malloc for %d\n", size, regex_gotten_store); fprintf(outfile, "Capturing subpattern count = %d\n", count); if (backrefmax > 0) fprintf(outfile, "Max back reference = %d\n", backrefmax); if (namecount > 0) { fprintf(outfile, "Named capturing subpatterns:\n"); while (namecount-- > 0) { fprintf(outfile, " %s %*s%3d\n", nametable + 2, nameentrysize - 3 - (int)strlen((char *)nametable + 2), "", GET2(nametable, 0)); nametable += nameentrysize; } } /* The NOPARTIAL bit is a private bit in the options, so we have to fish it out via out back door */ all_options = ((real_pcre *)re)->options; if (do_flip) { all_options = byteflip(all_options, sizeof(all_options)); } if ((all_options & PCRE_NOPARTIAL) != 0) fprintf(outfile, "Partial matching not supported\n"); if (get_options == 0) fprintf(outfile, "No options\n"); else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s%s\n", ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "", ((get_options & PCRE_CASELESS) != 0)? " caseless" : "", ((get_options & PCRE_EXTENDED) != 0)? " extended" : "", ((get_options & PCRE_MULTILINE) != 0)? " multiline" : "", ((get_options & PCRE_DOTALL) != 0)? " dotall" : "", ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "", ((get_options & PCRE_EXTRA) != 0)? " extra" : "", ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "", ((get_options & PCRE_UTF8) != 0)? " utf8" : "", ((get_options & PCRE_NO_UTF8_CHECK) != 0)? " no_utf8_check" : ""); if (((((real_pcre *)re)->options) & PCRE_ICHANGED) != 0) fprintf(outfile, "Case state changes\n"); if (first_char == -1) { fprintf(outfile, "First char at start or follows \\n\n"); } else if (first_char < 0) { fprintf(outfile, "No first char\n"); } else { int ch = first_char & 255; const char *caseless = ((first_char & REQ_CASELESS) == 0)? "" : " (caseless)"; if (isprint(ch)) fprintf(outfile, "First char = \'%c\'%s\n", ch, caseless); else fprintf(outfile, "First char = %d%s\n", ch, caseless); } if (need_char < 0) { fprintf(outfile, "No need char\n"); } else { int ch = need_char & 255; const char *caseless = ((need_char & REQ_CASELESS) == 0)? "" : " (caseless)"; if (isprint(ch)) fprintf(outfile, "Need char = \'%c\'%s\n", ch, caseless); else fprintf(outfile, "Need char = %d%s\n", ch, caseless); } /* Don't output study size; at present it is in any case a fixed value, but it varies, depending on the computer architecture, and so messes up the test suite. (And with the /F option, it might be flipped.) */ if (do_study) { if (extra == NULL) fprintf(outfile, "Study returned NULL\n"); else { uschar *start_bits = NULL; new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits); if (start_bits == NULL) fprintf(outfile, "No starting byte set\n"); else { int i; int c = 24; fprintf(outfile, "Starting byte set: "); for (i = 0; i < 256; i++) { if ((start_bits[i/8] & (1<<(i&7))) != 0) { if (c > 75) { fprintf(outfile, "\n "); c = 2; } if (isprint(i) && i != ' ') { fprintf(outfile, "%c ", i); c += 2; } else { fprintf(outfile, "\\x%02x ", i); c += 5; } } } fprintf(outfile, "\n"); } } } } /* If the '>' option was present, we write out the regex to a file, and that is all. The first 8 bytes of the file are the regex length and then the study length, in big-endian order. */ if (to_file != NULL) { FILE *f = fopen((char *)to_file, "wb"); if (f == NULL) { fprintf(outfile, "Unable to open %s: %s\n", to_file, strerror(errno)); } else { uschar sbuf[8]; sbuf[0] = (true_size >> 24) & 255; sbuf[1] = (true_size >> 16) & 255; sbuf[2] = (true_size >> 8) & 255; sbuf[3] = (true_size) & 255; sbuf[4] = (true_study_size >> 24) & 255; sbuf[5] = (true_study_size >> 16) & 255; sbuf[6] = (true_study_size >> 8) & 255; sbuf[7] = (true_study_size) & 255; if (fwrite(sbuf, 1, 8, f) < 8 || fwrite(re, 1, true_size, f) < true_size) { fprintf(outfile, "Write error on %s: %s\n", to_file, strerror(errno)); } else { fprintf(outfile, "Compiled regex written to %s\n", to_file); if (extra != NULL) { if (fwrite(extra->study_data, 1, true_study_size, f) < true_study_size) { fprintf(outfile, "Write error on %s: %s\n", to_file, strerror(errno)); } else fprintf(outfile, "Study data written to %s\n", to_file); } } fclose(f); } continue; /* With next regex */ } } /* End of non-POSIX compile */ /* Read data lines and test them */ for (;;) { unsigned char *q; unsigned char *bptr = dbuffer; int *use_offsets = offsets; int use_size_offsets = size_offsets; int callout_data = 0; int callout_data_set = 0; int count, c; int copystrings = 0; int find_match_limit = 0; int getstrings = 0; int getlist = 0; int gmatched = 0; int start_offset = 0; int g_notempty = 0; options = 0; pcre_callout = callout; first_callout = 1; callout_extra = 0; callout_count = 0; callout_fail_count = 999999; callout_fail_id = -1; show_malloc = 0; if (infile == stdin) printf("data> "); if (fgets((char *)buffer, BUFFER_SIZE, infile) == NULL) { done = 1; goto CONTINUE; } if (infile != stdin) fprintf(outfile, "%s", (char *)buffer); len = (int)strlen((char *)buffer); while (len > 0 && isspace(buffer[len-1])) len--; buffer[len] = 0; if (len == 0) break; p = buffer; while (isspace(*p)) p++; q = dbuffer; while ((c = *p++) != 0) { int i = 0; int n = 0; if (c == '\\') switch ((c = *p++)) { case 'a': c = 7; break; case 'b': c = '\b'; break; case 'e': c = 27; break; case 'f': c = '\f'; break; case 'n': c = '\n'; break; case 'r': c = '\r'; break; case 't': c = '\t'; break; case 'v': c = '\v'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': c -= '0'; while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9') c = c * 8 + *p++ - '0'; break; case 'x': /* Handle \x{..} specially - new Perl thing for utf8 */ if (*p == '{') { unsigned char *pt = p; c = 0; while (isxdigit(*(++pt))) c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W'); if (*pt == '}') { unsigned char buff8[8]; int ii, utn; utn = ord2utf8(c, buff8); for (ii = 0; ii < utn - 1; ii++) *q++ = buff8[ii]; c = buff8[ii]; /* Last byte */ p = pt + 1; break; } /* Not correct form; fall through */ } /* Ordinary \x */ c = 0; while (i++ < 2 && isxdigit(*p)) { c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'W'); p++; } break; case 0: /* \ followed by EOF allows for an empty line */ p--; continue; case '>': while(isdigit(*p)) start_offset = start_offset * 10 + *p++ - '0'; continue; case 'A': /* Option setting */ options |= PCRE_ANCHORED; continue; case 'B': options |= PCRE_NOTBOL; continue; case 'C': if (isdigit(*p)) /* Set copy string */ { while(isdigit(*p)) n = n * 10 + *p++ - '0'; copystrings |= 1 << n; } else if (isalnum(*p)) { uschar name[256]; uschar *npp = name; while (isalnum(*p)) *npp++ = *p++; *npp = 0; n = pcre_get_stringnumber(re, (char *)name); if (n < 0) fprintf(outfile, "no parentheses with name \"%s\"\n", name); else copystrings |= 1 << n; } else if (*p == '+') { callout_extra = 1; p++; } else if (*p == '-') { pcre_callout = NULL; p++; } else if (*p == '!') { callout_fail_id = 0; p++; while(isdigit(*p)) callout_fail_id = callout_fail_id * 10 + *p++ - '0'; callout_fail_count = 0; if (*p == '!') { p++; while(isdigit(*p)) callout_fail_count = callout_fail_count * 10 + *p++ - '0'; } } else if (*p == '*') { int sign = 1; callout_data = 0; if (*(++p) == '-') { sign = -1; p++; } while(isdigit(*p)) callout_data = callout_data * 10 + *p++ - '0'; callout_data *= sign; callout_data_set = 1; } continue; case 'G': if (isdigit(*p)) { while(isdigit(*p)) n = n * 10 + *p++ - '0'; getstrings |= 1 << n; } else if (isalnum(*p)) { uschar name[256]; uschar *npp = name; while (isalnum(*p)) *npp++ = *p++; *npp = 0; n = pcre_get_stringnumber(re, (char *)name); if (n < 0) fprintf(outfile, "no parentheses with name \"%s\"\n", name); else getstrings |= 1 << n; } continue; case 'L': getlist = 1; continue; case 'M': find_match_limit = 1; continue; case 'N': options |= PCRE_NOTEMPTY; continue; case 'O': while(isdigit(*p)) n = n * 10 + *p++ - '0'; if (n > size_offsets_max) { size_offsets_max = n; free(offsets); use_offsets = offsets = (int *)malloc(size_offsets_max * sizeof(int)); if (offsets == NULL) { printf("** Failed to get %d bytes of memory for offsets vector\n", size_offsets_max * sizeof(int)); return 1; } } use_size_offsets = n; if (n == 0) use_offsets = NULL; /* Ensures it can't write to it */ continue; case 'P': options |= PCRE_PARTIAL; continue; case 'S': show_malloc = 1; continue; case 'Z': options |= PCRE_NOTEOL; continue; case '?': options |= PCRE_NO_UTF8_CHECK; continue; } *q++ = c; } *q = 0; len = q - dbuffer; /* Handle matching via the POSIX interface, which does not support timing or playing with the match limit or callout data. */ #if !defined NOPOSIX if (posix || do_posix) { int rc; int eflags = 0; regmatch_t *pmatch = NULL; if (use_size_offsets > 0) pmatch = (regmatch_t *)malloc(sizeof(regmatch_t) * use_size_offsets); if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL; if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL; rc = regexec(&preg, (const char *)bptr, use_size_offsets, pmatch, eflags); if (rc != 0) { (void)regerror(rc, &preg, (char *)buffer, BUFFER_SIZE); fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer); } else { size_t i; for (i = 0; i < (size_t)use_size_offsets; i++) { if (pmatch[i].rm_so >= 0) { fprintf(outfile, "%2d: ", (int)i); (void)pchars(dbuffer + pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so, outfile); fprintf(outfile, "\n"); if (i == 0 && do_showrest) { fprintf(outfile, " 0+ "); (void)pchars(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo, outfile); fprintf(outfile, "\n"); } } } } free(pmatch); } /* Handle matching via the native interface - repeats for /g and /G */ else #endif /* !defined NOPOSIX */ for (;; gmatched++) /* Loop for /g or /G */ { if (timeit) { register int i; clock_t time_taken; clock_t start_time = clock(); for (i = 0; i < LOOPREPEAT; i++) count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); time_taken = clock() - start_time; fprintf(outfile, "Execute time %.3f milliseconds\n", (((double)time_taken * 1000.0) / (double)LOOPREPEAT) / (double)CLOCKS_PER_SEC); } /* If find_match_limit is set, we want to do repeated matches with varying limits in order to find the minimum value. */ if (find_match_limit) { int min = 0; int mid = 64; int max = -1; if (extra == NULL) { extra = (pcre_extra *)malloc(sizeof(pcre_extra)); extra->flags = 0; } extra->flags |= PCRE_EXTRA_MATCH_LIMIT; for (;;) { extra->match_limit = mid; count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); if (count == PCRE_ERROR_MATCHLIMIT) { /* fprintf(outfile, "Testing match limit = %d\n", mid); */ min = mid; mid = (mid == max - 1)? max : (max > 0)? (min + max)/2 : mid*2; } else if (count >= 0 || count == PCRE_ERROR_NOMATCH || count == PCRE_ERROR_PARTIAL) { if (mid == min + 1) { fprintf(outfile, "Minimum match limit = %d\n", mid); break; } /* fprintf(outfile, "Testing match limit = %d\n", mid); */ max = mid; mid = (min + mid)/2; } else break; /* Some other error */ } extra->flags &= ~PCRE_EXTRA_MATCH_LIMIT; } /* If callout_data is set, use the interface with additional data */ else if (callout_data_set) { if (extra == NULL) { extra = (pcre_extra *)malloc(sizeof(pcre_extra)); extra->flags = 0; } extra->flags |= PCRE_EXTRA_CALLOUT_DATA; extra->callout_data = &callout_data; count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA; } /* The normal case is just to do the match once, with the default value of match_limit. */ else { count = pcre_exec(re, extra, (char *)bptr, len, start_offset, options | g_notempty, use_offsets, use_size_offsets); } if (count == 0) { fprintf(outfile, "Matched, but too many substrings\n"); count = use_size_offsets/3; } /* Matched */ if (count >= 0) { int i; for (i = 0; i < count * 2; i += 2) { if (use_offsets[i] < 0) fprintf(outfile, "%2d: \n", i/2); else { fprintf(outfile, "%2d: ", i/2); (void)pchars(bptr + use_offsets[i], use_offsets[i+1] - use_offsets[i], outfile); fprintf(outfile, "\n"); if (i == 0) { if (do_showrest) { fprintf(outfile, " 0+ "); (void)pchars(bptr + use_offsets[i+1], len - use_offsets[i+1], outfile); fprintf(outfile, "\n"); } } } } for (i = 0; i < 32; i++) { if ((copystrings & (1 << i)) != 0) { char copybuffer[16]; int rc = pcre_copy_substring((char *)bptr, use_offsets, count, i, copybuffer, sizeof(copybuffer)); if (rc < 0) fprintf(outfile, "copy substring %d failed %d\n", i, rc); else fprintf(outfile, "%2dC %s (%d)\n", i, copybuffer, rc); } } for (i = 0; i < 32; i++) { if ((getstrings & (1 << i)) != 0) { const char *substring; int rc = pcre_get_substring((char *)bptr, use_offsets, count, i, &substring); if (rc < 0) fprintf(outfile, "get substring %d failed %d\n", i, rc); else { fprintf(outfile, "%2dG %s (%d)\n", i, substring, rc); /* free((void *)substring); */ pcre_free_substring(substring); } } } if (getlist) { const char **stringlist; int rc = pcre_get_substring_list((char *)bptr, use_offsets, count, &stringlist); if (rc < 0) fprintf(outfile, "get substring list failed %d\n", rc); else { for (i = 0; i < count; i++) fprintf(outfile, "%2dL %s\n", i, stringlist[i]); if (stringlist[i] != NULL) fprintf(outfile, "string list not terminated by NULL\n"); /* free((void *)stringlist); */ pcre_free_substring_list(stringlist); } } } /* There was a partial match */ else if (count == PCRE_ERROR_PARTIAL) { fprintf(outfile, "Partial match\n"); break; /* Out of the /g loop */ } /* Failed to match. If this is a /g or /G loop and we previously set g_notempty after a null match, this is not necessarily the end. We want to advance the start offset, and continue. In the case of UTF-8 matching, the advance must be one character, not one byte. Fudge the offset values to achieve this. We won't be at the end of the string - that was checked before setting g_notempty. */ else { if (g_notempty != 0) { int onechar = 1; use_offsets[0] = start_offset; if (use_utf8) { while (start_offset + onechar < len) { int tb = bptr[start_offset+onechar]; if (tb <= 127) break; tb &= 0xc0; if (tb != 0 && tb != 0xc0) onechar++; } } use_offsets[1] = start_offset + onechar; } else { if (count == PCRE_ERROR_NOMATCH) { if (gmatched == 0) fprintf(outfile, "No match\n"); } else fprintf(outfile, "Error %d\n", count); break; /* Out of the /g loop */ } } /* If not /g or /G we are done */ if (!do_g && !do_G) break; /* If we have matched an empty string, first check to see if we are at the end of the subject. If so, the /g loop is over. Otherwise, mimic what Perl's /g options does. This turns out to be rather cunning. First we set PCRE_NOTEMPTY and PCRE_ANCHORED and try the match again at the same point. If this fails (picked up above) we advance to the next character. */ g_notempty = 0; if (use_offsets[0] == use_offsets[1]) { if (use_offsets[0] == len) break; g_notempty = PCRE_NOTEMPTY | PCRE_ANCHORED; } /* For /g, update the start offset, leaving the rest alone */ if (do_g) start_offset = use_offsets[1]; /* For /G, update the pointer and length */ else { bptr += use_offsets[1]; len -= use_offsets[1]; } } /* End of loop for /g and /G */ } /* End of loop for data lines */ CONTINUE: #if !defined NOPOSIX if (posix || do_posix) regfree(&preg); #endif if (re != NULL) free(re); if (extra != NULL) free(extra); if (tables != NULL) { free((void *)tables); setlocale(LC_CTYPE, "C"); } } if (infile == stdin) fprintf(outfile, "\n"); return 0; } /* End */ tomcat-connectors-1.2.41-src/native/iis/pcre/install-sh0000755000000000000020000001273610517277132021340 0ustar rootbin#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 tomcat-connectors-1.2.41-src/native/iis/pcre/config.hw0000644000000000000020000001102711726336342021133 0ustar rootbin /* On Unix systems config.in is converted by configure into config.h. PCRE is written in Standard C, but there are a few non-standard things it can cope with, allowing it to run on SunOS4 and other "close to standard" systems. On a non-Unix system you should just copy this file into config.h, and set up the macros the way you need them. You should normally change the definitions of HAVE_STRERROR and HAVE_MEMMOVE to 1. Unfortunately, because of the way autoconf works, these cannot be made the defaults. If your system has bcopy() and not memmove(), change the definition of HAVE_BCOPY instead of HAVE_MEMMOVE. If your system has neither bcopy() nor memmove(), leave them both as 0; an emulation function will be used. */ /* If you are compiling for a system that uses EBCDIC instead of ASCII character codes, define this macro as 1. On systems that can use "configure", this can be done via --enable-ebcdic. */ #ifndef EBCDIC #define EBCDIC 0 #endif /* If you are compiling for a system that needs some magic to be inserted before the definition of an exported function, define this macro to contain the relevant magic. It apears at the start of every exported function. */ #define EXPORT /* Define to empty if the "const" keyword does not work. */ #undef const /* Define to "unsigned" if doesn't define size_t. */ #undef size_t /* The following two definitions are mainly for the benefit of SunOS4, which doesn't have the strerror() or memmove() functions that should be present in all Standard C libraries. The macros HAVE_STRERROR and HAVE_MEMMOVE should normally be defined with the value 1 for other systems, but unfortunately we can't make this the default because "configure" files generated by autoconf will only change 0 to 1; they won't change 1 to 0 if the functions are not found. */ #define HAVE_STRERROR 1 #define HAVE_MEMMOVE 1 /* There are some non-Unix systems that don't even have bcopy(). If this macro is false, an emulation is used. If HAVE_MEMMOVE is set to 1, the value of HAVE_BCOPY is not relevant. */ #define HAVE_BCOPY 0 /* The value of NEWLINE determines the newline character. The default is to leave it up to the compiler, but some sites want to force a particular value. On Unix systems, "configure" can be used to override this default. */ #ifndef NEWLINE #define NEWLINE '\n' #endif /* The value of LINK_SIZE determines the number of bytes used to store links as offsets within the compiled regex. The default is 2, which allows for compiled patterns up to 64K long. This covers the vast majority of cases. However, PCRE can also be compiled to use 3 or 4 bytes instead. This allows for longer patterns in extreme cases. On Unix systems, "configure" can be used to override this default. */ #ifndef LINK_SIZE #define LINK_SIZE 2 #endif /* The value of MATCH_LIMIT determines the default number of times the match() function can be called during a single execution of pcre_exec(). (There is a runtime method of setting a different limit.) The limit exists in order to catch runaway regular expressions that take for ever to determine that they do not match. The default is set very large so that it does not accidentally catch legitimate cases. On Unix systems, "configure" can be used to override this default default. */ #ifndef MATCH_LIMIT #define MATCH_LIMIT 10000000 #endif /* When calling PCRE via the POSIX interface, additional working storage is required for holding the pointers to capturing substrings because PCRE requires three integers per substring, whereas the POSIX interface provides only two. If the number of expected substrings is small, the wrapper function uses space on the stack, because this is faster than using malloc() for each call. The threshold above which the stack is no longer use is defined by POSIX_MALLOC_ THRESHOLD. On Unix systems, "configure" can be used to override this default. */ #ifndef POSIX_MALLOC_THRESHOLD #define POSIX_MALLOC_THRESHOLD 10 #endif /* PCRE uses recursive function calls to handle backtracking while matching. This can sometimes be a problem on systems that have stacks of limited size. Define NO_RECURSE to get a version that doesn't use recursion in the match() function; instead it creates its own stack by steam using pcre_recurse_malloc to get memory. For more detail, see comments and other stuff just above the match() function. On Unix systems, "configure" can be used to set this in the Makefile (use --disable-stack-for-recursion). */ /* #define NO_RECURSE */ #if defined(_MSC_VER) && _MSC_VER >= 1200 #pragma warning(disable: 4244) #pragma warning(disable: 4267) #endif /* End */ tomcat-connectors-1.2.41-src/native/iis/pcre/ucptable.c0000644000000000000020000156505610517277132021310 0ustar rootbin/* This source module is automatically generated from the Unicode property table. See internal.h for a description of the layout. */ static cnode ucp_table[] = { { 0x9a00, 0x2f1f, 0xe000 }, { 0x8700, 0x1558, 0xd000 }, { 0x8700, 0x0a99, 0xc000 }, { 0x8500, 0x0435, 0xbfe0 }, { 0x8500, 0x01ff, 0xafff }, { 0x8500, 0x00ff, 0x9079 }, { 0x8000, 0x007f, 0x8000 }, { 0x9500, 0x003f, 0x7000 }, { 0x8000, 0x001f, 0x6000 }, { 0x8000, 0x000f, 0x5000 }, { 0x8000, 0x0007, 0x4000 }, { 0x8000, 0x0003, 0x3000 }, { 0x8000, 0x0001, 0x2000 }, { 0x0000, 0x0000, 0x0000 }, { 0x0000, 0x0002, 0x0000 }, { 0x8000, 0x0005, 0x2000 }, { 0x0000, 0x0004, 0x0000 }, { 0x0000, 0x0006, 0x0000 }, { 0x8000, 0x000b, 0x3000 }, { 0x8000, 0x0009, 0x2000 }, { 0x0000, 0x0008, 0x0000 }, { 0x0000, 0x000a, 0x0000 }, { 0x8000, 0x000d, 0x2000 }, { 0x0000, 0x000c, 0x0000 }, { 0x0000, 0x000e, 0x0000 }, { 0x8000, 0x0017, 0x4000 }, { 0x8000, 0x0013, 0x3000 }, { 0x8000, 0x0011, 0x2000 }, { 0x0000, 0x0010, 0x0000 }, { 0x0000, 0x0012, 0x0000 }, { 0x8000, 0x0015, 0x2000 }, { 0x0000, 0x0014, 0x0000 }, { 0x0000, 0x0016, 0x0000 }, { 0x8000, 0x001b, 0x3000 }, { 0x8000, 0x0019, 0x2000 }, { 0x0000, 0x0018, 0x0000 }, { 0x0000, 0x001a, 0x0000 }, { 0x8000, 0x001d, 0x2000 }, { 0x0000, 0x001c, 0x0000 }, { 0x0000, 0x001e, 0x0000 }, { 0x9500, 0x002f, 0x5000 }, { 0x9500, 0x0027, 0x4000 }, { 0x9500, 0x0023, 0x3000 }, { 0x9500, 0x0021, 0x2000 }, { 0x1d00, 0x0020, 0x0000 }, { 0x1500, 0x0022, 0x0000 }, { 0x9500, 0x0025, 0x2000 }, { 0x1700, 0x0024, 0x0000 }, { 0x1500, 0x0026, 0x0000 }, { 0x9900, 0x002b, 0x3000 }, { 0x9200, 0x0029, 0x2000 }, { 0x1600, 0x0028, 0x0000 }, { 0x1500, 0x002a, 0x0000 }, { 0x9100, 0x002d, 0x2000 }, { 0x1500, 0x002c, 0x0000 }, { 0x1500, 0x002e, 0x0000 }, { 0x8d00, 0x0037, 0x4000 }, { 0x8d00, 0x0033, 0x3000 }, { 0x8d00, 0x0031, 0x2000 }, { 0x0d00, 0x0030, 0x0000 }, { 0x0d00, 0x0032, 0x0000 }, { 0x8d00, 0x0035, 0x2000 }, { 0x0d00, 0x0034, 0x0000 }, { 0x0d00, 0x0036, 0x0000 }, { 0x9500, 0x003b, 0x3000 }, { 0x8d00, 0x0039, 0x2000 }, { 0x0d00, 0x0038, 0x0000 }, { 0x1500, 0x003a, 0x0000 }, { 0x9900, 0x003d, 0x2000 }, { 0x1900, 0x003c, 0x0000 }, { 0x1900, 0x003e, 0x0000 }, { 0x9000, 0x005f, 0x6000 }, { 0x8900, 0x004f, 0x5020 }, { 0x8900, 0x0047, 0x4020 }, { 0x8900, 0x0043, 0x3020 }, { 0x8900, 0x0041, 0x2020 }, { 0x1500, 0x0040, 0x0000 }, { 0x0900, 0x0042, 0x0020 }, { 0x8900, 0x0045, 0x2020 }, { 0x0900, 0x0044, 0x0020 }, { 0x0900, 0x0046, 0x0020 }, { 0x8900, 0x004b, 0x3020 }, { 0x8900, 0x0049, 0x2020 }, { 0x0900, 0x0048, 0x0020 }, { 0x0900, 0x004a, 0x0020 }, { 0x8900, 0x004d, 0x2020 }, { 0x0900, 0x004c, 0x0020 }, { 0x0900, 0x004e, 0x0020 }, { 0x8900, 0x0057, 0x4020 }, { 0x8900, 0x0053, 0x3020 }, { 0x8900, 0x0051, 0x2020 }, { 0x0900, 0x0050, 0x0020 }, { 0x0900, 0x0052, 0x0020 }, { 0x8900, 0x0055, 0x2020 }, { 0x0900, 0x0054, 0x0020 }, { 0x0900, 0x0056, 0x0020 }, { 0x9600, 0x005b, 0x3000 }, { 0x8900, 0x0059, 0x2020 }, { 0x0900, 0x0058, 0x0020 }, { 0x0900, 0x005a, 0x0020 }, { 0x9200, 0x005d, 0x2000 }, { 0x1500, 0x005c, 0x0000 }, { 0x1800, 0x005e, 0x0000 }, { 0x8500, 0x006f, 0x5fe0 }, { 0x8500, 0x0067, 0x4fe0 }, { 0x8500, 0x0063, 0x3fe0 }, { 0x8500, 0x0061, 0x2fe0 }, { 0x1800, 0x0060, 0x0000 }, { 0x0500, 0x0062, 0x0fe0 }, { 0x8500, 0x0065, 0x2fe0 }, { 0x0500, 0x0064, 0x0fe0 }, { 0x0500, 0x0066, 0x0fe0 }, { 0x8500, 0x006b, 0x3fe0 }, { 0x8500, 0x0069, 0x2fe0 }, { 0x0500, 0x0068, 0x0fe0 }, { 0x0500, 0x006a, 0x0fe0 }, { 0x8500, 0x006d, 0x2fe0 }, { 0x0500, 0x006c, 0x0fe0 }, { 0x0500, 0x006e, 0x0fe0 }, { 0x8500, 0x0077, 0x4fe0 }, { 0x8500, 0x0073, 0x3fe0 }, { 0x8500, 0x0071, 0x2fe0 }, { 0x0500, 0x0070, 0x0fe0 }, { 0x0500, 0x0072, 0x0fe0 }, { 0x8500, 0x0075, 0x2fe0 }, { 0x0500, 0x0074, 0x0fe0 }, { 0x0500, 0x0076, 0x0fe0 }, { 0x9600, 0x007b, 0x3000 }, { 0x8500, 0x0079, 0x2fe0 }, { 0x0500, 0x0078, 0x0fe0 }, { 0x0500, 0x007a, 0x0fe0 }, { 0x9200, 0x007d, 0x2000 }, { 0x1900, 0x007c, 0x0000 }, { 0x1900, 0x007e, 0x0000 }, { 0x9500, 0x00bf, 0x7000 }, { 0x8000, 0x009f, 0x6000 }, { 0x8000, 0x008f, 0x5000 }, { 0x8000, 0x0087, 0x4000 }, { 0x8000, 0x0083, 0x3000 }, { 0x8000, 0x0081, 0x2000 }, { 0x0000, 0x0080, 0x0000 }, { 0x0000, 0x0082, 0x0000 }, { 0x8000, 0x0085, 0x2000 }, { 0x0000, 0x0084, 0x0000 }, { 0x0000, 0x0086, 0x0000 }, { 0x8000, 0x008b, 0x3000 }, { 0x8000, 0x0089, 0x2000 }, { 0x0000, 0x0088, 0x0000 }, { 0x0000, 0x008a, 0x0000 }, { 0x8000, 0x008d, 0x2000 }, { 0x0000, 0x008c, 0x0000 }, { 0x0000, 0x008e, 0x0000 }, { 0x8000, 0x0097, 0x4000 }, { 0x8000, 0x0093, 0x3000 }, { 0x8000, 0x0091, 0x2000 }, { 0x0000, 0x0090, 0x0000 }, { 0x0000, 0x0092, 0x0000 }, { 0x8000, 0x0095, 0x2000 }, { 0x0000, 0x0094, 0x0000 }, { 0x0000, 0x0096, 0x0000 }, { 0x8000, 0x009b, 0x3000 }, { 0x8000, 0x0099, 0x2000 }, { 0x0000, 0x0098, 0x0000 }, { 0x0000, 0x009a, 0x0000 }, { 0x8000, 0x009d, 0x2000 }, { 0x0000, 0x009c, 0x0000 }, { 0x0000, 0x009e, 0x0000 }, { 0x9800, 0x00af, 0x5000 }, { 0x9a00, 0x00a7, 0x4000 }, { 0x9700, 0x00a3, 0x3000 }, { 0x9500, 0x00a1, 0x2000 }, { 0x1d00, 0x00a0, 0x0000 }, { 0x1700, 0x00a2, 0x0000 }, { 0x9700, 0x00a5, 0x2000 }, { 0x1700, 0x00a4, 0x0000 }, { 0x1a00, 0x00a6, 0x0000 }, { 0x9400, 0x00ab, 0x3000 }, { 0x9a00, 0x00a9, 0x2000 }, { 0x1800, 0x00a8, 0x0000 }, { 0x0500, 0x00aa, 0x0000 }, { 0x8100, 0x00ad, 0x2000 }, { 0x1900, 0x00ac, 0x0000 }, { 0x1a00, 0x00ae, 0x0000 }, { 0x9500, 0x00b7, 0x4000 }, { 0x8f00, 0x00b3, 0x3000 }, { 0x9900, 0x00b1, 0x2000 }, { 0x1a00, 0x00b0, 0x0000 }, { 0x0f00, 0x00b2, 0x0000 }, { 0x8500, 0x00b5, 0x22e7 }, { 0x1800, 0x00b4, 0x0000 }, { 0x1a00, 0x00b6, 0x0000 }, { 0x9300, 0x00bb, 0x3000 }, { 0x8f00, 0x00b9, 0x2000 }, { 0x1800, 0x00b8, 0x0000 }, { 0x0500, 0x00ba, 0x0000 }, { 0x8f00, 0x00bd, 0x2000 }, { 0x0f00, 0x00bc, 0x0000 }, { 0x0f00, 0x00be, 0x0000 }, { 0x8500, 0x00df, 0x6000 }, { 0x8900, 0x00cf, 0x5020 }, { 0x8900, 0x00c7, 0x4020 }, { 0x8900, 0x00c3, 0x3020 }, { 0x8900, 0x00c1, 0x2020 }, { 0x0900, 0x00c0, 0x0020 }, { 0x0900, 0x00c2, 0x0020 }, { 0x8900, 0x00c5, 0x2020 }, { 0x0900, 0x00c4, 0x0020 }, { 0x0900, 0x00c6, 0x0020 }, { 0x8900, 0x00cb, 0x3020 }, { 0x8900, 0x00c9, 0x2020 }, { 0x0900, 0x00c8, 0x0020 }, { 0x0900, 0x00ca, 0x0020 }, { 0x8900, 0x00cd, 0x2020 }, { 0x0900, 0x00cc, 0x0020 }, { 0x0900, 0x00ce, 0x0020 }, { 0x9900, 0x00d7, 0x4000 }, { 0x8900, 0x00d3, 0x3020 }, { 0x8900, 0x00d1, 0x2020 }, { 0x0900, 0x00d0, 0x0020 }, { 0x0900, 0x00d2, 0x0020 }, { 0x8900, 0x00d5, 0x2020 }, { 0x0900, 0x00d4, 0x0020 }, { 0x0900, 0x00d6, 0x0020 }, { 0x8900, 0x00db, 0x3020 }, { 0x8900, 0x00d9, 0x2020 }, { 0x0900, 0x00d8, 0x0020 }, { 0x0900, 0x00da, 0x0020 }, { 0x8900, 0x00dd, 0x2020 }, { 0x0900, 0x00dc, 0x0020 }, { 0x0900, 0x00de, 0x0020 }, { 0x8500, 0x00ef, 0x5fe0 }, { 0x8500, 0x00e7, 0x4fe0 }, { 0x8500, 0x00e3, 0x3fe0 }, { 0x8500, 0x00e1, 0x2fe0 }, { 0x0500, 0x00e0, 0x0fe0 }, { 0x0500, 0x00e2, 0x0fe0 }, { 0x8500, 0x00e5, 0x2fe0 }, { 0x0500, 0x00e4, 0x0fe0 }, { 0x0500, 0x00e6, 0x0fe0 }, { 0x8500, 0x00eb, 0x3fe0 }, { 0x8500, 0x00e9, 0x2fe0 }, { 0x0500, 0x00e8, 0x0fe0 }, { 0x0500, 0x00ea, 0x0fe0 }, { 0x8500, 0x00ed, 0x2fe0 }, { 0x0500, 0x00ec, 0x0fe0 }, { 0x0500, 0x00ee, 0x0fe0 }, { 0x9900, 0x00f7, 0x4000 }, { 0x8500, 0x00f3, 0x3fe0 }, { 0x8500, 0x00f1, 0x2fe0 }, { 0x0500, 0x00f0, 0x0fe0 }, { 0x0500, 0x00f2, 0x0fe0 }, { 0x8500, 0x00f5, 0x2fe0 }, { 0x0500, 0x00f4, 0x0fe0 }, { 0x0500, 0x00f6, 0x0fe0 }, { 0x8500, 0x00fb, 0x3fe0 }, { 0x8500, 0x00f9, 0x2fe0 }, { 0x0500, 0x00f8, 0x0fe0 }, { 0x0500, 0x00fa, 0x0fe0 }, { 0x8500, 0x00fd, 0x2fe0 }, { 0x0500, 0x00fc, 0x0fe0 }, { 0x0500, 0x00fe, 0x0fe0 }, { 0x8500, 0x017f, 0x8ed4 }, { 0x8900, 0x013f, 0x7001 }, { 0x8500, 0x011f, 0x6fff }, { 0x8500, 0x010f, 0x5fff }, { 0x8500, 0x0107, 0x4fff }, { 0x8500, 0x0103, 0x3fff }, { 0x8500, 0x0101, 0x2fff }, { 0x0900, 0x0100, 0x0001 }, { 0x0900, 0x0102, 0x0001 }, { 0x8500, 0x0105, 0x2fff }, { 0x0900, 0x0104, 0x0001 }, { 0x0900, 0x0106, 0x0001 }, { 0x8500, 0x010b, 0x3fff }, { 0x8500, 0x0109, 0x2fff }, { 0x0900, 0x0108, 0x0001 }, { 0x0900, 0x010a, 0x0001 }, { 0x8500, 0x010d, 0x2fff }, { 0x0900, 0x010c, 0x0001 }, { 0x0900, 0x010e, 0x0001 }, { 0x8500, 0x0117, 0x4fff }, { 0x8500, 0x0113, 0x3fff }, { 0x8500, 0x0111, 0x2fff }, { 0x0900, 0x0110, 0x0001 }, { 0x0900, 0x0112, 0x0001 }, { 0x8500, 0x0115, 0x2fff }, { 0x0900, 0x0114, 0x0001 }, { 0x0900, 0x0116, 0x0001 }, { 0x8500, 0x011b, 0x3fff }, { 0x8500, 0x0119, 0x2fff }, { 0x0900, 0x0118, 0x0001 }, { 0x0900, 0x011a, 0x0001 }, { 0x8500, 0x011d, 0x2fff }, { 0x0900, 0x011c, 0x0001 }, { 0x0900, 0x011e, 0x0001 }, { 0x8500, 0x012f, 0x5fff }, { 0x8500, 0x0127, 0x4fff }, { 0x8500, 0x0123, 0x3fff }, { 0x8500, 0x0121, 0x2fff }, { 0x0900, 0x0120, 0x0001 }, { 0x0900, 0x0122, 0x0001 }, { 0x8500, 0x0125, 0x2fff }, { 0x0900, 0x0124, 0x0001 }, { 0x0900, 0x0126, 0x0001 }, { 0x8500, 0x012b, 0x3fff }, { 0x8500, 0x0129, 0x2fff }, { 0x0900, 0x0128, 0x0001 }, { 0x0900, 0x012a, 0x0001 }, { 0x8500, 0x012d, 0x2fff }, { 0x0900, 0x012c, 0x0001 }, { 0x0900, 0x012e, 0x0001 }, { 0x8500, 0x0137, 0x4fff }, { 0x8500, 0x0133, 0x3fff }, { 0x8500, 0x0131, 0x2f18 }, { 0x0900, 0x0130, 0x0f39 }, { 0x0900, 0x0132, 0x0001 }, { 0x8500, 0x0135, 0x2fff }, { 0x0900, 0x0134, 0x0001 }, { 0x0900, 0x0136, 0x0001 }, { 0x8900, 0x013b, 0x3001 }, { 0x8900, 0x0139, 0x2001 }, { 0x0500, 0x0138, 0x0000 }, { 0x0500, 0x013a, 0x0fff }, { 0x8900, 0x013d, 0x2001 }, { 0x0500, 0x013c, 0x0fff }, { 0x0500, 0x013e, 0x0fff }, { 0x8500, 0x015f, 0x6fff }, { 0x8500, 0x014f, 0x5fff }, { 0x8900, 0x0147, 0x4001 }, { 0x8900, 0x0143, 0x3001 }, { 0x8900, 0x0141, 0x2001 }, { 0x0500, 0x0140, 0x0fff }, { 0x0500, 0x0142, 0x0fff }, { 0x8900, 0x0145, 0x2001 }, { 0x0500, 0x0144, 0x0fff }, { 0x0500, 0x0146, 0x0fff }, { 0x8500, 0x014b, 0x3fff }, { 0x8500, 0x0149, 0x2000 }, { 0x0500, 0x0148, 0x0fff }, { 0x0900, 0x014a, 0x0001 }, { 0x8500, 0x014d, 0x2fff }, { 0x0900, 0x014c, 0x0001 }, { 0x0900, 0x014e, 0x0001 }, { 0x8500, 0x0157, 0x4fff }, { 0x8500, 0x0153, 0x3fff }, { 0x8500, 0x0151, 0x2fff }, { 0x0900, 0x0150, 0x0001 }, { 0x0900, 0x0152, 0x0001 }, { 0x8500, 0x0155, 0x2fff }, { 0x0900, 0x0154, 0x0001 }, { 0x0900, 0x0156, 0x0001 }, { 0x8500, 0x015b, 0x3fff }, { 0x8500, 0x0159, 0x2fff }, { 0x0900, 0x0158, 0x0001 }, { 0x0900, 0x015a, 0x0001 }, { 0x8500, 0x015d, 0x2fff }, { 0x0900, 0x015c, 0x0001 }, { 0x0900, 0x015e, 0x0001 }, { 0x8500, 0x016f, 0x5fff }, { 0x8500, 0x0167, 0x4fff }, { 0x8500, 0x0163, 0x3fff }, { 0x8500, 0x0161, 0x2fff }, { 0x0900, 0x0160, 0x0001 }, { 0x0900, 0x0162, 0x0001 }, { 0x8500, 0x0165, 0x2fff }, { 0x0900, 0x0164, 0x0001 }, { 0x0900, 0x0166, 0x0001 }, { 0x8500, 0x016b, 0x3fff }, { 0x8500, 0x0169, 0x2fff }, { 0x0900, 0x0168, 0x0001 }, { 0x0900, 0x016a, 0x0001 }, { 0x8500, 0x016d, 0x2fff }, { 0x0900, 0x016c, 0x0001 }, { 0x0900, 0x016e, 0x0001 }, { 0x8500, 0x0177, 0x4fff }, { 0x8500, 0x0173, 0x3fff }, { 0x8500, 0x0171, 0x2fff }, { 0x0900, 0x0170, 0x0001 }, { 0x0900, 0x0172, 0x0001 }, { 0x8500, 0x0175, 0x2fff }, { 0x0900, 0x0174, 0x0001 }, { 0x0900, 0x0176, 0x0001 }, { 0x8900, 0x017b, 0x3001 }, { 0x8900, 0x0179, 0x2001 }, { 0x0900, 0x0178, 0x0f87 }, { 0x0500, 0x017a, 0x0fff }, { 0x8900, 0x017d, 0x2001 }, { 0x0500, 0x017c, 0x0fff }, { 0x0500, 0x017e, 0x0fff }, { 0x8500, 0x01bf, 0x7038 }, { 0x8900, 0x019f, 0x60d6 }, { 0x8900, 0x018f, 0x50ca }, { 0x8900, 0x0187, 0x4001 }, { 0x8500, 0x0183, 0x3fff }, { 0x8900, 0x0181, 0x20d2 }, { 0x0500, 0x0180, 0x0000 }, { 0x0900, 0x0182, 0x0001 }, { 0x8500, 0x0185, 0x2fff }, { 0x0900, 0x0184, 0x0001 }, { 0x0900, 0x0186, 0x00ce }, { 0x8900, 0x018b, 0x3001 }, { 0x8900, 0x0189, 0x20cd }, { 0x0500, 0x0188, 0x0fff }, { 0x0900, 0x018a, 0x00cd }, { 0x8500, 0x018d, 0x2000 }, { 0x0500, 0x018c, 0x0fff }, { 0x0900, 0x018e, 0x004f }, { 0x8900, 0x0197, 0x40d1 }, { 0x8900, 0x0193, 0x30cd }, { 0x8900, 0x0191, 0x2001 }, { 0x0900, 0x0190, 0x00cb }, { 0x0500, 0x0192, 0x0fff }, { 0x8500, 0x0195, 0x2061 }, { 0x0900, 0x0194, 0x00cf }, { 0x0900, 0x0196, 0x00d3 }, { 0x8500, 0x019b, 0x3000 }, { 0x8500, 0x0199, 0x2fff }, { 0x0900, 0x0198, 0x0001 }, { 0x0500, 0x019a, 0x0000 }, { 0x8900, 0x019d, 0x20d5 }, { 0x0900, 0x019c, 0x00d3 }, { 0x0500, 0x019e, 0x0082 }, { 0x8900, 0x01af, 0x5001 }, { 0x8900, 0x01a7, 0x4001 }, { 0x8500, 0x01a3, 0x3fff }, { 0x8500, 0x01a1, 0x2fff }, { 0x0900, 0x01a0, 0x0001 }, { 0x0900, 0x01a2, 0x0001 }, { 0x8500, 0x01a5, 0x2fff }, { 0x0900, 0x01a4, 0x0001 }, { 0x0900, 0x01a6, 0x00da }, { 0x8500, 0x01ab, 0x3000 }, { 0x8900, 0x01a9, 0x20da }, { 0x0500, 0x01a8, 0x0fff }, { 0x0500, 0x01aa, 0x0000 }, { 0x8500, 0x01ad, 0x2fff }, { 0x0900, 0x01ac, 0x0001 }, { 0x0900, 0x01ae, 0x00da }, { 0x8900, 0x01b7, 0x40db }, { 0x8900, 0x01b3, 0x3001 }, { 0x8900, 0x01b1, 0x20d9 }, { 0x0500, 0x01b0, 0x0fff }, { 0x0900, 0x01b2, 0x00d9 }, { 0x8900, 0x01b5, 0x2001 }, { 0x0500, 0x01b4, 0x0fff }, { 0x0500, 0x01b6, 0x0fff }, { 0x8700, 0x01bb, 0x3000 }, { 0x8500, 0x01b9, 0x2fff }, { 0x0900, 0x01b8, 0x0001 }, { 0x0500, 0x01ba, 0x0000 }, { 0x8500, 0x01bd, 0x2fff }, { 0x0900, 0x01bc, 0x0001 }, { 0x0500, 0x01be, 0x0000 }, { 0x8500, 0x01df, 0x6fff }, { 0x8900, 0x01cf, 0x5001 }, { 0x8900, 0x01c7, 0x4002 }, { 0x8700, 0x01c3, 0x3000 }, { 0x8700, 0x01c1, 0x2000 }, { 0x0700, 0x01c0, 0x0000 }, { 0x0700, 0x01c2, 0x0000 }, { 0x8800, 0x01c5, 0x2000 }, { 0x0900, 0x01c4, 0x0002 }, { 0x0500, 0x01c6, 0x0ffe }, { 0x8800, 0x01cb, 0x3000 }, { 0x8500, 0x01c9, 0x2ffe }, { 0x0800, 0x01c8, 0x0000 }, { 0x0900, 0x01ca, 0x0002 }, { 0x8900, 0x01cd, 0x2001 }, { 0x0500, 0x01cc, 0x0ffe }, { 0x0500, 0x01ce, 0x0fff }, { 0x8900, 0x01d7, 0x4001 }, { 0x8900, 0x01d3, 0x3001 }, { 0x8900, 0x01d1, 0x2001 }, { 0x0500, 0x01d0, 0x0fff }, { 0x0500, 0x01d2, 0x0fff }, { 0x8900, 0x01d5, 0x2001 }, { 0x0500, 0x01d4, 0x0fff }, { 0x0500, 0x01d6, 0x0fff }, { 0x8900, 0x01db, 0x3001 }, { 0x8900, 0x01d9, 0x2001 }, { 0x0500, 0x01d8, 0x0fff }, { 0x0500, 0x01da, 0x0fff }, { 0x8500, 0x01dd, 0x2fb1 }, { 0x0500, 0x01dc, 0x0fff }, { 0x0900, 0x01de, 0x0001 }, { 0x8500, 0x01ef, 0x5fff }, { 0x8500, 0x01e7, 0x4fff }, { 0x8500, 0x01e3, 0x3fff }, { 0x8500, 0x01e1, 0x2fff }, { 0x0900, 0x01e0, 0x0001 }, { 0x0900, 0x01e2, 0x0001 }, { 0x8500, 0x01e5, 0x2fff }, { 0x0900, 0x01e4, 0x0001 }, { 0x0900, 0x01e6, 0x0001 }, { 0x8500, 0x01eb, 0x3fff }, { 0x8500, 0x01e9, 0x2fff }, { 0x0900, 0x01e8, 0x0001 }, { 0x0900, 0x01ea, 0x0001 }, { 0x8500, 0x01ed, 0x2fff }, { 0x0900, 0x01ec, 0x0001 }, { 0x0900, 0x01ee, 0x0001 }, { 0x8900, 0x01f7, 0x4fc8 }, { 0x8500, 0x01f3, 0x3ffe }, { 0x8900, 0x01f1, 0x2002 }, { 0x0500, 0x01f0, 0x0000 }, { 0x0800, 0x01f2, 0x0000 }, { 0x8500, 0x01f5, 0x2fff }, { 0x0900, 0x01f4, 0x0001 }, { 0x0900, 0x01f6, 0x0f9f }, { 0x8500, 0x01fb, 0x3fff }, { 0x8500, 0x01f9, 0x2fff }, { 0x0900, 0x01f8, 0x0001 }, { 0x0900, 0x01fa, 0x0001 }, { 0x8500, 0x01fd, 0x2fff }, { 0x0900, 0x01fc, 0x0001 }, { 0x0900, 0x01fe, 0x0001 }, { 0x8c00, 0x0318, 0x9000 }, { 0x8500, 0x0298, 0x8000 }, { 0x8500, 0x0258, 0x7000 }, { 0x8500, 0x021f, 0x6fff }, { 0x8500, 0x020f, 0x5fff }, { 0x8500, 0x0207, 0x4fff }, { 0x8500, 0x0203, 0x3fff }, { 0x8500, 0x0201, 0x2fff }, { 0x0900, 0x0200, 0x0001 }, { 0x0900, 0x0202, 0x0001 }, { 0x8500, 0x0205, 0x2fff }, { 0x0900, 0x0204, 0x0001 }, { 0x0900, 0x0206, 0x0001 }, { 0x8500, 0x020b, 0x3fff }, { 0x8500, 0x0209, 0x2fff }, { 0x0900, 0x0208, 0x0001 }, { 0x0900, 0x020a, 0x0001 }, { 0x8500, 0x020d, 0x2fff }, { 0x0900, 0x020c, 0x0001 }, { 0x0900, 0x020e, 0x0001 }, { 0x8500, 0x0217, 0x4fff }, { 0x8500, 0x0213, 0x3fff }, { 0x8500, 0x0211, 0x2fff }, { 0x0900, 0x0210, 0x0001 }, { 0x0900, 0x0212, 0x0001 }, { 0x8500, 0x0215, 0x2fff }, { 0x0900, 0x0214, 0x0001 }, { 0x0900, 0x0216, 0x0001 }, { 0x8500, 0x021b, 0x3fff }, { 0x8500, 0x0219, 0x2fff }, { 0x0900, 0x0218, 0x0001 }, { 0x0900, 0x021a, 0x0001 }, { 0x8500, 0x021d, 0x2fff }, { 0x0900, 0x021c, 0x0001 }, { 0x0900, 0x021e, 0x0001 }, { 0x8500, 0x022f, 0x5fff }, { 0x8500, 0x0227, 0x4fff }, { 0x8500, 0x0223, 0x3fff }, { 0x8500, 0x0221, 0x2000 }, { 0x0900, 0x0220, 0x0f7e }, { 0x0900, 0x0222, 0x0001 }, { 0x8500, 0x0225, 0x2fff }, { 0x0900, 0x0224, 0x0001 }, { 0x0900, 0x0226, 0x0001 }, { 0x8500, 0x022b, 0x3fff }, { 0x8500, 0x0229, 0x2fff }, { 0x0900, 0x0228, 0x0001 }, { 0x0900, 0x022a, 0x0001 }, { 0x8500, 0x022d, 0x2fff }, { 0x0900, 0x022c, 0x0001 }, { 0x0900, 0x022e, 0x0001 }, { 0x8500, 0x0250, 0x4000 }, { 0x8500, 0x0233, 0x3fff }, { 0x8500, 0x0231, 0x2fff }, { 0x0900, 0x0230, 0x0001 }, { 0x0900, 0x0232, 0x0001 }, { 0x8500, 0x0235, 0x2000 }, { 0x0500, 0x0234, 0x0000 }, { 0x0500, 0x0236, 0x0000 }, { 0x8500, 0x0254, 0x3f32 }, { 0x8500, 0x0252, 0x2000 }, { 0x0500, 0x0251, 0x0000 }, { 0x0500, 0x0253, 0x0f2e }, { 0x8500, 0x0256, 0x2f33 }, { 0x0500, 0x0255, 0x0000 }, { 0x0500, 0x0257, 0x0f33 }, { 0x8500, 0x0278, 0x6000 }, { 0x8500, 0x0268, 0x5f2f }, { 0x8500, 0x0260, 0x4f33 }, { 0x8500, 0x025c, 0x3000 }, { 0x8500, 0x025a, 0x2000 }, { 0x0500, 0x0259, 0x0f36 }, { 0x0500, 0x025b, 0x0f35 }, { 0x8500, 0x025e, 0x2000 }, { 0x0500, 0x025d, 0x0000 }, { 0x0500, 0x025f, 0x0000 }, { 0x8500, 0x0264, 0x3000 }, { 0x8500, 0x0262, 0x2000 }, { 0x0500, 0x0261, 0x0000 }, { 0x0500, 0x0263, 0x0f31 }, { 0x8500, 0x0266, 0x2000 }, { 0x0500, 0x0265, 0x0000 }, { 0x0500, 0x0267, 0x0000 }, { 0x8500, 0x0270, 0x4000 }, { 0x8500, 0x026c, 0x3000 }, { 0x8500, 0x026a, 0x2000 }, { 0x0500, 0x0269, 0x0f2d }, { 0x0500, 0x026b, 0x0000 }, { 0x8500, 0x026e, 0x2000 }, { 0x0500, 0x026d, 0x0000 }, { 0x0500, 0x026f, 0x0f2d }, { 0x8500, 0x0274, 0x3000 }, { 0x8500, 0x0272, 0x2f2b }, { 0x0500, 0x0271, 0x0000 }, { 0x0500, 0x0273, 0x0000 }, { 0x8500, 0x0276, 0x2000 }, { 0x0500, 0x0275, 0x0f2a }, { 0x0500, 0x0277, 0x0000 }, { 0x8500, 0x0288, 0x5f26 }, { 0x8500, 0x0280, 0x4f26 }, { 0x8500, 0x027c, 0x3000 }, { 0x8500, 0x027a, 0x2000 }, { 0x0500, 0x0279, 0x0000 }, { 0x0500, 0x027b, 0x0000 }, { 0x8500, 0x027e, 0x2000 }, { 0x0500, 0x027d, 0x0000 }, { 0x0500, 0x027f, 0x0000 }, { 0x8500, 0x0284, 0x3000 }, { 0x8500, 0x0282, 0x2000 }, { 0x0500, 0x0281, 0x0000 }, { 0x0500, 0x0283, 0x0f26 }, { 0x8500, 0x0286, 0x2000 }, { 0x0500, 0x0285, 0x0000 }, { 0x0500, 0x0287, 0x0000 }, { 0x8500, 0x0290, 0x4000 }, { 0x8500, 0x028c, 0x3000 }, { 0x8500, 0x028a, 0x2f27 }, { 0x0500, 0x0289, 0x0000 }, { 0x0500, 0x028b, 0x0f27 }, { 0x8500, 0x028e, 0x2000 }, { 0x0500, 0x028d, 0x0000 }, { 0x0500, 0x028f, 0x0000 }, { 0x8500, 0x0294, 0x3000 }, { 0x8500, 0x0292, 0x2f25 }, { 0x0500, 0x0291, 0x0000 }, { 0x0500, 0x0293, 0x0000 }, { 0x8500, 0x0296, 0x2000 }, { 0x0500, 0x0295, 0x0000 }, { 0x0500, 0x0297, 0x0000 }, { 0x9800, 0x02d8, 0x7000 }, { 0x8600, 0x02b8, 0x6000 }, { 0x8500, 0x02a8, 0x5000 }, { 0x8500, 0x02a0, 0x4000 }, { 0x8500, 0x029c, 0x3000 }, { 0x8500, 0x029a, 0x2000 }, { 0x0500, 0x0299, 0x0000 }, { 0x0500, 0x029b, 0x0000 }, { 0x8500, 0x029e, 0x2000 }, { 0x0500, 0x029d, 0x0000 }, { 0x0500, 0x029f, 0x0000 }, { 0x8500, 0x02a4, 0x3000 }, { 0x8500, 0x02a2, 0x2000 }, { 0x0500, 0x02a1, 0x0000 }, { 0x0500, 0x02a3, 0x0000 }, { 0x8500, 0x02a6, 0x2000 }, { 0x0500, 0x02a5, 0x0000 }, { 0x0500, 0x02a7, 0x0000 }, { 0x8600, 0x02b0, 0x4000 }, { 0x8500, 0x02ac, 0x3000 }, { 0x8500, 0x02aa, 0x2000 }, { 0x0500, 0x02a9, 0x0000 }, { 0x0500, 0x02ab, 0x0000 }, { 0x8500, 0x02ae, 0x2000 }, { 0x0500, 0x02ad, 0x0000 }, { 0x0500, 0x02af, 0x0000 }, { 0x8600, 0x02b4, 0x3000 }, { 0x8600, 0x02b2, 0x2000 }, { 0x0600, 0x02b1, 0x0000 }, { 0x0600, 0x02b3, 0x0000 }, { 0x8600, 0x02b6, 0x2000 }, { 0x0600, 0x02b5, 0x0000 }, { 0x0600, 0x02b7, 0x0000 }, { 0x8600, 0x02c8, 0x5000 }, { 0x8600, 0x02c0, 0x4000 }, { 0x8600, 0x02bc, 0x3000 }, { 0x8600, 0x02ba, 0x2000 }, { 0x0600, 0x02b9, 0x0000 }, { 0x0600, 0x02bb, 0x0000 }, { 0x8600, 0x02be, 0x2000 }, { 0x0600, 0x02bd, 0x0000 }, { 0x0600, 0x02bf, 0x0000 }, { 0x9800, 0x02c4, 0x3000 }, { 0x9800, 0x02c2, 0x2000 }, { 0x0600, 0x02c1, 0x0000 }, { 0x1800, 0x02c3, 0x0000 }, { 0x8600, 0x02c6, 0x2000 }, { 0x1800, 0x02c5, 0x0000 }, { 0x0600, 0x02c7, 0x0000 }, { 0x8600, 0x02d0, 0x4000 }, { 0x8600, 0x02cc, 0x3000 }, { 0x8600, 0x02ca, 0x2000 }, { 0x0600, 0x02c9, 0x0000 }, { 0x0600, 0x02cb, 0x0000 }, { 0x8600, 0x02ce, 0x2000 }, { 0x0600, 0x02cd, 0x0000 }, { 0x0600, 0x02cf, 0x0000 }, { 0x9800, 0x02d4, 0x3000 }, { 0x9800, 0x02d2, 0x2000 }, { 0x0600, 0x02d1, 0x0000 }, { 0x1800, 0x02d3, 0x0000 }, { 0x9800, 0x02d6, 0x2000 }, { 0x1800, 0x02d5, 0x0000 }, { 0x1800, 0x02d7, 0x0000 }, { 0x9800, 0x02f8, 0x6000 }, { 0x9800, 0x02e8, 0x5000 }, { 0x8600, 0x02e0, 0x4000 }, { 0x9800, 0x02dc, 0x3000 }, { 0x9800, 0x02da, 0x2000 }, { 0x1800, 0x02d9, 0x0000 }, { 0x1800, 0x02db, 0x0000 }, { 0x9800, 0x02de, 0x2000 }, { 0x1800, 0x02dd, 0x0000 }, { 0x1800, 0x02df, 0x0000 }, { 0x8600, 0x02e4, 0x3000 }, { 0x8600, 0x02e2, 0x2000 }, { 0x0600, 0x02e1, 0x0000 }, { 0x0600, 0x02e3, 0x0000 }, { 0x9800, 0x02e6, 0x2000 }, { 0x1800, 0x02e5, 0x0000 }, { 0x1800, 0x02e7, 0x0000 }, { 0x9800, 0x02f0, 0x4000 }, { 0x9800, 0x02ec, 0x3000 }, { 0x9800, 0x02ea, 0x2000 }, { 0x1800, 0x02e9, 0x0000 }, { 0x1800, 0x02eb, 0x0000 }, { 0x8600, 0x02ee, 0x2000 }, { 0x1800, 0x02ed, 0x0000 }, { 0x1800, 0x02ef, 0x0000 }, { 0x9800, 0x02f4, 0x3000 }, { 0x9800, 0x02f2, 0x2000 }, { 0x1800, 0x02f1, 0x0000 }, { 0x1800, 0x02f3, 0x0000 }, { 0x9800, 0x02f6, 0x2000 }, { 0x1800, 0x02f5, 0x0000 }, { 0x1800, 0x02f7, 0x0000 }, { 0x8c00, 0x0308, 0x5000 }, { 0x8c00, 0x0300, 0x4000 }, { 0x9800, 0x02fc, 0x3000 }, { 0x9800, 0x02fa, 0x2000 }, { 0x1800, 0x02f9, 0x0000 }, { 0x1800, 0x02fb, 0x0000 }, { 0x9800, 0x02fe, 0x2000 }, { 0x1800, 0x02fd, 0x0000 }, { 0x1800, 0x02ff, 0x0000 }, { 0x8c00, 0x0304, 0x3000 }, { 0x8c00, 0x0302, 0x2000 }, { 0x0c00, 0x0301, 0x0000 }, { 0x0c00, 0x0303, 0x0000 }, { 0x8c00, 0x0306, 0x2000 }, { 0x0c00, 0x0305, 0x0000 }, { 0x0c00, 0x0307, 0x0000 }, { 0x8c00, 0x0310, 0x4000 }, { 0x8c00, 0x030c, 0x3000 }, { 0x8c00, 0x030a, 0x2000 }, { 0x0c00, 0x0309, 0x0000 }, { 0x0c00, 0x030b, 0x0000 }, { 0x8c00, 0x030e, 0x2000 }, { 0x0c00, 0x030d, 0x0000 }, { 0x0c00, 0x030f, 0x0000 }, { 0x8c00, 0x0314, 0x3000 }, { 0x8c00, 0x0312, 0x2000 }, { 0x0c00, 0x0311, 0x0000 }, { 0x0c00, 0x0313, 0x0000 }, { 0x8c00, 0x0316, 0x2000 }, { 0x0c00, 0x0315, 0x0000 }, { 0x0c00, 0x0317, 0x0000 }, { 0x8500, 0x03b0, 0x8000 }, { 0x8c00, 0x035d, 0x7000 }, { 0x8c00, 0x0338, 0x6000 }, { 0x8c00, 0x0328, 0x5000 }, { 0x8c00, 0x0320, 0x4000 }, { 0x8c00, 0x031c, 0x3000 }, { 0x8c00, 0x031a, 0x2000 }, { 0x0c00, 0x0319, 0x0000 }, { 0x0c00, 0x031b, 0x0000 }, { 0x8c00, 0x031e, 0x2000 }, { 0x0c00, 0x031d, 0x0000 }, { 0x0c00, 0x031f, 0x0000 }, { 0x8c00, 0x0324, 0x3000 }, { 0x8c00, 0x0322, 0x2000 }, { 0x0c00, 0x0321, 0x0000 }, { 0x0c00, 0x0323, 0x0000 }, { 0x8c00, 0x0326, 0x2000 }, { 0x0c00, 0x0325, 0x0000 }, { 0x0c00, 0x0327, 0x0000 }, { 0x8c00, 0x0330, 0x4000 }, { 0x8c00, 0x032c, 0x3000 }, { 0x8c00, 0x032a, 0x2000 }, { 0x0c00, 0x0329, 0x0000 }, { 0x0c00, 0x032b, 0x0000 }, { 0x8c00, 0x032e, 0x2000 }, { 0x0c00, 0x032d, 0x0000 }, { 0x0c00, 0x032f, 0x0000 }, { 0x8c00, 0x0334, 0x3000 }, { 0x8c00, 0x0332, 0x2000 }, { 0x0c00, 0x0331, 0x0000 }, { 0x0c00, 0x0333, 0x0000 }, { 0x8c00, 0x0336, 0x2000 }, { 0x0c00, 0x0335, 0x0000 }, { 0x0c00, 0x0337, 0x0000 }, { 0x8c00, 0x0348, 0x5000 }, { 0x8c00, 0x0340, 0x4000 }, { 0x8c00, 0x033c, 0x3000 }, { 0x8c00, 0x033a, 0x2000 }, { 0x0c00, 0x0339, 0x0000 }, { 0x0c00, 0x033b, 0x0000 }, { 0x8c00, 0x033e, 0x2000 }, { 0x0c00, 0x033d, 0x0000 }, { 0x0c00, 0x033f, 0x0000 }, { 0x8c00, 0x0344, 0x3000 }, { 0x8c00, 0x0342, 0x2000 }, { 0x0c00, 0x0341, 0x0000 }, { 0x0c00, 0x0343, 0x0000 }, { 0x8c00, 0x0346, 0x2000 }, { 0x0c00, 0x0345, 0x0000 }, { 0x0c00, 0x0347, 0x0000 }, { 0x8c00, 0x0350, 0x4000 }, { 0x8c00, 0x034c, 0x3000 }, { 0x8c00, 0x034a, 0x2000 }, { 0x0c00, 0x0349, 0x0000 }, { 0x0c00, 0x034b, 0x0000 }, { 0x8c00, 0x034e, 0x2000 }, { 0x0c00, 0x034d, 0x0000 }, { 0x0c00, 0x034f, 0x0000 }, { 0x8c00, 0x0354, 0x3000 }, { 0x8c00, 0x0352, 0x2000 }, { 0x0c00, 0x0351, 0x0000 }, { 0x0c00, 0x0353, 0x0000 }, { 0x8c00, 0x0356, 0x2000 }, { 0x0c00, 0x0355, 0x0000 }, { 0x0c00, 0x0357, 0x0000 }, { 0x8900, 0x038f, 0x603f }, { 0x8c00, 0x036d, 0x5000 }, { 0x8c00, 0x0365, 0x4000 }, { 0x8c00, 0x0361, 0x3000 }, { 0x8c00, 0x035f, 0x2000 }, { 0x0c00, 0x035e, 0x0000 }, { 0x0c00, 0x0360, 0x0000 }, { 0x8c00, 0x0363, 0x2000 }, { 0x0c00, 0x0362, 0x0000 }, { 0x0c00, 0x0364, 0x0000 }, { 0x8c00, 0x0369, 0x3000 }, { 0x8c00, 0x0367, 0x2000 }, { 0x0c00, 0x0366, 0x0000 }, { 0x0c00, 0x0368, 0x0000 }, { 0x8c00, 0x036b, 0x2000 }, { 0x0c00, 0x036a, 0x0000 }, { 0x0c00, 0x036c, 0x0000 }, { 0x9800, 0x0385, 0x4000 }, { 0x9800, 0x0375, 0x3000 }, { 0x8c00, 0x036f, 0x2000 }, { 0x0c00, 0x036e, 0x0000 }, { 0x1800, 0x0374, 0x0000 }, { 0x9500, 0x037e, 0x2000 }, { 0x0600, 0x037a, 0x0000 }, { 0x1800, 0x0384, 0x0000 }, { 0x8900, 0x0389, 0x3025 }, { 0x9500, 0x0387, 0x2000 }, { 0x0900, 0x0386, 0x0026 }, { 0x0900, 0x0388, 0x0025 }, { 0x8900, 0x038c, 0x2040 }, { 0x0900, 0x038a, 0x0025 }, { 0x0900, 0x038e, 0x003f }, { 0x8900, 0x039f, 0x5020 }, { 0x8900, 0x0397, 0x4020 }, { 0x8900, 0x0393, 0x3020 }, { 0x8900, 0x0391, 0x2020 }, { 0x0500, 0x0390, 0x0000 }, { 0x0900, 0x0392, 0x0020 }, { 0x8900, 0x0395, 0x2020 }, { 0x0900, 0x0394, 0x0020 }, { 0x0900, 0x0396, 0x0020 }, { 0x8900, 0x039b, 0x3020 }, { 0x8900, 0x0399, 0x2020 }, { 0x0900, 0x0398, 0x0020 }, { 0x0900, 0x039a, 0x0020 }, { 0x8900, 0x039d, 0x2020 }, { 0x0900, 0x039c, 0x0020 }, { 0x0900, 0x039e, 0x0020 }, { 0x8900, 0x03a8, 0x4020 }, { 0x8900, 0x03a4, 0x3020 }, { 0x8900, 0x03a1, 0x2020 }, { 0x0900, 0x03a0, 0x0020 }, { 0x0900, 0x03a3, 0x0020 }, { 0x8900, 0x03a6, 0x2020 }, { 0x0900, 0x03a5, 0x0020 }, { 0x0900, 0x03a7, 0x0020 }, { 0x8500, 0x03ac, 0x3fda }, { 0x8900, 0x03aa, 0x2020 }, { 0x0900, 0x03a9, 0x0020 }, { 0x0900, 0x03ab, 0x0020 }, { 0x8500, 0x03ae, 0x2fdb }, { 0x0500, 0x03ad, 0x0fdb }, { 0x0500, 0x03af, 0x0fdb }, { 0x8500, 0x03f1, 0x7fb0 }, { 0x8500, 0x03d1, 0x6fc7 }, { 0x8500, 0x03c0, 0x5fe0 }, { 0x8500, 0x03b8, 0x4fe0 }, { 0x8500, 0x03b4, 0x3fe0 }, { 0x8500, 0x03b2, 0x2fe0 }, { 0x0500, 0x03b1, 0x0fe0 }, { 0x0500, 0x03b3, 0x0fe0 }, { 0x8500, 0x03b6, 0x2fe0 }, { 0x0500, 0x03b5, 0x0fe0 }, { 0x0500, 0x03b7, 0x0fe0 }, { 0x8500, 0x03bc, 0x3fe0 }, { 0x8500, 0x03ba, 0x2fe0 }, { 0x0500, 0x03b9, 0x0fe0 }, { 0x0500, 0x03bb, 0x0fe0 }, { 0x8500, 0x03be, 0x2fe0 }, { 0x0500, 0x03bd, 0x0fe0 }, { 0x0500, 0x03bf, 0x0fe0 }, { 0x8500, 0x03c8, 0x4fe0 }, { 0x8500, 0x03c4, 0x3fe0 }, { 0x8500, 0x03c2, 0x2fe1 }, { 0x0500, 0x03c1, 0x0fe0 }, { 0x0500, 0x03c3, 0x0fe0 }, { 0x8500, 0x03c6, 0x2fe0 }, { 0x0500, 0x03c5, 0x0fe0 }, { 0x0500, 0x03c7, 0x0fe0 }, { 0x8500, 0x03cc, 0x3fc0 }, { 0x8500, 0x03ca, 0x2fe0 }, { 0x0500, 0x03c9, 0x0fe0 }, { 0x0500, 0x03cb, 0x0fe0 }, { 0x8500, 0x03ce, 0x2fc1 }, { 0x0500, 0x03cd, 0x0fc1 }, { 0x0500, 0x03d0, 0x0fc2 }, { 0x8500, 0x03e1, 0x5fff }, { 0x8500, 0x03d9, 0x4fff }, { 0x8500, 0x03d5, 0x3fd1 }, { 0x8900, 0x03d3, 0x2000 }, { 0x0900, 0x03d2, 0x0000 }, { 0x0900, 0x03d4, 0x0000 }, { 0x8500, 0x03d7, 0x2000 }, { 0x0500, 0x03d6, 0x0fca }, { 0x0900, 0x03d8, 0x0001 }, { 0x8500, 0x03dd, 0x3fff }, { 0x8500, 0x03db, 0x2fff }, { 0x0900, 0x03da, 0x0001 }, { 0x0900, 0x03dc, 0x0001 }, { 0x8500, 0x03df, 0x2fff }, { 0x0900, 0x03de, 0x0001 }, { 0x0900, 0x03e0, 0x0001 }, { 0x8500, 0x03e9, 0x4fff }, { 0x8500, 0x03e5, 0x3fff }, { 0x8500, 0x03e3, 0x2fff }, { 0x0900, 0x03e2, 0x0001 }, { 0x0900, 0x03e4, 0x0001 }, { 0x8500, 0x03e7, 0x2fff }, { 0x0900, 0x03e6, 0x0001 }, { 0x0900, 0x03e8, 0x0001 }, { 0x8500, 0x03ed, 0x3fff }, { 0x8500, 0x03eb, 0x2fff }, { 0x0900, 0x03ea, 0x0001 }, { 0x0900, 0x03ec, 0x0001 }, { 0x8500, 0x03ef, 0x2fff }, { 0x0900, 0x03ee, 0x0001 }, { 0x0500, 0x03f0, 0x0faa }, { 0x8900, 0x0415, 0x6020 }, { 0x8900, 0x0405, 0x5050 }, { 0x8900, 0x03f9, 0x4ff9 }, { 0x8500, 0x03f5, 0x3fa0 }, { 0x8500, 0x03f3, 0x2000 }, { 0x0500, 0x03f2, 0x0007 }, { 0x0900, 0x03f4, 0x0fc4 }, { 0x8900, 0x03f7, 0x2001 }, { 0x1900, 0x03f6, 0x0000 }, { 0x0500, 0x03f8, 0x0fff }, { 0x8900, 0x0401, 0x3050 }, { 0x8500, 0x03fb, 0x2fff }, { 0x0900, 0x03fa, 0x0001 }, { 0x0900, 0x0400, 0x0050 }, { 0x8900, 0x0403, 0x2050 }, { 0x0900, 0x0402, 0x0050 }, { 0x0900, 0x0404, 0x0050 }, { 0x8900, 0x040d, 0x4050 }, { 0x8900, 0x0409, 0x3050 }, { 0x8900, 0x0407, 0x2050 }, { 0x0900, 0x0406, 0x0050 }, { 0x0900, 0x0408, 0x0050 }, { 0x8900, 0x040b, 0x2050 }, { 0x0900, 0x040a, 0x0050 }, { 0x0900, 0x040c, 0x0050 }, { 0x8900, 0x0411, 0x3020 }, { 0x8900, 0x040f, 0x2050 }, { 0x0900, 0x040e, 0x0050 }, { 0x0900, 0x0410, 0x0020 }, { 0x8900, 0x0413, 0x2020 }, { 0x0900, 0x0412, 0x0020 }, { 0x0900, 0x0414, 0x0020 }, { 0x8900, 0x0425, 0x5020 }, { 0x8900, 0x041d, 0x4020 }, { 0x8900, 0x0419, 0x3020 }, { 0x8900, 0x0417, 0x2020 }, { 0x0900, 0x0416, 0x0020 }, { 0x0900, 0x0418, 0x0020 }, { 0x8900, 0x041b, 0x2020 }, { 0x0900, 0x041a, 0x0020 }, { 0x0900, 0x041c, 0x0020 }, { 0x8900, 0x0421, 0x3020 }, { 0x8900, 0x041f, 0x2020 }, { 0x0900, 0x041e, 0x0020 }, { 0x0900, 0x0420, 0x0020 }, { 0x8900, 0x0423, 0x2020 }, { 0x0900, 0x0422, 0x0020 }, { 0x0900, 0x0424, 0x0020 }, { 0x8900, 0x042d, 0x4020 }, { 0x8900, 0x0429, 0x3020 }, { 0x8900, 0x0427, 0x2020 }, { 0x0900, 0x0426, 0x0020 }, { 0x0900, 0x0428, 0x0020 }, { 0x8900, 0x042b, 0x2020 }, { 0x0900, 0x042a, 0x0020 }, { 0x0900, 0x042c, 0x0020 }, { 0x8500, 0x0431, 0x3fe0 }, { 0x8900, 0x042f, 0x2020 }, { 0x0900, 0x042e, 0x0020 }, { 0x0500, 0x0430, 0x0fe0 }, { 0x8500, 0x0433, 0x2fe0 }, { 0x0500, 0x0432, 0x0fe0 }, { 0x0500, 0x0434, 0x0fe0 }, { 0x8700, 0x06a4, 0xa000 }, { 0x8500, 0x0563, 0x9fd0 }, { 0x8900, 0x04b6, 0x8001 }, { 0x8500, 0x0475, 0x7fff }, { 0x8500, 0x0455, 0x6fb0 }, { 0x8500, 0x0445, 0x5fe0 }, { 0x8500, 0x043d, 0x4fe0 }, { 0x8500, 0x0439, 0x3fe0 }, { 0x8500, 0x0437, 0x2fe0 }, { 0x0500, 0x0436, 0x0fe0 }, { 0x0500, 0x0438, 0x0fe0 }, { 0x8500, 0x043b, 0x2fe0 }, { 0x0500, 0x043a, 0x0fe0 }, { 0x0500, 0x043c, 0x0fe0 }, { 0x8500, 0x0441, 0x3fe0 }, { 0x8500, 0x043f, 0x2fe0 }, { 0x0500, 0x043e, 0x0fe0 }, { 0x0500, 0x0440, 0x0fe0 }, { 0x8500, 0x0443, 0x2fe0 }, { 0x0500, 0x0442, 0x0fe0 }, { 0x0500, 0x0444, 0x0fe0 }, { 0x8500, 0x044d, 0x4fe0 }, { 0x8500, 0x0449, 0x3fe0 }, { 0x8500, 0x0447, 0x2fe0 }, { 0x0500, 0x0446, 0x0fe0 }, { 0x0500, 0x0448, 0x0fe0 }, { 0x8500, 0x044b, 0x2fe0 }, { 0x0500, 0x044a, 0x0fe0 }, { 0x0500, 0x044c, 0x0fe0 }, { 0x8500, 0x0451, 0x3fb0 }, { 0x8500, 0x044f, 0x2fe0 }, { 0x0500, 0x044e, 0x0fe0 }, { 0x0500, 0x0450, 0x0fb0 }, { 0x8500, 0x0453, 0x2fb0 }, { 0x0500, 0x0452, 0x0fb0 }, { 0x0500, 0x0454, 0x0fb0 }, { 0x8500, 0x0465, 0x5fff }, { 0x8500, 0x045d, 0x4fb0 }, { 0x8500, 0x0459, 0x3fb0 }, { 0x8500, 0x0457, 0x2fb0 }, { 0x0500, 0x0456, 0x0fb0 }, { 0x0500, 0x0458, 0x0fb0 }, { 0x8500, 0x045b, 0x2fb0 }, { 0x0500, 0x045a, 0x0fb0 }, { 0x0500, 0x045c, 0x0fb0 }, { 0x8500, 0x0461, 0x3fff }, { 0x8500, 0x045f, 0x2fb0 }, { 0x0500, 0x045e, 0x0fb0 }, { 0x0900, 0x0460, 0x0001 }, { 0x8500, 0x0463, 0x2fff }, { 0x0900, 0x0462, 0x0001 }, { 0x0900, 0x0464, 0x0001 }, { 0x8500, 0x046d, 0x4fff }, { 0x8500, 0x0469, 0x3fff }, { 0x8500, 0x0467, 0x2fff }, { 0x0900, 0x0466, 0x0001 }, { 0x0900, 0x0468, 0x0001 }, { 0x8500, 0x046b, 0x2fff }, { 0x0900, 0x046a, 0x0001 }, { 0x0900, 0x046c, 0x0001 }, { 0x8500, 0x0471, 0x3fff }, { 0x8500, 0x046f, 0x2fff }, { 0x0900, 0x046e, 0x0001 }, { 0x0900, 0x0470, 0x0001 }, { 0x8500, 0x0473, 0x2fff }, { 0x0900, 0x0472, 0x0001 }, { 0x0900, 0x0474, 0x0001 }, { 0x8900, 0x0496, 0x6001 }, { 0x8c00, 0x0485, 0x5000 }, { 0x8500, 0x047d, 0x4fff }, { 0x8500, 0x0479, 0x3fff }, { 0x8500, 0x0477, 0x2fff }, { 0x0900, 0x0476, 0x0001 }, { 0x0900, 0x0478, 0x0001 }, { 0x8500, 0x047b, 0x2fff }, { 0x0900, 0x047a, 0x0001 }, { 0x0900, 0x047c, 0x0001 }, { 0x8500, 0x0481, 0x3fff }, { 0x8500, 0x047f, 0x2fff }, { 0x0900, 0x047e, 0x0001 }, { 0x0900, 0x0480, 0x0001 }, { 0x8c00, 0x0483, 0x2000 }, { 0x1a00, 0x0482, 0x0000 }, { 0x0c00, 0x0484, 0x0000 }, { 0x8900, 0x048e, 0x4001 }, { 0x8900, 0x048a, 0x3001 }, { 0x8b00, 0x0488, 0x2000 }, { 0x0c00, 0x0486, 0x0000 }, { 0x0b00, 0x0489, 0x0000 }, { 0x8900, 0x048c, 0x2001 }, { 0x0500, 0x048b, 0x0fff }, { 0x0500, 0x048d, 0x0fff }, { 0x8900, 0x0492, 0x3001 }, { 0x8900, 0x0490, 0x2001 }, { 0x0500, 0x048f, 0x0fff }, { 0x0500, 0x0491, 0x0fff }, { 0x8900, 0x0494, 0x2001 }, { 0x0500, 0x0493, 0x0fff }, { 0x0500, 0x0495, 0x0fff }, { 0x8900, 0x04a6, 0x5001 }, { 0x8900, 0x049e, 0x4001 }, { 0x8900, 0x049a, 0x3001 }, { 0x8900, 0x0498, 0x2001 }, { 0x0500, 0x0497, 0x0fff }, { 0x0500, 0x0499, 0x0fff }, { 0x8900, 0x049c, 0x2001 }, { 0x0500, 0x049b, 0x0fff }, { 0x0500, 0x049d, 0x0fff }, { 0x8900, 0x04a2, 0x3001 }, { 0x8900, 0x04a0, 0x2001 }, { 0x0500, 0x049f, 0x0fff }, { 0x0500, 0x04a1, 0x0fff }, { 0x8900, 0x04a4, 0x2001 }, { 0x0500, 0x04a3, 0x0fff }, { 0x0500, 0x04a5, 0x0fff }, { 0x8900, 0x04ae, 0x4001 }, { 0x8900, 0x04aa, 0x3001 }, { 0x8900, 0x04a8, 0x2001 }, { 0x0500, 0x04a7, 0x0fff }, { 0x0500, 0x04a9, 0x0fff }, { 0x8900, 0x04ac, 0x2001 }, { 0x0500, 0x04ab, 0x0fff }, { 0x0500, 0x04ad, 0x0fff }, { 0x8900, 0x04b2, 0x3001 }, { 0x8900, 0x04b0, 0x2001 }, { 0x0500, 0x04af, 0x0fff }, { 0x0500, 0x04b1, 0x0fff }, { 0x8900, 0x04b4, 0x2001 }, { 0x0500, 0x04b3, 0x0fff }, { 0x0500, 0x04b5, 0x0fff }, { 0x8500, 0x04f9, 0x7fff }, { 0x8500, 0x04d7, 0x6fff }, { 0x8500, 0x04c6, 0x5fff }, { 0x8900, 0x04be, 0x4001 }, { 0x8900, 0x04ba, 0x3001 }, { 0x8900, 0x04b8, 0x2001 }, { 0x0500, 0x04b7, 0x0fff }, { 0x0500, 0x04b9, 0x0fff }, { 0x8900, 0x04bc, 0x2001 }, { 0x0500, 0x04bb, 0x0fff }, { 0x0500, 0x04bd, 0x0fff }, { 0x8500, 0x04c2, 0x3fff }, { 0x8900, 0x04c0, 0x2000 }, { 0x0500, 0x04bf, 0x0fff }, { 0x0900, 0x04c1, 0x0001 }, { 0x8500, 0x04c4, 0x2fff }, { 0x0900, 0x04c3, 0x0001 }, { 0x0900, 0x04c5, 0x0001 }, { 0x8500, 0x04ce, 0x4fff }, { 0x8500, 0x04ca, 0x3fff }, { 0x8500, 0x04c8, 0x2fff }, { 0x0900, 0x04c7, 0x0001 }, { 0x0900, 0x04c9, 0x0001 }, { 0x8500, 0x04cc, 0x2fff }, { 0x0900, 0x04cb, 0x0001 }, { 0x0900, 0x04cd, 0x0001 }, { 0x8500, 0x04d3, 0x3fff }, { 0x8500, 0x04d1, 0x2fff }, { 0x0900, 0x04d0, 0x0001 }, { 0x0900, 0x04d2, 0x0001 }, { 0x8500, 0x04d5, 0x2fff }, { 0x0900, 0x04d4, 0x0001 }, { 0x0900, 0x04d6, 0x0001 }, { 0x8500, 0x04e7, 0x5fff }, { 0x8500, 0x04df, 0x4fff }, { 0x8500, 0x04db, 0x3fff }, { 0x8500, 0x04d9, 0x2fff }, { 0x0900, 0x04d8, 0x0001 }, { 0x0900, 0x04da, 0x0001 }, { 0x8500, 0x04dd, 0x2fff }, { 0x0900, 0x04dc, 0x0001 }, { 0x0900, 0x04de, 0x0001 }, { 0x8500, 0x04e3, 0x3fff }, { 0x8500, 0x04e1, 0x2fff }, { 0x0900, 0x04e0, 0x0001 }, { 0x0900, 0x04e2, 0x0001 }, { 0x8500, 0x04e5, 0x2fff }, { 0x0900, 0x04e4, 0x0001 }, { 0x0900, 0x04e6, 0x0001 }, { 0x8500, 0x04ef, 0x4fff }, { 0x8500, 0x04eb, 0x3fff }, { 0x8500, 0x04e9, 0x2fff }, { 0x0900, 0x04e8, 0x0001 }, { 0x0900, 0x04ea, 0x0001 }, { 0x8500, 0x04ed, 0x2fff }, { 0x0900, 0x04ec, 0x0001 }, { 0x0900, 0x04ee, 0x0001 }, { 0x8500, 0x04f3, 0x3fff }, { 0x8500, 0x04f1, 0x2fff }, { 0x0900, 0x04f0, 0x0001 }, { 0x0900, 0x04f2, 0x0001 }, { 0x8500, 0x04f5, 0x2fff }, { 0x0900, 0x04f4, 0x0001 }, { 0x0900, 0x04f8, 0x0001 }, { 0x8900, 0x0540, 0x6030 }, { 0x8500, 0x050f, 0x5fff }, { 0x8500, 0x0507, 0x4fff }, { 0x8500, 0x0503, 0x3fff }, { 0x8500, 0x0501, 0x2fff }, { 0x0900, 0x0500, 0x0001 }, { 0x0900, 0x0502, 0x0001 }, { 0x8500, 0x0505, 0x2fff }, { 0x0900, 0x0504, 0x0001 }, { 0x0900, 0x0506, 0x0001 }, { 0x8500, 0x050b, 0x3fff }, { 0x8500, 0x0509, 0x2fff }, { 0x0900, 0x0508, 0x0001 }, { 0x0900, 0x050a, 0x0001 }, { 0x8500, 0x050d, 0x2fff }, { 0x0900, 0x050c, 0x0001 }, { 0x0900, 0x050e, 0x0001 }, { 0x8900, 0x0538, 0x4030 }, { 0x8900, 0x0534, 0x3030 }, { 0x8900, 0x0532, 0x2030 }, { 0x0900, 0x0531, 0x0030 }, { 0x0900, 0x0533, 0x0030 }, { 0x8900, 0x0536, 0x2030 }, { 0x0900, 0x0535, 0x0030 }, { 0x0900, 0x0537, 0x0030 }, { 0x8900, 0x053c, 0x3030 }, { 0x8900, 0x053a, 0x2030 }, { 0x0900, 0x0539, 0x0030 }, { 0x0900, 0x053b, 0x0030 }, { 0x8900, 0x053e, 0x2030 }, { 0x0900, 0x053d, 0x0030 }, { 0x0900, 0x053f, 0x0030 }, { 0x8900, 0x0550, 0x5030 }, { 0x8900, 0x0548, 0x4030 }, { 0x8900, 0x0544, 0x3030 }, { 0x8900, 0x0542, 0x2030 }, { 0x0900, 0x0541, 0x0030 }, { 0x0900, 0x0543, 0x0030 }, { 0x8900, 0x0546, 0x2030 }, { 0x0900, 0x0545, 0x0030 }, { 0x0900, 0x0547, 0x0030 }, { 0x8900, 0x054c, 0x3030 }, { 0x8900, 0x054a, 0x2030 }, { 0x0900, 0x0549, 0x0030 }, { 0x0900, 0x054b, 0x0030 }, { 0x8900, 0x054e, 0x2030 }, { 0x0900, 0x054d, 0x0030 }, { 0x0900, 0x054f, 0x0030 }, { 0x9500, 0x055a, 0x4000 }, { 0x8900, 0x0554, 0x3030 }, { 0x8900, 0x0552, 0x2030 }, { 0x0900, 0x0551, 0x0030 }, { 0x0900, 0x0553, 0x0030 }, { 0x8900, 0x0556, 0x2030 }, { 0x0900, 0x0555, 0x0030 }, { 0x0600, 0x0559, 0x0000 }, { 0x9500, 0x055e, 0x3000 }, { 0x9500, 0x055c, 0x2000 }, { 0x1500, 0x055b, 0x0000 }, { 0x1500, 0x055d, 0x0000 }, { 0x8500, 0x0561, 0x2fd0 }, { 0x1500, 0x055f, 0x0000 }, { 0x0500, 0x0562, 0x0fd0 }, { 0x9a00, 0x060f, 0x8000 }, { 0x8c00, 0x05ab, 0x7000 }, { 0x8500, 0x0583, 0x6fd0 }, { 0x8500, 0x0573, 0x5fd0 }, { 0x8500, 0x056b, 0x4fd0 }, { 0x8500, 0x0567, 0x3fd0 }, { 0x8500, 0x0565, 0x2fd0 }, { 0x0500, 0x0564, 0x0fd0 }, { 0x0500, 0x0566, 0x0fd0 }, { 0x8500, 0x0569, 0x2fd0 }, { 0x0500, 0x0568, 0x0fd0 }, { 0x0500, 0x056a, 0x0fd0 }, { 0x8500, 0x056f, 0x3fd0 }, { 0x8500, 0x056d, 0x2fd0 }, { 0x0500, 0x056c, 0x0fd0 }, { 0x0500, 0x056e, 0x0fd0 }, { 0x8500, 0x0571, 0x2fd0 }, { 0x0500, 0x0570, 0x0fd0 }, { 0x0500, 0x0572, 0x0fd0 }, { 0x8500, 0x057b, 0x4fd0 }, { 0x8500, 0x0577, 0x3fd0 }, { 0x8500, 0x0575, 0x2fd0 }, { 0x0500, 0x0574, 0x0fd0 }, { 0x0500, 0x0576, 0x0fd0 }, { 0x8500, 0x0579, 0x2fd0 }, { 0x0500, 0x0578, 0x0fd0 }, { 0x0500, 0x057a, 0x0fd0 }, { 0x8500, 0x057f, 0x3fd0 }, { 0x8500, 0x057d, 0x2fd0 }, { 0x0500, 0x057c, 0x0fd0 }, { 0x0500, 0x057e, 0x0fd0 }, { 0x8500, 0x0581, 0x2fd0 }, { 0x0500, 0x0580, 0x0fd0 }, { 0x0500, 0x0582, 0x0fd0 }, { 0x8c00, 0x059a, 0x5000 }, { 0x8c00, 0x0592, 0x4000 }, { 0x8500, 0x0587, 0x3000 }, { 0x8500, 0x0585, 0x2fd0 }, { 0x0500, 0x0584, 0x0fd0 }, { 0x0500, 0x0586, 0x0fd0 }, { 0x9100, 0x058a, 0x2000 }, { 0x1500, 0x0589, 0x0000 }, { 0x0c00, 0x0591, 0x0000 }, { 0x8c00, 0x0596, 0x3000 }, { 0x8c00, 0x0594, 0x2000 }, { 0x0c00, 0x0593, 0x0000 }, { 0x0c00, 0x0595, 0x0000 }, { 0x8c00, 0x0598, 0x2000 }, { 0x0c00, 0x0597, 0x0000 }, { 0x0c00, 0x0599, 0x0000 }, { 0x8c00, 0x05a3, 0x4000 }, { 0x8c00, 0x059e, 0x3000 }, { 0x8c00, 0x059c, 0x2000 }, { 0x0c00, 0x059b, 0x0000 }, { 0x0c00, 0x059d, 0x0000 }, { 0x8c00, 0x05a0, 0x2000 }, { 0x0c00, 0x059f, 0x0000 }, { 0x0c00, 0x05a1, 0x0000 }, { 0x8c00, 0x05a7, 0x3000 }, { 0x8c00, 0x05a5, 0x2000 }, { 0x0c00, 0x05a4, 0x0000 }, { 0x0c00, 0x05a6, 0x0000 }, { 0x8c00, 0x05a9, 0x2000 }, { 0x0c00, 0x05a8, 0x0000 }, { 0x0c00, 0x05aa, 0x0000 }, { 0x8700, 0x05d7, 0x6000 }, { 0x8c00, 0x05bc, 0x5000 }, { 0x8c00, 0x05b3, 0x4000 }, { 0x8c00, 0x05af, 0x3000 }, { 0x8c00, 0x05ad, 0x2000 }, { 0x0c00, 0x05ac, 0x0000 }, { 0x0c00, 0x05ae, 0x0000 }, { 0x8c00, 0x05b1, 0x2000 }, { 0x0c00, 0x05b0, 0x0000 }, { 0x0c00, 0x05b2, 0x0000 }, { 0x8c00, 0x05b7, 0x3000 }, { 0x8c00, 0x05b5, 0x2000 }, { 0x0c00, 0x05b4, 0x0000 }, { 0x0c00, 0x05b6, 0x0000 }, { 0x8c00, 0x05b9, 0x2000 }, { 0x0c00, 0x05b8, 0x0000 }, { 0x0c00, 0x05bb, 0x0000 }, { 0x8c00, 0x05c4, 0x4000 }, { 0x9500, 0x05c0, 0x3000 }, { 0x9500, 0x05be, 0x2000 }, { 0x0c00, 0x05bd, 0x0000 }, { 0x0c00, 0x05bf, 0x0000 }, { 0x8c00, 0x05c2, 0x2000 }, { 0x0c00, 0x05c1, 0x0000 }, { 0x1500, 0x05c3, 0x0000 }, { 0x8700, 0x05d3, 0x3000 }, { 0x8700, 0x05d1, 0x2000 }, { 0x0700, 0x05d0, 0x0000 }, { 0x0700, 0x05d2, 0x0000 }, { 0x8700, 0x05d5, 0x2000 }, { 0x0700, 0x05d4, 0x0000 }, { 0x0700, 0x05d6, 0x0000 }, { 0x8700, 0x05e7, 0x5000 }, { 0x8700, 0x05df, 0x4000 }, { 0x8700, 0x05db, 0x3000 }, { 0x8700, 0x05d9, 0x2000 }, { 0x0700, 0x05d8, 0x0000 }, { 0x0700, 0x05da, 0x0000 }, { 0x8700, 0x05dd, 0x2000 }, { 0x0700, 0x05dc, 0x0000 }, { 0x0700, 0x05de, 0x0000 }, { 0x8700, 0x05e3, 0x3000 }, { 0x8700, 0x05e1, 0x2000 }, { 0x0700, 0x05e0, 0x0000 }, { 0x0700, 0x05e2, 0x0000 }, { 0x8700, 0x05e5, 0x2000 }, { 0x0700, 0x05e4, 0x0000 }, { 0x0700, 0x05e6, 0x0000 }, { 0x9500, 0x05f4, 0x4000 }, { 0x8700, 0x05f0, 0x3000 }, { 0x8700, 0x05e9, 0x2000 }, { 0x0700, 0x05e8, 0x0000 }, { 0x0700, 0x05ea, 0x0000 }, { 0x8700, 0x05f2, 0x2000 }, { 0x0700, 0x05f1, 0x0000 }, { 0x1500, 0x05f3, 0x0000 }, { 0x8100, 0x0603, 0x3000 }, { 0x8100, 0x0601, 0x2000 }, { 0x0100, 0x0600, 0x0000 }, { 0x0100, 0x0602, 0x0000 }, { 0x9500, 0x060d, 0x2000 }, { 0x1500, 0x060c, 0x0000 }, { 0x1a00, 0x060e, 0x0000 }, { 0x8d00, 0x0664, 0x7000 }, { 0x8700, 0x0638, 0x6000 }, { 0x8700, 0x0628, 0x5000 }, { 0x9500, 0x061f, 0x4000 }, { 0x8c00, 0x0613, 0x3000 }, { 0x8c00, 0x0611, 0x2000 }, { 0x0c00, 0x0610, 0x0000 }, { 0x0c00, 0x0612, 0x0000 }, { 0x8c00, 0x0615, 0x2000 }, { 0x0c00, 0x0614, 0x0000 }, { 0x1500, 0x061b, 0x0000 }, { 0x8700, 0x0624, 0x3000 }, { 0x8700, 0x0622, 0x2000 }, { 0x0700, 0x0621, 0x0000 }, { 0x0700, 0x0623, 0x0000 }, { 0x8700, 0x0626, 0x2000 }, { 0x0700, 0x0625, 0x0000 }, { 0x0700, 0x0627, 0x0000 }, { 0x8700, 0x0630, 0x4000 }, { 0x8700, 0x062c, 0x3000 }, { 0x8700, 0x062a, 0x2000 }, { 0x0700, 0x0629, 0x0000 }, { 0x0700, 0x062b, 0x0000 }, { 0x8700, 0x062e, 0x2000 }, { 0x0700, 0x062d, 0x0000 }, { 0x0700, 0x062f, 0x0000 }, { 0x8700, 0x0634, 0x3000 }, { 0x8700, 0x0632, 0x2000 }, { 0x0700, 0x0631, 0x0000 }, { 0x0700, 0x0633, 0x0000 }, { 0x8700, 0x0636, 0x2000 }, { 0x0700, 0x0635, 0x0000 }, { 0x0700, 0x0637, 0x0000 }, { 0x8c00, 0x064d, 0x5000 }, { 0x8700, 0x0645, 0x4000 }, { 0x8700, 0x0641, 0x3000 }, { 0x8700, 0x063a, 0x2000 }, { 0x0700, 0x0639, 0x0000 }, { 0x0600, 0x0640, 0x0000 }, { 0x8700, 0x0643, 0x2000 }, { 0x0700, 0x0642, 0x0000 }, { 0x0700, 0x0644, 0x0000 }, { 0x8700, 0x0649, 0x3000 }, { 0x8700, 0x0647, 0x2000 }, { 0x0700, 0x0646, 0x0000 }, { 0x0700, 0x0648, 0x0000 }, { 0x8c00, 0x064b, 0x2000 }, { 0x0700, 0x064a, 0x0000 }, { 0x0c00, 0x064c, 0x0000 }, { 0x8c00, 0x0655, 0x4000 }, { 0x8c00, 0x0651, 0x3000 }, { 0x8c00, 0x064f, 0x2000 }, { 0x0c00, 0x064e, 0x0000 }, { 0x0c00, 0x0650, 0x0000 }, { 0x8c00, 0x0653, 0x2000 }, { 0x0c00, 0x0652, 0x0000 }, { 0x0c00, 0x0654, 0x0000 }, { 0x8d00, 0x0660, 0x3000 }, { 0x8c00, 0x0657, 0x2000 }, { 0x0c00, 0x0656, 0x0000 }, { 0x0c00, 0x0658, 0x0000 }, { 0x8d00, 0x0662, 0x2000 }, { 0x0d00, 0x0661, 0x0000 }, { 0x0d00, 0x0663, 0x0000 }, { 0x8700, 0x0684, 0x6000 }, { 0x8700, 0x0674, 0x5000 }, { 0x9500, 0x066c, 0x4000 }, { 0x8d00, 0x0668, 0x3000 }, { 0x8d00, 0x0666, 0x2000 }, { 0x0d00, 0x0665, 0x0000 }, { 0x0d00, 0x0667, 0x0000 }, { 0x9500, 0x066a, 0x2000 }, { 0x0d00, 0x0669, 0x0000 }, { 0x1500, 0x066b, 0x0000 }, { 0x8c00, 0x0670, 0x3000 }, { 0x8700, 0x066e, 0x2000 }, { 0x1500, 0x066d, 0x0000 }, { 0x0700, 0x066f, 0x0000 }, { 0x8700, 0x0672, 0x2000 }, { 0x0700, 0x0671, 0x0000 }, { 0x0700, 0x0673, 0x0000 }, { 0x8700, 0x067c, 0x4000 }, { 0x8700, 0x0678, 0x3000 }, { 0x8700, 0x0676, 0x2000 }, { 0x0700, 0x0675, 0x0000 }, { 0x0700, 0x0677, 0x0000 }, { 0x8700, 0x067a, 0x2000 }, { 0x0700, 0x0679, 0x0000 }, { 0x0700, 0x067b, 0x0000 }, { 0x8700, 0x0680, 0x3000 }, { 0x8700, 0x067e, 0x2000 }, { 0x0700, 0x067d, 0x0000 }, { 0x0700, 0x067f, 0x0000 }, { 0x8700, 0x0682, 0x2000 }, { 0x0700, 0x0681, 0x0000 }, { 0x0700, 0x0683, 0x0000 }, { 0x8700, 0x0694, 0x5000 }, { 0x8700, 0x068c, 0x4000 }, { 0x8700, 0x0688, 0x3000 }, { 0x8700, 0x0686, 0x2000 }, { 0x0700, 0x0685, 0x0000 }, { 0x0700, 0x0687, 0x0000 }, { 0x8700, 0x068a, 0x2000 }, { 0x0700, 0x0689, 0x0000 }, { 0x0700, 0x068b, 0x0000 }, { 0x8700, 0x0690, 0x3000 }, { 0x8700, 0x068e, 0x2000 }, { 0x0700, 0x068d, 0x0000 }, { 0x0700, 0x068f, 0x0000 }, { 0x8700, 0x0692, 0x2000 }, { 0x0700, 0x0691, 0x0000 }, { 0x0700, 0x0693, 0x0000 }, { 0x8700, 0x069c, 0x4000 }, { 0x8700, 0x0698, 0x3000 }, { 0x8700, 0x0696, 0x2000 }, { 0x0700, 0x0695, 0x0000 }, { 0x0700, 0x0697, 0x0000 }, { 0x8700, 0x069a, 0x2000 }, { 0x0700, 0x0699, 0x0000 }, { 0x0700, 0x069b, 0x0000 }, { 0x8700, 0x06a0, 0x3000 }, { 0x8700, 0x069e, 0x2000 }, { 0x0700, 0x069d, 0x0000 }, { 0x0700, 0x069f, 0x0000 }, { 0x8700, 0x06a2, 0x2000 }, { 0x0700, 0x06a1, 0x0000 }, { 0x0700, 0x06a3, 0x0000 }, { 0x8700, 0x0926, 0x9000 }, { 0x8700, 0x0725, 0x8000 }, { 0x8c00, 0x06e4, 0x7000 }, { 0x8700, 0x06c4, 0x6000 }, { 0x8700, 0x06b4, 0x5000 }, { 0x8700, 0x06ac, 0x4000 }, { 0x8700, 0x06a8, 0x3000 }, { 0x8700, 0x06a6, 0x2000 }, { 0x0700, 0x06a5, 0x0000 }, { 0x0700, 0x06a7, 0x0000 }, { 0x8700, 0x06aa, 0x2000 }, { 0x0700, 0x06a9, 0x0000 }, { 0x0700, 0x06ab, 0x0000 }, { 0x8700, 0x06b0, 0x3000 }, { 0x8700, 0x06ae, 0x2000 }, { 0x0700, 0x06ad, 0x0000 }, { 0x0700, 0x06af, 0x0000 }, { 0x8700, 0x06b2, 0x2000 }, { 0x0700, 0x06b1, 0x0000 }, { 0x0700, 0x06b3, 0x0000 }, { 0x8700, 0x06bc, 0x4000 }, { 0x8700, 0x06b8, 0x3000 }, { 0x8700, 0x06b6, 0x2000 }, { 0x0700, 0x06b5, 0x0000 }, { 0x0700, 0x06b7, 0x0000 }, { 0x8700, 0x06ba, 0x2000 }, { 0x0700, 0x06b9, 0x0000 }, { 0x0700, 0x06bb, 0x0000 }, { 0x8700, 0x06c0, 0x3000 }, { 0x8700, 0x06be, 0x2000 }, { 0x0700, 0x06bd, 0x0000 }, { 0x0700, 0x06bf, 0x0000 }, { 0x8700, 0x06c2, 0x2000 }, { 0x0700, 0x06c1, 0x0000 }, { 0x0700, 0x06c3, 0x0000 }, { 0x9500, 0x06d4, 0x5000 }, { 0x8700, 0x06cc, 0x4000 }, { 0x8700, 0x06c8, 0x3000 }, { 0x8700, 0x06c6, 0x2000 }, { 0x0700, 0x06c5, 0x0000 }, { 0x0700, 0x06c7, 0x0000 }, { 0x8700, 0x06ca, 0x2000 }, { 0x0700, 0x06c9, 0x0000 }, { 0x0700, 0x06cb, 0x0000 }, { 0x8700, 0x06d0, 0x3000 }, { 0x8700, 0x06ce, 0x2000 }, { 0x0700, 0x06cd, 0x0000 }, { 0x0700, 0x06cf, 0x0000 }, { 0x8700, 0x06d2, 0x2000 }, { 0x0700, 0x06d1, 0x0000 }, { 0x0700, 0x06d3, 0x0000 }, { 0x8c00, 0x06dc, 0x4000 }, { 0x8c00, 0x06d8, 0x3000 }, { 0x8c00, 0x06d6, 0x2000 }, { 0x0700, 0x06d5, 0x0000 }, { 0x0c00, 0x06d7, 0x0000 }, { 0x8c00, 0x06da, 0x2000 }, { 0x0c00, 0x06d9, 0x0000 }, { 0x0c00, 0x06db, 0x0000 }, { 0x8c00, 0x06e0, 0x3000 }, { 0x8b00, 0x06de, 0x2000 }, { 0x0100, 0x06dd, 0x0000 }, { 0x0c00, 0x06df, 0x0000 }, { 0x8c00, 0x06e2, 0x2000 }, { 0x0c00, 0x06e1, 0x0000 }, { 0x0c00, 0x06e3, 0x0000 }, { 0x9500, 0x0704, 0x6000 }, { 0x8d00, 0x06f4, 0x5000 }, { 0x8c00, 0x06ec, 0x4000 }, { 0x8c00, 0x06e8, 0x3000 }, { 0x8600, 0x06e6, 0x2000 }, { 0x0600, 0x06e5, 0x0000 }, { 0x0c00, 0x06e7, 0x0000 }, { 0x8c00, 0x06ea, 0x2000 }, { 0x1a00, 0x06e9, 0x0000 }, { 0x0c00, 0x06eb, 0x0000 }, { 0x8d00, 0x06f0, 0x3000 }, { 0x8700, 0x06ee, 0x2000 }, { 0x0c00, 0x06ed, 0x0000 }, { 0x0700, 0x06ef, 0x0000 }, { 0x8d00, 0x06f2, 0x2000 }, { 0x0d00, 0x06f1, 0x0000 }, { 0x0d00, 0x06f3, 0x0000 }, { 0x8700, 0x06fc, 0x4000 }, { 0x8d00, 0x06f8, 0x3000 }, { 0x8d00, 0x06f6, 0x2000 }, { 0x0d00, 0x06f5, 0x0000 }, { 0x0d00, 0x06f7, 0x0000 }, { 0x8700, 0x06fa, 0x2000 }, { 0x0d00, 0x06f9, 0x0000 }, { 0x0700, 0x06fb, 0x0000 }, { 0x9500, 0x0700, 0x3000 }, { 0x9a00, 0x06fe, 0x2000 }, { 0x1a00, 0x06fd, 0x0000 }, { 0x0700, 0x06ff, 0x0000 }, { 0x9500, 0x0702, 0x2000 }, { 0x1500, 0x0701, 0x0000 }, { 0x1500, 0x0703, 0x0000 }, { 0x8700, 0x0715, 0x5000 }, { 0x9500, 0x070c, 0x4000 }, { 0x9500, 0x0708, 0x3000 }, { 0x9500, 0x0706, 0x2000 }, { 0x1500, 0x0705, 0x0000 }, { 0x1500, 0x0707, 0x0000 }, { 0x9500, 0x070a, 0x2000 }, { 0x1500, 0x0709, 0x0000 }, { 0x1500, 0x070b, 0x0000 }, { 0x8c00, 0x0711, 0x3000 }, { 0x8100, 0x070f, 0x2000 }, { 0x1500, 0x070d, 0x0000 }, { 0x0700, 0x0710, 0x0000 }, { 0x8700, 0x0713, 0x2000 }, { 0x0700, 0x0712, 0x0000 }, { 0x0700, 0x0714, 0x0000 }, { 0x8700, 0x071d, 0x4000 }, { 0x8700, 0x0719, 0x3000 }, { 0x8700, 0x0717, 0x2000 }, { 0x0700, 0x0716, 0x0000 }, { 0x0700, 0x0718, 0x0000 }, { 0x8700, 0x071b, 0x2000 }, { 0x0700, 0x071a, 0x0000 }, { 0x0700, 0x071c, 0x0000 }, { 0x8700, 0x0721, 0x3000 }, { 0x8700, 0x071f, 0x2000 }, { 0x0700, 0x071e, 0x0000 }, { 0x0700, 0x0720, 0x0000 }, { 0x8700, 0x0723, 0x2000 }, { 0x0700, 0x0722, 0x0000 }, { 0x0700, 0x0724, 0x0000 }, { 0x8700, 0x0797, 0x7000 }, { 0x8c00, 0x0745, 0x6000 }, { 0x8c00, 0x0735, 0x5000 }, { 0x8700, 0x072d, 0x4000 }, { 0x8700, 0x0729, 0x3000 }, { 0x8700, 0x0727, 0x2000 }, { 0x0700, 0x0726, 0x0000 }, { 0x0700, 0x0728, 0x0000 }, { 0x8700, 0x072b, 0x2000 }, { 0x0700, 0x072a, 0x0000 }, { 0x0700, 0x072c, 0x0000 }, { 0x8c00, 0x0731, 0x3000 }, { 0x8700, 0x072f, 0x2000 }, { 0x0700, 0x072e, 0x0000 }, { 0x0c00, 0x0730, 0x0000 }, { 0x8c00, 0x0733, 0x2000 }, { 0x0c00, 0x0732, 0x0000 }, { 0x0c00, 0x0734, 0x0000 }, { 0x8c00, 0x073d, 0x4000 }, { 0x8c00, 0x0739, 0x3000 }, { 0x8c00, 0x0737, 0x2000 }, { 0x0c00, 0x0736, 0x0000 }, { 0x0c00, 0x0738, 0x0000 }, { 0x8c00, 0x073b, 0x2000 }, { 0x0c00, 0x073a, 0x0000 }, { 0x0c00, 0x073c, 0x0000 }, { 0x8c00, 0x0741, 0x3000 }, { 0x8c00, 0x073f, 0x2000 }, { 0x0c00, 0x073e, 0x0000 }, { 0x0c00, 0x0740, 0x0000 }, { 0x8c00, 0x0743, 0x2000 }, { 0x0c00, 0x0742, 0x0000 }, { 0x0c00, 0x0744, 0x0000 }, { 0x8700, 0x0787, 0x5000 }, { 0x8700, 0x074f, 0x4000 }, { 0x8c00, 0x0749, 0x3000 }, { 0x8c00, 0x0747, 0x2000 }, { 0x0c00, 0x0746, 0x0000 }, { 0x0c00, 0x0748, 0x0000 }, { 0x8700, 0x074d, 0x2000 }, { 0x0c00, 0x074a, 0x0000 }, { 0x0700, 0x074e, 0x0000 }, { 0x8700, 0x0783, 0x3000 }, { 0x8700, 0x0781, 0x2000 }, { 0x0700, 0x0780, 0x0000 }, { 0x0700, 0x0782, 0x0000 }, { 0x8700, 0x0785, 0x2000 }, { 0x0700, 0x0784, 0x0000 }, { 0x0700, 0x0786, 0x0000 }, { 0x8700, 0x078f, 0x4000 }, { 0x8700, 0x078b, 0x3000 }, { 0x8700, 0x0789, 0x2000 }, { 0x0700, 0x0788, 0x0000 }, { 0x0700, 0x078a, 0x0000 }, { 0x8700, 0x078d, 0x2000 }, { 0x0700, 0x078c, 0x0000 }, { 0x0700, 0x078e, 0x0000 }, { 0x8700, 0x0793, 0x3000 }, { 0x8700, 0x0791, 0x2000 }, { 0x0700, 0x0790, 0x0000 }, { 0x0700, 0x0792, 0x0000 }, { 0x8700, 0x0795, 0x2000 }, { 0x0700, 0x0794, 0x0000 }, { 0x0700, 0x0796, 0x0000 }, { 0x8700, 0x0906, 0x6000 }, { 0x8c00, 0x07a7, 0x5000 }, { 0x8700, 0x079f, 0x4000 }, { 0x8700, 0x079b, 0x3000 }, { 0x8700, 0x0799, 0x2000 }, { 0x0700, 0x0798, 0x0000 }, { 0x0700, 0x079a, 0x0000 }, { 0x8700, 0x079d, 0x2000 }, { 0x0700, 0x079c, 0x0000 }, { 0x0700, 0x079e, 0x0000 }, { 0x8700, 0x07a3, 0x3000 }, { 0x8700, 0x07a1, 0x2000 }, { 0x0700, 0x07a0, 0x0000 }, { 0x0700, 0x07a2, 0x0000 }, { 0x8700, 0x07a5, 0x2000 }, { 0x0700, 0x07a4, 0x0000 }, { 0x0c00, 0x07a6, 0x0000 }, { 0x8c00, 0x07af, 0x4000 }, { 0x8c00, 0x07ab, 0x3000 }, { 0x8c00, 0x07a9, 0x2000 }, { 0x0c00, 0x07a8, 0x0000 }, { 0x0c00, 0x07aa, 0x0000 }, { 0x8c00, 0x07ad, 0x2000 }, { 0x0c00, 0x07ac, 0x0000 }, { 0x0c00, 0x07ae, 0x0000 }, { 0x8c00, 0x0902, 0x3000 }, { 0x8700, 0x07b1, 0x2000 }, { 0x0c00, 0x07b0, 0x0000 }, { 0x0c00, 0x0901, 0x0000 }, { 0x8700, 0x0904, 0x2000 }, { 0x0a00, 0x0903, 0x0000 }, { 0x0700, 0x0905, 0x0000 }, { 0x8700, 0x0916, 0x5000 }, { 0x8700, 0x090e, 0x4000 }, { 0x8700, 0x090a, 0x3000 }, { 0x8700, 0x0908, 0x2000 }, { 0x0700, 0x0907, 0x0000 }, { 0x0700, 0x0909, 0x0000 }, { 0x8700, 0x090c, 0x2000 }, { 0x0700, 0x090b, 0x0000 }, { 0x0700, 0x090d, 0x0000 }, { 0x8700, 0x0912, 0x3000 }, { 0x8700, 0x0910, 0x2000 }, { 0x0700, 0x090f, 0x0000 }, { 0x0700, 0x0911, 0x0000 }, { 0x8700, 0x0914, 0x2000 }, { 0x0700, 0x0913, 0x0000 }, { 0x0700, 0x0915, 0x0000 }, { 0x8700, 0x091e, 0x4000 }, { 0x8700, 0x091a, 0x3000 }, { 0x8700, 0x0918, 0x2000 }, { 0x0700, 0x0917, 0x0000 }, { 0x0700, 0x0919, 0x0000 }, { 0x8700, 0x091c, 0x2000 }, { 0x0700, 0x091b, 0x0000 }, { 0x0700, 0x091d, 0x0000 }, { 0x8700, 0x0922, 0x3000 }, { 0x8700, 0x0920, 0x2000 }, { 0x0700, 0x091f, 0x0000 }, { 0x0700, 0x0921, 0x0000 }, { 0x8700, 0x0924, 0x2000 }, { 0x0700, 0x0923, 0x0000 }, { 0x0700, 0x0925, 0x0000 }, { 0x8c00, 0x09cd, 0x8000 }, { 0x8d00, 0x096d, 0x7000 }, { 0x8c00, 0x0948, 0x6000 }, { 0x8700, 0x0936, 0x5000 }, { 0x8700, 0x092e, 0x4000 }, { 0x8700, 0x092a, 0x3000 }, { 0x8700, 0x0928, 0x2000 }, { 0x0700, 0x0927, 0x0000 }, { 0x0700, 0x0929, 0x0000 }, { 0x8700, 0x092c, 0x2000 }, { 0x0700, 0x092b, 0x0000 }, { 0x0700, 0x092d, 0x0000 }, { 0x8700, 0x0932, 0x3000 }, { 0x8700, 0x0930, 0x2000 }, { 0x0700, 0x092f, 0x0000 }, { 0x0700, 0x0931, 0x0000 }, { 0x8700, 0x0934, 0x2000 }, { 0x0700, 0x0933, 0x0000 }, { 0x0700, 0x0935, 0x0000 }, { 0x8a00, 0x0940, 0x4000 }, { 0x8c00, 0x093c, 0x3000 }, { 0x8700, 0x0938, 0x2000 }, { 0x0700, 0x0937, 0x0000 }, { 0x0700, 0x0939, 0x0000 }, { 0x8a00, 0x093e, 0x2000 }, { 0x0700, 0x093d, 0x0000 }, { 0x0a00, 0x093f, 0x0000 }, { 0x8c00, 0x0944, 0x3000 }, { 0x8c00, 0x0942, 0x2000 }, { 0x0c00, 0x0941, 0x0000 }, { 0x0c00, 0x0943, 0x0000 }, { 0x8c00, 0x0946, 0x2000 }, { 0x0c00, 0x0945, 0x0000 }, { 0x0c00, 0x0947, 0x0000 }, { 0x8700, 0x095d, 0x5000 }, { 0x8c00, 0x0952, 0x4000 }, { 0x8a00, 0x094c, 0x3000 }, { 0x8a00, 0x094a, 0x2000 }, { 0x0a00, 0x0949, 0x0000 }, { 0x0a00, 0x094b, 0x0000 }, { 0x8700, 0x0950, 0x2000 }, { 0x0c00, 0x094d, 0x0000 }, { 0x0c00, 0x0951, 0x0000 }, { 0x8700, 0x0959, 0x3000 }, { 0x8c00, 0x0954, 0x2000 }, { 0x0c00, 0x0953, 0x0000 }, { 0x0700, 0x0958, 0x0000 }, { 0x8700, 0x095b, 0x2000 }, { 0x0700, 0x095a, 0x0000 }, { 0x0700, 0x095c, 0x0000 }, { 0x9500, 0x0965, 0x4000 }, { 0x8700, 0x0961, 0x3000 }, { 0x8700, 0x095f, 0x2000 }, { 0x0700, 0x095e, 0x0000 }, { 0x0700, 0x0960, 0x0000 }, { 0x8c00, 0x0963, 0x2000 }, { 0x0c00, 0x0962, 0x0000 }, { 0x1500, 0x0964, 0x0000 }, { 0x8d00, 0x0969, 0x3000 }, { 0x8d00, 0x0967, 0x2000 }, { 0x0d00, 0x0966, 0x0000 }, { 0x0d00, 0x0968, 0x0000 }, { 0x8d00, 0x096b, 0x2000 }, { 0x0d00, 0x096a, 0x0000 }, { 0x0d00, 0x096c, 0x0000 }, { 0x8700, 0x09a2, 0x6000 }, { 0x8700, 0x0990, 0x5000 }, { 0x8700, 0x0986, 0x4000 }, { 0x8c00, 0x0981, 0x3000 }, { 0x8d00, 0x096f, 0x2000 }, { 0x0d00, 0x096e, 0x0000 }, { 0x1500, 0x0970, 0x0000 }, { 0x8a00, 0x0983, 0x2000 }, { 0x0a00, 0x0982, 0x0000 }, { 0x0700, 0x0985, 0x0000 }, { 0x8700, 0x098a, 0x3000 }, { 0x8700, 0x0988, 0x2000 }, { 0x0700, 0x0987, 0x0000 }, { 0x0700, 0x0989, 0x0000 }, { 0x8700, 0x098c, 0x2000 }, { 0x0700, 0x098b, 0x0000 }, { 0x0700, 0x098f, 0x0000 }, { 0x8700, 0x099a, 0x4000 }, { 0x8700, 0x0996, 0x3000 }, { 0x8700, 0x0994, 0x2000 }, { 0x0700, 0x0993, 0x0000 }, { 0x0700, 0x0995, 0x0000 }, { 0x8700, 0x0998, 0x2000 }, { 0x0700, 0x0997, 0x0000 }, { 0x0700, 0x0999, 0x0000 }, { 0x8700, 0x099e, 0x3000 }, { 0x8700, 0x099c, 0x2000 }, { 0x0700, 0x099b, 0x0000 }, { 0x0700, 0x099d, 0x0000 }, { 0x8700, 0x09a0, 0x2000 }, { 0x0700, 0x099f, 0x0000 }, { 0x0700, 0x09a1, 0x0000 }, { 0x8700, 0x09b7, 0x5000 }, { 0x8700, 0x09ab, 0x4000 }, { 0x8700, 0x09a6, 0x3000 }, { 0x8700, 0x09a4, 0x2000 }, { 0x0700, 0x09a3, 0x0000 }, { 0x0700, 0x09a5, 0x0000 }, { 0x8700, 0x09a8, 0x2000 }, { 0x0700, 0x09a7, 0x0000 }, { 0x0700, 0x09aa, 0x0000 }, { 0x8700, 0x09af, 0x3000 }, { 0x8700, 0x09ad, 0x2000 }, { 0x0700, 0x09ac, 0x0000 }, { 0x0700, 0x09ae, 0x0000 }, { 0x8700, 0x09b2, 0x2000 }, { 0x0700, 0x09b0, 0x0000 }, { 0x0700, 0x09b6, 0x0000 }, { 0x8c00, 0x09c1, 0x4000 }, { 0x8700, 0x09bd, 0x3000 }, { 0x8700, 0x09b9, 0x2000 }, { 0x0700, 0x09b8, 0x0000 }, { 0x0c00, 0x09bc, 0x0000 }, { 0x8a00, 0x09bf, 0x2000 }, { 0x0a00, 0x09be, 0x0000 }, { 0x0a00, 0x09c0, 0x0000 }, { 0x8a00, 0x09c7, 0x3000 }, { 0x8c00, 0x09c3, 0x2000 }, { 0x0c00, 0x09c2, 0x0000 }, { 0x0c00, 0x09c4, 0x0000 }, { 0x8a00, 0x09cb, 0x2000 }, { 0x0a00, 0x09c8, 0x0000 }, { 0x0a00, 0x09cc, 0x0000 }, { 0x8700, 0x0a2b, 0x7000 }, { 0x8a00, 0x0a03, 0x6000 }, { 0x8d00, 0x09ed, 0x5000 }, { 0x8c00, 0x09e3, 0x4000 }, { 0x8700, 0x09df, 0x3000 }, { 0x8700, 0x09dc, 0x2000 }, { 0x0a00, 0x09d7, 0x0000 }, { 0x0700, 0x09dd, 0x0000 }, { 0x8700, 0x09e1, 0x2000 }, { 0x0700, 0x09e0, 0x0000 }, { 0x0c00, 0x09e2, 0x0000 }, { 0x8d00, 0x09e9, 0x3000 }, { 0x8d00, 0x09e7, 0x2000 }, { 0x0d00, 0x09e6, 0x0000 }, { 0x0d00, 0x09e8, 0x0000 }, { 0x8d00, 0x09eb, 0x2000 }, { 0x0d00, 0x09ea, 0x0000 }, { 0x0d00, 0x09ec, 0x0000 }, { 0x8f00, 0x09f5, 0x4000 }, { 0x8700, 0x09f1, 0x3000 }, { 0x8d00, 0x09ef, 0x2000 }, { 0x0d00, 0x09ee, 0x0000 }, { 0x0700, 0x09f0, 0x0000 }, { 0x9700, 0x09f3, 0x2000 }, { 0x1700, 0x09f2, 0x0000 }, { 0x0f00, 0x09f4, 0x0000 }, { 0x8f00, 0x09f9, 0x3000 }, { 0x8f00, 0x09f7, 0x2000 }, { 0x0f00, 0x09f6, 0x0000 }, { 0x0f00, 0x09f8, 0x0000 }, { 0x8c00, 0x0a01, 0x2000 }, { 0x1a00, 0x09fa, 0x0000 }, { 0x0c00, 0x0a02, 0x0000 }, { 0x8700, 0x0a1a, 0x5000 }, { 0x8700, 0x0a10, 0x4000 }, { 0x8700, 0x0a08, 0x3000 }, { 0x8700, 0x0a06, 0x2000 }, { 0x0700, 0x0a05, 0x0000 }, { 0x0700, 0x0a07, 0x0000 }, { 0x8700, 0x0a0a, 0x2000 }, { 0x0700, 0x0a09, 0x0000 }, { 0x0700, 0x0a0f, 0x0000 }, { 0x8700, 0x0a16, 0x3000 }, { 0x8700, 0x0a14, 0x2000 }, { 0x0700, 0x0a13, 0x0000 }, { 0x0700, 0x0a15, 0x0000 }, { 0x8700, 0x0a18, 0x2000 }, { 0x0700, 0x0a17, 0x0000 }, { 0x0700, 0x0a19, 0x0000 }, { 0x8700, 0x0a22, 0x4000 }, { 0x8700, 0x0a1e, 0x3000 }, { 0x8700, 0x0a1c, 0x2000 }, { 0x0700, 0x0a1b, 0x0000 }, { 0x0700, 0x0a1d, 0x0000 }, { 0x8700, 0x0a20, 0x2000 }, { 0x0700, 0x0a1f, 0x0000 }, { 0x0700, 0x0a21, 0x0000 }, { 0x8700, 0x0a26, 0x3000 }, { 0x8700, 0x0a24, 0x2000 }, { 0x0700, 0x0a23, 0x0000 }, { 0x0700, 0x0a25, 0x0000 }, { 0x8700, 0x0a28, 0x2000 }, { 0x0700, 0x0a27, 0x0000 }, { 0x0700, 0x0a2a, 0x0000 }, { 0x8d00, 0x0a6a, 0x6000 }, { 0x8c00, 0x0a41, 0x5000 }, { 0x8700, 0x0a35, 0x4000 }, { 0x8700, 0x0a2f, 0x3000 }, { 0x8700, 0x0a2d, 0x2000 }, { 0x0700, 0x0a2c, 0x0000 }, { 0x0700, 0x0a2e, 0x0000 }, { 0x8700, 0x0a32, 0x2000 }, { 0x0700, 0x0a30, 0x0000 }, { 0x0700, 0x0a33, 0x0000 }, { 0x8c00, 0x0a3c, 0x3000 }, { 0x8700, 0x0a38, 0x2000 }, { 0x0700, 0x0a36, 0x0000 }, { 0x0700, 0x0a39, 0x0000 }, { 0x8a00, 0x0a3f, 0x2000 }, { 0x0a00, 0x0a3e, 0x0000 }, { 0x0a00, 0x0a40, 0x0000 }, { 0x8700, 0x0a5a, 0x4000 }, { 0x8c00, 0x0a4b, 0x3000 }, { 0x8c00, 0x0a47, 0x2000 }, { 0x0c00, 0x0a42, 0x0000 }, { 0x0c00, 0x0a48, 0x0000 }, { 0x8c00, 0x0a4d, 0x2000 }, { 0x0c00, 0x0a4c, 0x0000 }, { 0x0700, 0x0a59, 0x0000 }, { 0x8d00, 0x0a66, 0x3000 }, { 0x8700, 0x0a5c, 0x2000 }, { 0x0700, 0x0a5b, 0x0000 }, { 0x0700, 0x0a5e, 0x0000 }, { 0x8d00, 0x0a68, 0x2000 }, { 0x0d00, 0x0a67, 0x0000 }, { 0x0d00, 0x0a69, 0x0000 }, { 0x8700, 0x0a87, 0x5000 }, { 0x8700, 0x0a72, 0x4000 }, { 0x8d00, 0x0a6e, 0x3000 }, { 0x8d00, 0x0a6c, 0x2000 }, { 0x0d00, 0x0a6b, 0x0000 }, { 0x0d00, 0x0a6d, 0x0000 }, { 0x8c00, 0x0a70, 0x2000 }, { 0x0d00, 0x0a6f, 0x0000 }, { 0x0c00, 0x0a71, 0x0000 }, { 0x8c00, 0x0a82, 0x3000 }, { 0x8700, 0x0a74, 0x2000 }, { 0x0700, 0x0a73, 0x0000 }, { 0x0c00, 0x0a81, 0x0000 }, { 0x8700, 0x0a85, 0x2000 }, { 0x0a00, 0x0a83, 0x0000 }, { 0x0700, 0x0a86, 0x0000 }, { 0x8700, 0x0a90, 0x4000 }, { 0x8700, 0x0a8b, 0x3000 }, { 0x8700, 0x0a89, 0x2000 }, { 0x0700, 0x0a88, 0x0000 }, { 0x0700, 0x0a8a, 0x0000 }, { 0x8700, 0x0a8d, 0x2000 }, { 0x0700, 0x0a8c, 0x0000 }, { 0x0700, 0x0a8f, 0x0000 }, { 0x8700, 0x0a95, 0x3000 }, { 0x8700, 0x0a93, 0x2000 }, { 0x0700, 0x0a91, 0x0000 }, { 0x0700, 0x0a94, 0x0000 }, { 0x8700, 0x0a97, 0x2000 }, { 0x0700, 0x0a96, 0x0000 }, { 0x0700, 0x0a98, 0x0000 }, { 0x8700, 0x10ef, 0xb000 }, { 0x8700, 0x0dc6, 0xa000 }, { 0x8700, 0x0c31, 0x9000 }, { 0x8700, 0x0b5f, 0x8000 }, { 0x8a00, 0x0b03, 0x7000 }, { 0x8a00, 0x0abe, 0x6000 }, { 0x8700, 0x0aaa, 0x5000 }, { 0x8700, 0x0aa1, 0x4000 }, { 0x8700, 0x0a9d, 0x3000 }, { 0x8700, 0x0a9b, 0x2000 }, { 0x0700, 0x0a9a, 0x0000 }, { 0x0700, 0x0a9c, 0x0000 }, { 0x8700, 0x0a9f, 0x2000 }, { 0x0700, 0x0a9e, 0x0000 }, { 0x0700, 0x0aa0, 0x0000 }, { 0x8700, 0x0aa5, 0x3000 }, { 0x8700, 0x0aa3, 0x2000 }, { 0x0700, 0x0aa2, 0x0000 }, { 0x0700, 0x0aa4, 0x0000 }, { 0x8700, 0x0aa7, 0x2000 }, { 0x0700, 0x0aa6, 0x0000 }, { 0x0700, 0x0aa8, 0x0000 }, { 0x8700, 0x0ab3, 0x4000 }, { 0x8700, 0x0aae, 0x3000 }, { 0x8700, 0x0aac, 0x2000 }, { 0x0700, 0x0aab, 0x0000 }, { 0x0700, 0x0aad, 0x0000 }, { 0x8700, 0x0ab0, 0x2000 }, { 0x0700, 0x0aaf, 0x0000 }, { 0x0700, 0x0ab2, 0x0000 }, { 0x8700, 0x0ab8, 0x3000 }, { 0x8700, 0x0ab6, 0x2000 }, { 0x0700, 0x0ab5, 0x0000 }, { 0x0700, 0x0ab7, 0x0000 }, { 0x8c00, 0x0abc, 0x2000 }, { 0x0700, 0x0ab9, 0x0000 }, { 0x0700, 0x0abd, 0x0000 }, { 0x8700, 0x0ae1, 0x5000 }, { 0x8c00, 0x0ac7, 0x4000 }, { 0x8c00, 0x0ac2, 0x3000 }, { 0x8a00, 0x0ac0, 0x2000 }, { 0x0a00, 0x0abf, 0x0000 }, { 0x0c00, 0x0ac1, 0x0000 }, { 0x8c00, 0x0ac4, 0x2000 }, { 0x0c00, 0x0ac3, 0x0000 }, { 0x0c00, 0x0ac5, 0x0000 }, { 0x8a00, 0x0acc, 0x3000 }, { 0x8a00, 0x0ac9, 0x2000 }, { 0x0c00, 0x0ac8, 0x0000 }, { 0x0a00, 0x0acb, 0x0000 }, { 0x8700, 0x0ad0, 0x2000 }, { 0x0c00, 0x0acd, 0x0000 }, { 0x0700, 0x0ae0, 0x0000 }, { 0x8d00, 0x0aeb, 0x4000 }, { 0x8d00, 0x0ae7, 0x3000 }, { 0x8c00, 0x0ae3, 0x2000 }, { 0x0c00, 0x0ae2, 0x0000 }, { 0x0d00, 0x0ae6, 0x0000 }, { 0x8d00, 0x0ae9, 0x2000 }, { 0x0d00, 0x0ae8, 0x0000 }, { 0x0d00, 0x0aea, 0x0000 }, { 0x8d00, 0x0aef, 0x3000 }, { 0x8d00, 0x0aed, 0x2000 }, { 0x0d00, 0x0aec, 0x0000 }, { 0x0d00, 0x0aee, 0x0000 }, { 0x8c00, 0x0b01, 0x2000 }, { 0x1700, 0x0af1, 0x0000 }, { 0x0a00, 0x0b02, 0x0000 }, { 0x8700, 0x0b28, 0x6000 }, { 0x8700, 0x0b18, 0x5000 }, { 0x8700, 0x0b0c, 0x4000 }, { 0x8700, 0x0b08, 0x3000 }, { 0x8700, 0x0b06, 0x2000 }, { 0x0700, 0x0b05, 0x0000 }, { 0x0700, 0x0b07, 0x0000 }, { 0x8700, 0x0b0a, 0x2000 }, { 0x0700, 0x0b09, 0x0000 }, { 0x0700, 0x0b0b, 0x0000 }, { 0x8700, 0x0b14, 0x3000 }, { 0x8700, 0x0b10, 0x2000 }, { 0x0700, 0x0b0f, 0x0000 }, { 0x0700, 0x0b13, 0x0000 }, { 0x8700, 0x0b16, 0x2000 }, { 0x0700, 0x0b15, 0x0000 }, { 0x0700, 0x0b17, 0x0000 }, { 0x8700, 0x0b20, 0x4000 }, { 0x8700, 0x0b1c, 0x3000 }, { 0x8700, 0x0b1a, 0x2000 }, { 0x0700, 0x0b19, 0x0000 }, { 0x0700, 0x0b1b, 0x0000 }, { 0x8700, 0x0b1e, 0x2000 }, { 0x0700, 0x0b1d, 0x0000 }, { 0x0700, 0x0b1f, 0x0000 }, { 0x8700, 0x0b24, 0x3000 }, { 0x8700, 0x0b22, 0x2000 }, { 0x0700, 0x0b21, 0x0000 }, { 0x0700, 0x0b23, 0x0000 }, { 0x8700, 0x0b26, 0x2000 }, { 0x0700, 0x0b25, 0x0000 }, { 0x0700, 0x0b27, 0x0000 }, { 0x8700, 0x0b3d, 0x5000 }, { 0x8700, 0x0b32, 0x4000 }, { 0x8700, 0x0b2d, 0x3000 }, { 0x8700, 0x0b2b, 0x2000 }, { 0x0700, 0x0b2a, 0x0000 }, { 0x0700, 0x0b2c, 0x0000 }, { 0x8700, 0x0b2f, 0x2000 }, { 0x0700, 0x0b2e, 0x0000 }, { 0x0700, 0x0b30, 0x0000 }, { 0x8700, 0x0b37, 0x3000 }, { 0x8700, 0x0b35, 0x2000 }, { 0x0700, 0x0b33, 0x0000 }, { 0x0700, 0x0b36, 0x0000 }, { 0x8700, 0x0b39, 0x2000 }, { 0x0700, 0x0b38, 0x0000 }, { 0x0c00, 0x0b3c, 0x0000 }, { 0x8a00, 0x0b48, 0x4000 }, { 0x8c00, 0x0b41, 0x3000 }, { 0x8c00, 0x0b3f, 0x2000 }, { 0x0a00, 0x0b3e, 0x0000 }, { 0x0a00, 0x0b40, 0x0000 }, { 0x8c00, 0x0b43, 0x2000 }, { 0x0c00, 0x0b42, 0x0000 }, { 0x0a00, 0x0b47, 0x0000 }, { 0x8c00, 0x0b56, 0x3000 }, { 0x8a00, 0x0b4c, 0x2000 }, { 0x0a00, 0x0b4b, 0x0000 }, { 0x0c00, 0x0b4d, 0x0000 }, { 0x8700, 0x0b5c, 0x2000 }, { 0x0a00, 0x0b57, 0x0000 }, { 0x0700, 0x0b5d, 0x0000 }, { 0x8d00, 0x0be7, 0x7000 }, { 0x8700, 0x0b9c, 0x6000 }, { 0x8700, 0x0b83, 0x5000 }, { 0x8d00, 0x0b6b, 0x4000 }, { 0x8d00, 0x0b67, 0x3000 }, { 0x8700, 0x0b61, 0x2000 }, { 0x0700, 0x0b60, 0x0000 }, { 0x0d00, 0x0b66, 0x0000 }, { 0x8d00, 0x0b69, 0x2000 }, { 0x0d00, 0x0b68, 0x0000 }, { 0x0d00, 0x0b6a, 0x0000 }, { 0x8d00, 0x0b6f, 0x3000 }, { 0x8d00, 0x0b6d, 0x2000 }, { 0x0d00, 0x0b6c, 0x0000 }, { 0x0d00, 0x0b6e, 0x0000 }, { 0x8700, 0x0b71, 0x2000 }, { 0x1a00, 0x0b70, 0x0000 }, { 0x0c00, 0x0b82, 0x0000 }, { 0x8700, 0x0b8f, 0x4000 }, { 0x8700, 0x0b88, 0x3000 }, { 0x8700, 0x0b86, 0x2000 }, { 0x0700, 0x0b85, 0x0000 }, { 0x0700, 0x0b87, 0x0000 }, { 0x8700, 0x0b8a, 0x2000 }, { 0x0700, 0x0b89, 0x0000 }, { 0x0700, 0x0b8e, 0x0000 }, { 0x8700, 0x0b94, 0x3000 }, { 0x8700, 0x0b92, 0x2000 }, { 0x0700, 0x0b90, 0x0000 }, { 0x0700, 0x0b93, 0x0000 }, { 0x8700, 0x0b99, 0x2000 }, { 0x0700, 0x0b95, 0x0000 }, { 0x0700, 0x0b9a, 0x0000 }, { 0x8700, 0x0bb7, 0x5000 }, { 0x8700, 0x0bae, 0x4000 }, { 0x8700, 0x0ba4, 0x3000 }, { 0x8700, 0x0b9f, 0x2000 }, { 0x0700, 0x0b9e, 0x0000 }, { 0x0700, 0x0ba3, 0x0000 }, { 0x8700, 0x0ba9, 0x2000 }, { 0x0700, 0x0ba8, 0x0000 }, { 0x0700, 0x0baa, 0x0000 }, { 0x8700, 0x0bb2, 0x3000 }, { 0x8700, 0x0bb0, 0x2000 }, { 0x0700, 0x0baf, 0x0000 }, { 0x0700, 0x0bb1, 0x0000 }, { 0x8700, 0x0bb4, 0x2000 }, { 0x0700, 0x0bb3, 0x0000 }, { 0x0700, 0x0bb5, 0x0000 }, { 0x8a00, 0x0bc6, 0x4000 }, { 0x8a00, 0x0bbf, 0x3000 }, { 0x8700, 0x0bb9, 0x2000 }, { 0x0700, 0x0bb8, 0x0000 }, { 0x0a00, 0x0bbe, 0x0000 }, { 0x8a00, 0x0bc1, 0x2000 }, { 0x0c00, 0x0bc0, 0x0000 }, { 0x0a00, 0x0bc2, 0x0000 }, { 0x8a00, 0x0bcb, 0x3000 }, { 0x8a00, 0x0bc8, 0x2000 }, { 0x0a00, 0x0bc7, 0x0000 }, { 0x0a00, 0x0bca, 0x0000 }, { 0x8c00, 0x0bcd, 0x2000 }, { 0x0a00, 0x0bcc, 0x0000 }, { 0x0a00, 0x0bd7, 0x0000 }, { 0x8700, 0x0c0f, 0x6000 }, { 0x9a00, 0x0bf7, 0x5000 }, { 0x8d00, 0x0bef, 0x4000 }, { 0x8d00, 0x0beb, 0x3000 }, { 0x8d00, 0x0be9, 0x2000 }, { 0x0d00, 0x0be8, 0x0000 }, { 0x0d00, 0x0bea, 0x0000 }, { 0x8d00, 0x0bed, 0x2000 }, { 0x0d00, 0x0bec, 0x0000 }, { 0x0d00, 0x0bee, 0x0000 }, { 0x9a00, 0x0bf3, 0x3000 }, { 0x8f00, 0x0bf1, 0x2000 }, { 0x0f00, 0x0bf0, 0x0000 }, { 0x0f00, 0x0bf2, 0x0000 }, { 0x9a00, 0x0bf5, 0x2000 }, { 0x1a00, 0x0bf4, 0x0000 }, { 0x1a00, 0x0bf6, 0x0000 }, { 0x8700, 0x0c06, 0x4000 }, { 0x8a00, 0x0c01, 0x3000 }, { 0x9700, 0x0bf9, 0x2000 }, { 0x1a00, 0x0bf8, 0x0000 }, { 0x1a00, 0x0bfa, 0x0000 }, { 0x8a00, 0x0c03, 0x2000 }, { 0x0a00, 0x0c02, 0x0000 }, { 0x0700, 0x0c05, 0x0000 }, { 0x8700, 0x0c0a, 0x3000 }, { 0x8700, 0x0c08, 0x2000 }, { 0x0700, 0x0c07, 0x0000 }, { 0x0700, 0x0c09, 0x0000 }, { 0x8700, 0x0c0c, 0x2000 }, { 0x0700, 0x0c0b, 0x0000 }, { 0x0700, 0x0c0e, 0x0000 }, { 0x8700, 0x0c20, 0x5000 }, { 0x8700, 0x0c18, 0x4000 }, { 0x8700, 0x0c14, 0x3000 }, { 0x8700, 0x0c12, 0x2000 }, { 0x0700, 0x0c10, 0x0000 }, { 0x0700, 0x0c13, 0x0000 }, { 0x8700, 0x0c16, 0x2000 }, { 0x0700, 0x0c15, 0x0000 }, { 0x0700, 0x0c17, 0x0000 }, { 0x8700, 0x0c1c, 0x3000 }, { 0x8700, 0x0c1a, 0x2000 }, { 0x0700, 0x0c19, 0x0000 }, { 0x0700, 0x0c1b, 0x0000 }, { 0x8700, 0x0c1e, 0x2000 }, { 0x0700, 0x0c1d, 0x0000 }, { 0x0700, 0x0c1f, 0x0000 }, { 0x8700, 0x0c28, 0x4000 }, { 0x8700, 0x0c24, 0x3000 }, { 0x8700, 0x0c22, 0x2000 }, { 0x0700, 0x0c21, 0x0000 }, { 0x0700, 0x0c23, 0x0000 }, { 0x8700, 0x0c26, 0x2000 }, { 0x0700, 0x0c25, 0x0000 }, { 0x0700, 0x0c27, 0x0000 }, { 0x8700, 0x0c2d, 0x3000 }, { 0x8700, 0x0c2b, 0x2000 }, { 0x0700, 0x0c2a, 0x0000 }, { 0x0700, 0x0c2c, 0x0000 }, { 0x8700, 0x0c2f, 0x2000 }, { 0x0700, 0x0c2e, 0x0000 }, { 0x0700, 0x0c30, 0x0000 }, { 0x8700, 0x0d0e, 0x8000 }, { 0x8700, 0x0ca1, 0x7000 }, { 0x8d00, 0x0c6c, 0x6000 }, { 0x8c00, 0x0c47, 0x5000 }, { 0x8c00, 0x0c3e, 0x4000 }, { 0x8700, 0x0c36, 0x3000 }, { 0x8700, 0x0c33, 0x2000 }, { 0x0700, 0x0c32, 0x0000 }, { 0x0700, 0x0c35, 0x0000 }, { 0x8700, 0x0c38, 0x2000 }, { 0x0700, 0x0c37, 0x0000 }, { 0x0700, 0x0c39, 0x0000 }, { 0x8a00, 0x0c42, 0x3000 }, { 0x8c00, 0x0c40, 0x2000 }, { 0x0c00, 0x0c3f, 0x0000 }, { 0x0a00, 0x0c41, 0x0000 }, { 0x8a00, 0x0c44, 0x2000 }, { 0x0a00, 0x0c43, 0x0000 }, { 0x0c00, 0x0c46, 0x0000 }, { 0x8700, 0x0c60, 0x4000 }, { 0x8c00, 0x0c4c, 0x3000 }, { 0x8c00, 0x0c4a, 0x2000 }, { 0x0c00, 0x0c48, 0x0000 }, { 0x0c00, 0x0c4b, 0x0000 }, { 0x8c00, 0x0c55, 0x2000 }, { 0x0c00, 0x0c4d, 0x0000 }, { 0x0c00, 0x0c56, 0x0000 }, { 0x8d00, 0x0c68, 0x3000 }, { 0x8d00, 0x0c66, 0x2000 }, { 0x0700, 0x0c61, 0x0000 }, { 0x0d00, 0x0c67, 0x0000 }, { 0x8d00, 0x0c6a, 0x2000 }, { 0x0d00, 0x0c69, 0x0000 }, { 0x0d00, 0x0c6b, 0x0000 }, { 0x8700, 0x0c90, 0x5000 }, { 0x8700, 0x0c87, 0x4000 }, { 0x8a00, 0x0c82, 0x3000 }, { 0x8d00, 0x0c6e, 0x2000 }, { 0x0d00, 0x0c6d, 0x0000 }, { 0x0d00, 0x0c6f, 0x0000 }, { 0x8700, 0x0c85, 0x2000 }, { 0x0a00, 0x0c83, 0x0000 }, { 0x0700, 0x0c86, 0x0000 }, { 0x8700, 0x0c8b, 0x3000 }, { 0x8700, 0x0c89, 0x2000 }, { 0x0700, 0x0c88, 0x0000 }, { 0x0700, 0x0c8a, 0x0000 }, { 0x8700, 0x0c8e, 0x2000 }, { 0x0700, 0x0c8c, 0x0000 }, { 0x0700, 0x0c8f, 0x0000 }, { 0x8700, 0x0c99, 0x4000 }, { 0x8700, 0x0c95, 0x3000 }, { 0x8700, 0x0c93, 0x2000 }, { 0x0700, 0x0c92, 0x0000 }, { 0x0700, 0x0c94, 0x0000 }, { 0x8700, 0x0c97, 0x2000 }, { 0x0700, 0x0c96, 0x0000 }, { 0x0700, 0x0c98, 0x0000 }, { 0x8700, 0x0c9d, 0x3000 }, { 0x8700, 0x0c9b, 0x2000 }, { 0x0700, 0x0c9a, 0x0000 }, { 0x0700, 0x0c9c, 0x0000 }, { 0x8700, 0x0c9f, 0x2000 }, { 0x0700, 0x0c9e, 0x0000 }, { 0x0700, 0x0ca0, 0x0000 }, { 0x8c00, 0x0cc6, 0x6000 }, { 0x8700, 0x0cb2, 0x5000 }, { 0x8700, 0x0caa, 0x4000 }, { 0x8700, 0x0ca5, 0x3000 }, { 0x8700, 0x0ca3, 0x2000 }, { 0x0700, 0x0ca2, 0x0000 }, { 0x0700, 0x0ca4, 0x0000 }, { 0x8700, 0x0ca7, 0x2000 }, { 0x0700, 0x0ca6, 0x0000 }, { 0x0700, 0x0ca8, 0x0000 }, { 0x8700, 0x0cae, 0x3000 }, { 0x8700, 0x0cac, 0x2000 }, { 0x0700, 0x0cab, 0x0000 }, { 0x0700, 0x0cad, 0x0000 }, { 0x8700, 0x0cb0, 0x2000 }, { 0x0700, 0x0caf, 0x0000 }, { 0x0700, 0x0cb1, 0x0000 }, { 0x8700, 0x0cbd, 0x4000 }, { 0x8700, 0x0cb7, 0x3000 }, { 0x8700, 0x0cb5, 0x2000 }, { 0x0700, 0x0cb3, 0x0000 }, { 0x0700, 0x0cb6, 0x0000 }, { 0x8700, 0x0cb9, 0x2000 }, { 0x0700, 0x0cb8, 0x0000 }, { 0x0c00, 0x0cbc, 0x0000 }, { 0x8a00, 0x0cc1, 0x3000 }, { 0x8c00, 0x0cbf, 0x2000 }, { 0x0a00, 0x0cbe, 0x0000 }, { 0x0a00, 0x0cc0, 0x0000 }, { 0x8a00, 0x0cc3, 0x2000 }, { 0x0a00, 0x0cc2, 0x0000 }, { 0x0a00, 0x0cc4, 0x0000 }, { 0x8d00, 0x0cea, 0x5000 }, { 0x8a00, 0x0cd6, 0x4000 }, { 0x8a00, 0x0ccb, 0x3000 }, { 0x8a00, 0x0cc8, 0x2000 }, { 0x0a00, 0x0cc7, 0x0000 }, { 0x0a00, 0x0cca, 0x0000 }, { 0x8c00, 0x0ccd, 0x2000 }, { 0x0c00, 0x0ccc, 0x0000 }, { 0x0a00, 0x0cd5, 0x0000 }, { 0x8d00, 0x0ce6, 0x3000 }, { 0x8700, 0x0ce0, 0x2000 }, { 0x0700, 0x0cde, 0x0000 }, { 0x0700, 0x0ce1, 0x0000 }, { 0x8d00, 0x0ce8, 0x2000 }, { 0x0d00, 0x0ce7, 0x0000 }, { 0x0d00, 0x0ce9, 0x0000 }, { 0x8700, 0x0d05, 0x4000 }, { 0x8d00, 0x0cee, 0x3000 }, { 0x8d00, 0x0cec, 0x2000 }, { 0x0d00, 0x0ceb, 0x0000 }, { 0x0d00, 0x0ced, 0x0000 }, { 0x8a00, 0x0d02, 0x2000 }, { 0x0d00, 0x0cef, 0x0000 }, { 0x0a00, 0x0d03, 0x0000 }, { 0x8700, 0x0d09, 0x3000 }, { 0x8700, 0x0d07, 0x2000 }, { 0x0700, 0x0d06, 0x0000 }, { 0x0700, 0x0d08, 0x0000 }, { 0x8700, 0x0d0b, 0x2000 }, { 0x0700, 0x0d0a, 0x0000 }, { 0x0700, 0x0d0c, 0x0000 }, { 0x8d00, 0x0d6c, 0x7000 }, { 0x8700, 0x0d30, 0x6000 }, { 0x8700, 0x0d1f, 0x5000 }, { 0x8700, 0x0d17, 0x4000 }, { 0x8700, 0x0d13, 0x3000 }, { 0x8700, 0x0d10, 0x2000 }, { 0x0700, 0x0d0f, 0x0000 }, { 0x0700, 0x0d12, 0x0000 }, { 0x8700, 0x0d15, 0x2000 }, { 0x0700, 0x0d14, 0x0000 }, { 0x0700, 0x0d16, 0x0000 }, { 0x8700, 0x0d1b, 0x3000 }, { 0x8700, 0x0d19, 0x2000 }, { 0x0700, 0x0d18, 0x0000 }, { 0x0700, 0x0d1a, 0x0000 }, { 0x8700, 0x0d1d, 0x2000 }, { 0x0700, 0x0d1c, 0x0000 }, { 0x0700, 0x0d1e, 0x0000 }, { 0x8700, 0x0d27, 0x4000 }, { 0x8700, 0x0d23, 0x3000 }, { 0x8700, 0x0d21, 0x2000 }, { 0x0700, 0x0d20, 0x0000 }, { 0x0700, 0x0d22, 0x0000 }, { 0x8700, 0x0d25, 0x2000 }, { 0x0700, 0x0d24, 0x0000 }, { 0x0700, 0x0d26, 0x0000 }, { 0x8700, 0x0d2c, 0x3000 }, { 0x8700, 0x0d2a, 0x2000 }, { 0x0700, 0x0d28, 0x0000 }, { 0x0700, 0x0d2b, 0x0000 }, { 0x8700, 0x0d2e, 0x2000 }, { 0x0700, 0x0d2d, 0x0000 }, { 0x0700, 0x0d2f, 0x0000 }, { 0x8a00, 0x0d46, 0x5000 }, { 0x8700, 0x0d38, 0x4000 }, { 0x8700, 0x0d34, 0x3000 }, { 0x8700, 0x0d32, 0x2000 }, { 0x0700, 0x0d31, 0x0000 }, { 0x0700, 0x0d33, 0x0000 }, { 0x8700, 0x0d36, 0x2000 }, { 0x0700, 0x0d35, 0x0000 }, { 0x0700, 0x0d37, 0x0000 }, { 0x8a00, 0x0d40, 0x3000 }, { 0x8a00, 0x0d3e, 0x2000 }, { 0x0700, 0x0d39, 0x0000 }, { 0x0a00, 0x0d3f, 0x0000 }, { 0x8c00, 0x0d42, 0x2000 }, { 0x0c00, 0x0d41, 0x0000 }, { 0x0c00, 0x0d43, 0x0000 }, { 0x8700, 0x0d60, 0x4000 }, { 0x8a00, 0x0d4b, 0x3000 }, { 0x8a00, 0x0d48, 0x2000 }, { 0x0a00, 0x0d47, 0x0000 }, { 0x0a00, 0x0d4a, 0x0000 }, { 0x8c00, 0x0d4d, 0x2000 }, { 0x0a00, 0x0d4c, 0x0000 }, { 0x0a00, 0x0d57, 0x0000 }, { 0x8d00, 0x0d68, 0x3000 }, { 0x8d00, 0x0d66, 0x2000 }, { 0x0700, 0x0d61, 0x0000 }, { 0x0d00, 0x0d67, 0x0000 }, { 0x8d00, 0x0d6a, 0x2000 }, { 0x0d00, 0x0d69, 0x0000 }, { 0x0d00, 0x0d6b, 0x0000 }, { 0x8700, 0x0da2, 0x6000 }, { 0x8700, 0x0d8f, 0x5000 }, { 0x8700, 0x0d87, 0x4000 }, { 0x8a00, 0x0d82, 0x3000 }, { 0x8d00, 0x0d6e, 0x2000 }, { 0x0d00, 0x0d6d, 0x0000 }, { 0x0d00, 0x0d6f, 0x0000 }, { 0x8700, 0x0d85, 0x2000 }, { 0x0a00, 0x0d83, 0x0000 }, { 0x0700, 0x0d86, 0x0000 }, { 0x8700, 0x0d8b, 0x3000 }, { 0x8700, 0x0d89, 0x2000 }, { 0x0700, 0x0d88, 0x0000 }, { 0x0700, 0x0d8a, 0x0000 }, { 0x8700, 0x0d8d, 0x2000 }, { 0x0700, 0x0d8c, 0x0000 }, { 0x0700, 0x0d8e, 0x0000 }, { 0x8700, 0x0d9a, 0x4000 }, { 0x8700, 0x0d93, 0x3000 }, { 0x8700, 0x0d91, 0x2000 }, { 0x0700, 0x0d90, 0x0000 }, { 0x0700, 0x0d92, 0x0000 }, { 0x8700, 0x0d95, 0x2000 }, { 0x0700, 0x0d94, 0x0000 }, { 0x0700, 0x0d96, 0x0000 }, { 0x8700, 0x0d9e, 0x3000 }, { 0x8700, 0x0d9c, 0x2000 }, { 0x0700, 0x0d9b, 0x0000 }, { 0x0700, 0x0d9d, 0x0000 }, { 0x8700, 0x0da0, 0x2000 }, { 0x0700, 0x0d9f, 0x0000 }, { 0x0700, 0x0da1, 0x0000 }, { 0x8700, 0x0db3, 0x5000 }, { 0x8700, 0x0daa, 0x4000 }, { 0x8700, 0x0da6, 0x3000 }, { 0x8700, 0x0da4, 0x2000 }, { 0x0700, 0x0da3, 0x0000 }, { 0x0700, 0x0da5, 0x0000 }, { 0x8700, 0x0da8, 0x2000 }, { 0x0700, 0x0da7, 0x0000 }, { 0x0700, 0x0da9, 0x0000 }, { 0x8700, 0x0dae, 0x3000 }, { 0x8700, 0x0dac, 0x2000 }, { 0x0700, 0x0dab, 0x0000 }, { 0x0700, 0x0dad, 0x0000 }, { 0x8700, 0x0db0, 0x2000 }, { 0x0700, 0x0daf, 0x0000 }, { 0x0700, 0x0db1, 0x0000 }, { 0x8700, 0x0dbb, 0x4000 }, { 0x8700, 0x0db7, 0x3000 }, { 0x8700, 0x0db5, 0x2000 }, { 0x0700, 0x0db4, 0x0000 }, { 0x0700, 0x0db6, 0x0000 }, { 0x8700, 0x0db9, 0x2000 }, { 0x0700, 0x0db8, 0x0000 }, { 0x0700, 0x0dba, 0x0000 }, { 0x8700, 0x0dc2, 0x3000 }, { 0x8700, 0x0dc0, 0x2000 }, { 0x0700, 0x0dbd, 0x0000 }, { 0x0700, 0x0dc1, 0x0000 }, { 0x8700, 0x0dc4, 0x2000 }, { 0x0700, 0x0dc3, 0x0000 }, { 0x0700, 0x0dc5, 0x0000 }, { 0x8700, 0x0f55, 0x9000 }, { 0x8700, 0x0ea5, 0x8000 }, { 0x8700, 0x0e2d, 0x7000 }, { 0x8700, 0x0e0d, 0x6000 }, { 0x8a00, 0x0ddf, 0x5000 }, { 0x8c00, 0x0dd6, 0x4000 }, { 0x8a00, 0x0dd1, 0x3000 }, { 0x8a00, 0x0dcf, 0x2000 }, { 0x0c00, 0x0dca, 0x0000 }, { 0x0a00, 0x0dd0, 0x0000 }, { 0x8c00, 0x0dd3, 0x2000 }, { 0x0c00, 0x0dd2, 0x0000 }, { 0x0c00, 0x0dd4, 0x0000 }, { 0x8a00, 0x0ddb, 0x3000 }, { 0x8a00, 0x0dd9, 0x2000 }, { 0x0a00, 0x0dd8, 0x0000 }, { 0x0a00, 0x0dda, 0x0000 }, { 0x8a00, 0x0ddd, 0x2000 }, { 0x0a00, 0x0ddc, 0x0000 }, { 0x0a00, 0x0dde, 0x0000 }, { 0x8700, 0x0e05, 0x4000 }, { 0x8700, 0x0e01, 0x3000 }, { 0x8a00, 0x0df3, 0x2000 }, { 0x0a00, 0x0df2, 0x0000 }, { 0x1500, 0x0df4, 0x0000 }, { 0x8700, 0x0e03, 0x2000 }, { 0x0700, 0x0e02, 0x0000 }, { 0x0700, 0x0e04, 0x0000 }, { 0x8700, 0x0e09, 0x3000 }, { 0x8700, 0x0e07, 0x2000 }, { 0x0700, 0x0e06, 0x0000 }, { 0x0700, 0x0e08, 0x0000 }, { 0x8700, 0x0e0b, 0x2000 }, { 0x0700, 0x0e0a, 0x0000 }, { 0x0700, 0x0e0c, 0x0000 }, { 0x8700, 0x0e1d, 0x5000 }, { 0x8700, 0x0e15, 0x4000 }, { 0x8700, 0x0e11, 0x3000 }, { 0x8700, 0x0e0f, 0x2000 }, { 0x0700, 0x0e0e, 0x0000 }, { 0x0700, 0x0e10, 0x0000 }, { 0x8700, 0x0e13, 0x2000 }, { 0x0700, 0x0e12, 0x0000 }, { 0x0700, 0x0e14, 0x0000 }, { 0x8700, 0x0e19, 0x3000 }, { 0x8700, 0x0e17, 0x2000 }, { 0x0700, 0x0e16, 0x0000 }, { 0x0700, 0x0e18, 0x0000 }, { 0x8700, 0x0e1b, 0x2000 }, { 0x0700, 0x0e1a, 0x0000 }, { 0x0700, 0x0e1c, 0x0000 }, { 0x8700, 0x0e25, 0x4000 }, { 0x8700, 0x0e21, 0x3000 }, { 0x8700, 0x0e1f, 0x2000 }, { 0x0700, 0x0e1e, 0x0000 }, { 0x0700, 0x0e20, 0x0000 }, { 0x8700, 0x0e23, 0x2000 }, { 0x0700, 0x0e22, 0x0000 }, { 0x0700, 0x0e24, 0x0000 }, { 0x8700, 0x0e29, 0x3000 }, { 0x8700, 0x0e27, 0x2000 }, { 0x0700, 0x0e26, 0x0000 }, { 0x0700, 0x0e28, 0x0000 }, { 0x8700, 0x0e2b, 0x2000 }, { 0x0700, 0x0e2a, 0x0000 }, { 0x0700, 0x0e2c, 0x0000 }, { 0x8d00, 0x0e51, 0x6000 }, { 0x8700, 0x0e41, 0x5000 }, { 0x8c00, 0x0e35, 0x4000 }, { 0x8c00, 0x0e31, 0x3000 }, { 0x8700, 0x0e2f, 0x2000 }, { 0x0700, 0x0e2e, 0x0000 }, { 0x0700, 0x0e30, 0x0000 }, { 0x8700, 0x0e33, 0x2000 }, { 0x0700, 0x0e32, 0x0000 }, { 0x0c00, 0x0e34, 0x0000 }, { 0x8c00, 0x0e39, 0x3000 }, { 0x8c00, 0x0e37, 0x2000 }, { 0x0c00, 0x0e36, 0x0000 }, { 0x0c00, 0x0e38, 0x0000 }, { 0x9700, 0x0e3f, 0x2000 }, { 0x0c00, 0x0e3a, 0x0000 }, { 0x0700, 0x0e40, 0x0000 }, { 0x8c00, 0x0e49, 0x4000 }, { 0x8700, 0x0e45, 0x3000 }, { 0x8700, 0x0e43, 0x2000 }, { 0x0700, 0x0e42, 0x0000 }, { 0x0700, 0x0e44, 0x0000 }, { 0x8c00, 0x0e47, 0x2000 }, { 0x0600, 0x0e46, 0x0000 }, { 0x0c00, 0x0e48, 0x0000 }, { 0x8c00, 0x0e4d, 0x3000 }, { 0x8c00, 0x0e4b, 0x2000 }, { 0x0c00, 0x0e4a, 0x0000 }, { 0x0c00, 0x0e4c, 0x0000 }, { 0x9500, 0x0e4f, 0x2000 }, { 0x0c00, 0x0e4e, 0x0000 }, { 0x0d00, 0x0e50, 0x0000 }, { 0x8700, 0x0e8a, 0x5000 }, { 0x8d00, 0x0e59, 0x4000 }, { 0x8d00, 0x0e55, 0x3000 }, { 0x8d00, 0x0e53, 0x2000 }, { 0x0d00, 0x0e52, 0x0000 }, { 0x0d00, 0x0e54, 0x0000 }, { 0x8d00, 0x0e57, 0x2000 }, { 0x0d00, 0x0e56, 0x0000 }, { 0x0d00, 0x0e58, 0x0000 }, { 0x8700, 0x0e82, 0x3000 }, { 0x9500, 0x0e5b, 0x2000 }, { 0x1500, 0x0e5a, 0x0000 }, { 0x0700, 0x0e81, 0x0000 }, { 0x8700, 0x0e87, 0x2000 }, { 0x0700, 0x0e84, 0x0000 }, { 0x0700, 0x0e88, 0x0000 }, { 0x8700, 0x0e9b, 0x4000 }, { 0x8700, 0x0e96, 0x3000 }, { 0x8700, 0x0e94, 0x2000 }, { 0x0700, 0x0e8d, 0x0000 }, { 0x0700, 0x0e95, 0x0000 }, { 0x8700, 0x0e99, 0x2000 }, { 0x0700, 0x0e97, 0x0000 }, { 0x0700, 0x0e9a, 0x0000 }, { 0x8700, 0x0e9f, 0x3000 }, { 0x8700, 0x0e9d, 0x2000 }, { 0x0700, 0x0e9c, 0x0000 }, { 0x0700, 0x0e9e, 0x0000 }, { 0x8700, 0x0ea2, 0x2000 }, { 0x0700, 0x0ea1, 0x0000 }, { 0x0700, 0x0ea3, 0x0000 }, { 0x9a00, 0x0f14, 0x7000 }, { 0x8d00, 0x0ed0, 0x6000 }, { 0x8c00, 0x0eb9, 0x5000 }, { 0x8c00, 0x0eb1, 0x4000 }, { 0x8700, 0x0ead, 0x3000 }, { 0x8700, 0x0eaa, 0x2000 }, { 0x0700, 0x0ea7, 0x0000 }, { 0x0700, 0x0eab, 0x0000 }, { 0x8700, 0x0eaf, 0x2000 }, { 0x0700, 0x0eae, 0x0000 }, { 0x0700, 0x0eb0, 0x0000 }, { 0x8c00, 0x0eb5, 0x3000 }, { 0x8700, 0x0eb3, 0x2000 }, { 0x0700, 0x0eb2, 0x0000 }, { 0x0c00, 0x0eb4, 0x0000 }, { 0x8c00, 0x0eb7, 0x2000 }, { 0x0c00, 0x0eb6, 0x0000 }, { 0x0c00, 0x0eb8, 0x0000 }, { 0x8700, 0x0ec4, 0x4000 }, { 0x8700, 0x0ec0, 0x3000 }, { 0x8c00, 0x0ebc, 0x2000 }, { 0x0c00, 0x0ebb, 0x0000 }, { 0x0700, 0x0ebd, 0x0000 }, { 0x8700, 0x0ec2, 0x2000 }, { 0x0700, 0x0ec1, 0x0000 }, { 0x0700, 0x0ec3, 0x0000 }, { 0x8c00, 0x0eca, 0x3000 }, { 0x8c00, 0x0ec8, 0x2000 }, { 0x0600, 0x0ec6, 0x0000 }, { 0x0c00, 0x0ec9, 0x0000 }, { 0x8c00, 0x0ecc, 0x2000 }, { 0x0c00, 0x0ecb, 0x0000 }, { 0x0c00, 0x0ecd, 0x0000 }, { 0x9500, 0x0f04, 0x5000 }, { 0x8d00, 0x0ed8, 0x4000 }, { 0x8d00, 0x0ed4, 0x3000 }, { 0x8d00, 0x0ed2, 0x2000 }, { 0x0d00, 0x0ed1, 0x0000 }, { 0x0d00, 0x0ed3, 0x0000 }, { 0x8d00, 0x0ed6, 0x2000 }, { 0x0d00, 0x0ed5, 0x0000 }, { 0x0d00, 0x0ed7, 0x0000 }, { 0x8700, 0x0f00, 0x3000 }, { 0x8700, 0x0edc, 0x2000 }, { 0x0d00, 0x0ed9, 0x0000 }, { 0x0700, 0x0edd, 0x0000 }, { 0x9a00, 0x0f02, 0x2000 }, { 0x1a00, 0x0f01, 0x0000 }, { 0x1a00, 0x0f03, 0x0000 }, { 0x9500, 0x0f0c, 0x4000 }, { 0x9500, 0x0f08, 0x3000 }, { 0x9500, 0x0f06, 0x2000 }, { 0x1500, 0x0f05, 0x0000 }, { 0x1500, 0x0f07, 0x0000 }, { 0x9500, 0x0f0a, 0x2000 }, { 0x1500, 0x0f09, 0x0000 }, { 0x1500, 0x0f0b, 0x0000 }, { 0x9500, 0x0f10, 0x3000 }, { 0x9500, 0x0f0e, 0x2000 }, { 0x1500, 0x0f0d, 0x0000 }, { 0x1500, 0x0f0f, 0x0000 }, { 0x9500, 0x0f12, 0x2000 }, { 0x1500, 0x0f11, 0x0000 }, { 0x1a00, 0x0f13, 0x0000 }, { 0x9a00, 0x0f34, 0x6000 }, { 0x8d00, 0x0f24, 0x5000 }, { 0x9a00, 0x0f1c, 0x4000 }, { 0x8c00, 0x0f18, 0x3000 }, { 0x9a00, 0x0f16, 0x2000 }, { 0x1a00, 0x0f15, 0x0000 }, { 0x1a00, 0x0f17, 0x0000 }, { 0x9a00, 0x0f1a, 0x2000 }, { 0x0c00, 0x0f19, 0x0000 }, { 0x1a00, 0x0f1b, 0x0000 }, { 0x8d00, 0x0f20, 0x3000 }, { 0x9a00, 0x0f1e, 0x2000 }, { 0x1a00, 0x0f1d, 0x0000 }, { 0x1a00, 0x0f1f, 0x0000 }, { 0x8d00, 0x0f22, 0x2000 }, { 0x0d00, 0x0f21, 0x0000 }, { 0x0d00, 0x0f23, 0x0000 }, { 0x8f00, 0x0f2c, 0x4000 }, { 0x8d00, 0x0f28, 0x3000 }, { 0x8d00, 0x0f26, 0x2000 }, { 0x0d00, 0x0f25, 0x0000 }, { 0x0d00, 0x0f27, 0x0000 }, { 0x8f00, 0x0f2a, 0x2000 }, { 0x0d00, 0x0f29, 0x0000 }, { 0x0f00, 0x0f2b, 0x0000 }, { 0x8f00, 0x0f30, 0x3000 }, { 0x8f00, 0x0f2e, 0x2000 }, { 0x0f00, 0x0f2d, 0x0000 }, { 0x0f00, 0x0f2f, 0x0000 }, { 0x8f00, 0x0f32, 0x2000 }, { 0x0f00, 0x0f31, 0x0000 }, { 0x0f00, 0x0f33, 0x0000 }, { 0x8700, 0x0f44, 0x5000 }, { 0x9600, 0x0f3c, 0x4000 }, { 0x9a00, 0x0f38, 0x3000 }, { 0x9a00, 0x0f36, 0x2000 }, { 0x0c00, 0x0f35, 0x0000 }, { 0x0c00, 0x0f37, 0x0000 }, { 0x9600, 0x0f3a, 0x2000 }, { 0x0c00, 0x0f39, 0x0000 }, { 0x1200, 0x0f3b, 0x0000 }, { 0x8700, 0x0f40, 0x3000 }, { 0x8a00, 0x0f3e, 0x2000 }, { 0x1200, 0x0f3d, 0x0000 }, { 0x0a00, 0x0f3f, 0x0000 }, { 0x8700, 0x0f42, 0x2000 }, { 0x0700, 0x0f41, 0x0000 }, { 0x0700, 0x0f43, 0x0000 }, { 0x8700, 0x0f4d, 0x4000 }, { 0x8700, 0x0f49, 0x3000 }, { 0x8700, 0x0f46, 0x2000 }, { 0x0700, 0x0f45, 0x0000 }, { 0x0700, 0x0f47, 0x0000 }, { 0x8700, 0x0f4b, 0x2000 }, { 0x0700, 0x0f4a, 0x0000 }, { 0x0700, 0x0f4c, 0x0000 }, { 0x8700, 0x0f51, 0x3000 }, { 0x8700, 0x0f4f, 0x2000 }, { 0x0700, 0x0f4e, 0x0000 }, { 0x0700, 0x0f50, 0x0000 }, { 0x8700, 0x0f53, 0x2000 }, { 0x0700, 0x0f52, 0x0000 }, { 0x0700, 0x0f54, 0x0000 }, { 0x8700, 0x1013, 0x8000 }, { 0x8c00, 0x0fa0, 0x7000 }, { 0x8c00, 0x0f7b, 0x6000 }, { 0x8700, 0x0f65, 0x5000 }, { 0x8700, 0x0f5d, 0x4000 }, { 0x8700, 0x0f59, 0x3000 }, { 0x8700, 0x0f57, 0x2000 }, { 0x0700, 0x0f56, 0x0000 }, { 0x0700, 0x0f58, 0x0000 }, { 0x8700, 0x0f5b, 0x2000 }, { 0x0700, 0x0f5a, 0x0000 }, { 0x0700, 0x0f5c, 0x0000 }, { 0x8700, 0x0f61, 0x3000 }, { 0x8700, 0x0f5f, 0x2000 }, { 0x0700, 0x0f5e, 0x0000 }, { 0x0700, 0x0f60, 0x0000 }, { 0x8700, 0x0f63, 0x2000 }, { 0x0700, 0x0f62, 0x0000 }, { 0x0700, 0x0f64, 0x0000 }, { 0x8c00, 0x0f73, 0x4000 }, { 0x8700, 0x0f69, 0x3000 }, { 0x8700, 0x0f67, 0x2000 }, { 0x0700, 0x0f66, 0x0000 }, { 0x0700, 0x0f68, 0x0000 }, { 0x8c00, 0x0f71, 0x2000 }, { 0x0700, 0x0f6a, 0x0000 }, { 0x0c00, 0x0f72, 0x0000 }, { 0x8c00, 0x0f77, 0x3000 }, { 0x8c00, 0x0f75, 0x2000 }, { 0x0c00, 0x0f74, 0x0000 }, { 0x0c00, 0x0f76, 0x0000 }, { 0x8c00, 0x0f79, 0x2000 }, { 0x0c00, 0x0f78, 0x0000 }, { 0x0c00, 0x0f7a, 0x0000 }, { 0x8700, 0x0f8b, 0x5000 }, { 0x8c00, 0x0f83, 0x4000 }, { 0x8a00, 0x0f7f, 0x3000 }, { 0x8c00, 0x0f7d, 0x2000 }, { 0x0c00, 0x0f7c, 0x0000 }, { 0x0c00, 0x0f7e, 0x0000 }, { 0x8c00, 0x0f81, 0x2000 }, { 0x0c00, 0x0f80, 0x0000 }, { 0x0c00, 0x0f82, 0x0000 }, { 0x8c00, 0x0f87, 0x3000 }, { 0x9500, 0x0f85, 0x2000 }, { 0x0c00, 0x0f84, 0x0000 }, { 0x0c00, 0x0f86, 0x0000 }, { 0x8700, 0x0f89, 0x2000 }, { 0x0700, 0x0f88, 0x0000 }, { 0x0700, 0x0f8a, 0x0000 }, { 0x8c00, 0x0f97, 0x4000 }, { 0x8c00, 0x0f93, 0x3000 }, { 0x8c00, 0x0f91, 0x2000 }, { 0x0c00, 0x0f90, 0x0000 }, { 0x0c00, 0x0f92, 0x0000 }, { 0x8c00, 0x0f95, 0x2000 }, { 0x0c00, 0x0f94, 0x0000 }, { 0x0c00, 0x0f96, 0x0000 }, { 0x8c00, 0x0f9c, 0x3000 }, { 0x8c00, 0x0f9a, 0x2000 }, { 0x0c00, 0x0f99, 0x0000 }, { 0x0c00, 0x0f9b, 0x0000 }, { 0x8c00, 0x0f9e, 0x2000 }, { 0x0c00, 0x0f9d, 0x0000 }, { 0x0c00, 0x0f9f, 0x0000 }, { 0x9a00, 0x0fc1, 0x6000 }, { 0x8c00, 0x0fb0, 0x5000 }, { 0x8c00, 0x0fa8, 0x4000 }, { 0x8c00, 0x0fa4, 0x3000 }, { 0x8c00, 0x0fa2, 0x2000 }, { 0x0c00, 0x0fa1, 0x0000 }, { 0x0c00, 0x0fa3, 0x0000 }, { 0x8c00, 0x0fa6, 0x2000 }, { 0x0c00, 0x0fa5, 0x0000 }, { 0x0c00, 0x0fa7, 0x0000 }, { 0x8c00, 0x0fac, 0x3000 }, { 0x8c00, 0x0faa, 0x2000 }, { 0x0c00, 0x0fa9, 0x0000 }, { 0x0c00, 0x0fab, 0x0000 }, { 0x8c00, 0x0fae, 0x2000 }, { 0x0c00, 0x0fad, 0x0000 }, { 0x0c00, 0x0faf, 0x0000 }, { 0x8c00, 0x0fb8, 0x4000 }, { 0x8c00, 0x0fb4, 0x3000 }, { 0x8c00, 0x0fb2, 0x2000 }, { 0x0c00, 0x0fb1, 0x0000 }, { 0x0c00, 0x0fb3, 0x0000 }, { 0x8c00, 0x0fb6, 0x2000 }, { 0x0c00, 0x0fb5, 0x0000 }, { 0x0c00, 0x0fb7, 0x0000 }, { 0x8c00, 0x0fbc, 0x3000 }, { 0x8c00, 0x0fba, 0x2000 }, { 0x0c00, 0x0fb9, 0x0000 }, { 0x0c00, 0x0fbb, 0x0000 }, { 0x9a00, 0x0fbf, 0x2000 }, { 0x1a00, 0x0fbe, 0x0000 }, { 0x1a00, 0x0fc0, 0x0000 }, { 0x8700, 0x1003, 0x5000 }, { 0x9a00, 0x0fc9, 0x4000 }, { 0x9a00, 0x0fc5, 0x3000 }, { 0x9a00, 0x0fc3, 0x2000 }, { 0x1a00, 0x0fc2, 0x0000 }, { 0x1a00, 0x0fc4, 0x0000 }, { 0x9a00, 0x0fc7, 0x2000 }, { 0x0c00, 0x0fc6, 0x0000 }, { 0x1a00, 0x0fc8, 0x0000 }, { 0x9a00, 0x0fcf, 0x3000 }, { 0x9a00, 0x0fcb, 0x2000 }, { 0x1a00, 0x0fca, 0x0000 }, { 0x1a00, 0x0fcc, 0x0000 }, { 0x8700, 0x1001, 0x2000 }, { 0x0700, 0x1000, 0x0000 }, { 0x0700, 0x1002, 0x0000 }, { 0x8700, 0x100b, 0x4000 }, { 0x8700, 0x1007, 0x3000 }, { 0x8700, 0x1005, 0x2000 }, { 0x0700, 0x1004, 0x0000 }, { 0x0700, 0x1006, 0x0000 }, { 0x8700, 0x1009, 0x2000 }, { 0x0700, 0x1008, 0x0000 }, { 0x0700, 0x100a, 0x0000 }, { 0x8700, 0x100f, 0x3000 }, { 0x8700, 0x100d, 0x2000 }, { 0x0700, 0x100c, 0x0000 }, { 0x0700, 0x100e, 0x0000 }, { 0x8700, 0x1011, 0x2000 }, { 0x0700, 0x1010, 0x0000 }, { 0x0700, 0x1012, 0x0000 }, { 0x8900, 0x10a5, 0x7000 }, { 0x8c00, 0x1039, 0x6000 }, { 0x8700, 0x1024, 0x5000 }, { 0x8700, 0x101b, 0x4000 }, { 0x8700, 0x1017, 0x3000 }, { 0x8700, 0x1015, 0x2000 }, { 0x0700, 0x1014, 0x0000 }, { 0x0700, 0x1016, 0x0000 }, { 0x8700, 0x1019, 0x2000 }, { 0x0700, 0x1018, 0x0000 }, { 0x0700, 0x101a, 0x0000 }, { 0x8700, 0x101f, 0x3000 }, { 0x8700, 0x101d, 0x2000 }, { 0x0700, 0x101c, 0x0000 }, { 0x0700, 0x101e, 0x0000 }, { 0x8700, 0x1021, 0x2000 }, { 0x0700, 0x1020, 0x0000 }, { 0x0700, 0x1023, 0x0000 }, { 0x8c00, 0x102e, 0x4000 }, { 0x8700, 0x1029, 0x3000 }, { 0x8700, 0x1026, 0x2000 }, { 0x0700, 0x1025, 0x0000 }, { 0x0700, 0x1027, 0x0000 }, { 0x8a00, 0x102c, 0x2000 }, { 0x0700, 0x102a, 0x0000 }, { 0x0c00, 0x102d, 0x0000 }, { 0x8c00, 0x1032, 0x3000 }, { 0x8c00, 0x1030, 0x2000 }, { 0x0c00, 0x102f, 0x0000 }, { 0x0a00, 0x1031, 0x0000 }, { 0x8c00, 0x1037, 0x2000 }, { 0x0c00, 0x1036, 0x0000 }, { 0x0a00, 0x1038, 0x0000 }, { 0x9500, 0x104f, 0x5000 }, { 0x8d00, 0x1047, 0x4000 }, { 0x8d00, 0x1043, 0x3000 }, { 0x8d00, 0x1041, 0x2000 }, { 0x0d00, 0x1040, 0x0000 }, { 0x0d00, 0x1042, 0x0000 }, { 0x8d00, 0x1045, 0x2000 }, { 0x0d00, 0x1044, 0x0000 }, { 0x0d00, 0x1046, 0x0000 }, { 0x9500, 0x104b, 0x3000 }, { 0x8d00, 0x1049, 0x2000 }, { 0x0d00, 0x1048, 0x0000 }, { 0x1500, 0x104a, 0x0000 }, { 0x9500, 0x104d, 0x2000 }, { 0x1500, 0x104c, 0x0000 }, { 0x1500, 0x104e, 0x0000 }, { 0x8a00, 0x1057, 0x4000 }, { 0x8700, 0x1053, 0x3000 }, { 0x8700, 0x1051, 0x2000 }, { 0x0700, 0x1050, 0x0000 }, { 0x0700, 0x1052, 0x0000 }, { 0x8700, 0x1055, 0x2000 }, { 0x0700, 0x1054, 0x0000 }, { 0x0a00, 0x1056, 0x0000 }, { 0x8900, 0x10a1, 0x3000 }, { 0x8c00, 0x1059, 0x2000 }, { 0x0c00, 0x1058, 0x0000 }, { 0x0900, 0x10a0, 0x0000 }, { 0x8900, 0x10a3, 0x2000 }, { 0x0900, 0x10a2, 0x0000 }, { 0x0900, 0x10a4, 0x0000 }, { 0x8900, 0x10c5, 0x6000 }, { 0x8900, 0x10b5, 0x5000 }, { 0x8900, 0x10ad, 0x4000 }, { 0x8900, 0x10a9, 0x3000 }, { 0x8900, 0x10a7, 0x2000 }, { 0x0900, 0x10a6, 0x0000 }, { 0x0900, 0x10a8, 0x0000 }, { 0x8900, 0x10ab, 0x2000 }, { 0x0900, 0x10aa, 0x0000 }, { 0x0900, 0x10ac, 0x0000 }, { 0x8900, 0x10b1, 0x3000 }, { 0x8900, 0x10af, 0x2000 }, { 0x0900, 0x10ae, 0x0000 }, { 0x0900, 0x10b0, 0x0000 }, { 0x8900, 0x10b3, 0x2000 }, { 0x0900, 0x10b2, 0x0000 }, { 0x0900, 0x10b4, 0x0000 }, { 0x8900, 0x10bd, 0x4000 }, { 0x8900, 0x10b9, 0x3000 }, { 0x8900, 0x10b7, 0x2000 }, { 0x0900, 0x10b6, 0x0000 }, { 0x0900, 0x10b8, 0x0000 }, { 0x8900, 0x10bb, 0x2000 }, { 0x0900, 0x10ba, 0x0000 }, { 0x0900, 0x10bc, 0x0000 }, { 0x8900, 0x10c1, 0x3000 }, { 0x8900, 0x10bf, 0x2000 }, { 0x0900, 0x10be, 0x0000 }, { 0x0900, 0x10c0, 0x0000 }, { 0x8900, 0x10c3, 0x2000 }, { 0x0900, 0x10c2, 0x0000 }, { 0x0900, 0x10c4, 0x0000 }, { 0x8700, 0x10df, 0x5000 }, { 0x8700, 0x10d7, 0x4000 }, { 0x8700, 0x10d3, 0x3000 }, { 0x8700, 0x10d1, 0x2000 }, { 0x0700, 0x10d0, 0x0000 }, { 0x0700, 0x10d2, 0x0000 }, { 0x8700, 0x10d5, 0x2000 }, { 0x0700, 0x10d4, 0x0000 }, { 0x0700, 0x10d6, 0x0000 }, { 0x8700, 0x10db, 0x3000 }, { 0x8700, 0x10d9, 0x2000 }, { 0x0700, 0x10d8, 0x0000 }, { 0x0700, 0x10da, 0x0000 }, { 0x8700, 0x10dd, 0x2000 }, { 0x0700, 0x10dc, 0x0000 }, { 0x0700, 0x10de, 0x0000 }, { 0x8700, 0x10e7, 0x4000 }, { 0x8700, 0x10e3, 0x3000 }, { 0x8700, 0x10e1, 0x2000 }, { 0x0700, 0x10e0, 0x0000 }, { 0x0700, 0x10e2, 0x0000 }, { 0x8700, 0x10e5, 0x2000 }, { 0x0700, 0x10e4, 0x0000 }, { 0x0700, 0x10e6, 0x0000 }, { 0x8700, 0x10eb, 0x3000 }, { 0x8700, 0x10e9, 0x2000 }, { 0x0700, 0x10e8, 0x0000 }, { 0x0700, 0x10ea, 0x0000 }, { 0x8700, 0x10ed, 0x2000 }, { 0x0700, 0x10ec, 0x0000 }, { 0x0700, 0x10ee, 0x0000 }, { 0x8700, 0x1322, 0xa000 }, { 0x8700, 0x1205, 0x9000 }, { 0x8700, 0x117a, 0x8000 }, { 0x8700, 0x1135, 0x7000 }, { 0x8700, 0x1115, 0x6000 }, { 0x8700, 0x1105, 0x5000 }, { 0x8700, 0x10f7, 0x4000 }, { 0x8700, 0x10f3, 0x3000 }, { 0x8700, 0x10f1, 0x2000 }, { 0x0700, 0x10f0, 0x0000 }, { 0x0700, 0x10f2, 0x0000 }, { 0x8700, 0x10f5, 0x2000 }, { 0x0700, 0x10f4, 0x0000 }, { 0x0700, 0x10f6, 0x0000 }, { 0x8700, 0x1101, 0x3000 }, { 0x9500, 0x10fb, 0x2000 }, { 0x0700, 0x10f8, 0x0000 }, { 0x0700, 0x1100, 0x0000 }, { 0x8700, 0x1103, 0x2000 }, { 0x0700, 0x1102, 0x0000 }, { 0x0700, 0x1104, 0x0000 }, { 0x8700, 0x110d, 0x4000 }, { 0x8700, 0x1109, 0x3000 }, { 0x8700, 0x1107, 0x2000 }, { 0x0700, 0x1106, 0x0000 }, { 0x0700, 0x1108, 0x0000 }, { 0x8700, 0x110b, 0x2000 }, { 0x0700, 0x110a, 0x0000 }, { 0x0700, 0x110c, 0x0000 }, { 0x8700, 0x1111, 0x3000 }, { 0x8700, 0x110f, 0x2000 }, { 0x0700, 0x110e, 0x0000 }, { 0x0700, 0x1110, 0x0000 }, { 0x8700, 0x1113, 0x2000 }, { 0x0700, 0x1112, 0x0000 }, { 0x0700, 0x1114, 0x0000 }, { 0x8700, 0x1125, 0x5000 }, { 0x8700, 0x111d, 0x4000 }, { 0x8700, 0x1119, 0x3000 }, { 0x8700, 0x1117, 0x2000 }, { 0x0700, 0x1116, 0x0000 }, { 0x0700, 0x1118, 0x0000 }, { 0x8700, 0x111b, 0x2000 }, { 0x0700, 0x111a, 0x0000 }, { 0x0700, 0x111c, 0x0000 }, { 0x8700, 0x1121, 0x3000 }, { 0x8700, 0x111f, 0x2000 }, { 0x0700, 0x111e, 0x0000 }, { 0x0700, 0x1120, 0x0000 }, { 0x8700, 0x1123, 0x2000 }, { 0x0700, 0x1122, 0x0000 }, { 0x0700, 0x1124, 0x0000 }, { 0x8700, 0x112d, 0x4000 }, { 0x8700, 0x1129, 0x3000 }, { 0x8700, 0x1127, 0x2000 }, { 0x0700, 0x1126, 0x0000 }, { 0x0700, 0x1128, 0x0000 }, { 0x8700, 0x112b, 0x2000 }, { 0x0700, 0x112a, 0x0000 }, { 0x0700, 0x112c, 0x0000 }, { 0x8700, 0x1131, 0x3000 }, { 0x8700, 0x112f, 0x2000 }, { 0x0700, 0x112e, 0x0000 }, { 0x0700, 0x1130, 0x0000 }, { 0x8700, 0x1133, 0x2000 }, { 0x0700, 0x1132, 0x0000 }, { 0x0700, 0x1134, 0x0000 }, { 0x8700, 0x1155, 0x6000 }, { 0x8700, 0x1145, 0x5000 }, { 0x8700, 0x113d, 0x4000 }, { 0x8700, 0x1139, 0x3000 }, { 0x8700, 0x1137, 0x2000 }, { 0x0700, 0x1136, 0x0000 }, { 0x0700, 0x1138, 0x0000 }, { 0x8700, 0x113b, 0x2000 }, { 0x0700, 0x113a, 0x0000 }, { 0x0700, 0x113c, 0x0000 }, { 0x8700, 0x1141, 0x3000 }, { 0x8700, 0x113f, 0x2000 }, { 0x0700, 0x113e, 0x0000 }, { 0x0700, 0x1140, 0x0000 }, { 0x8700, 0x1143, 0x2000 }, { 0x0700, 0x1142, 0x0000 }, { 0x0700, 0x1144, 0x0000 }, { 0x8700, 0x114d, 0x4000 }, { 0x8700, 0x1149, 0x3000 }, { 0x8700, 0x1147, 0x2000 }, { 0x0700, 0x1146, 0x0000 }, { 0x0700, 0x1148, 0x0000 }, { 0x8700, 0x114b, 0x2000 }, { 0x0700, 0x114a, 0x0000 }, { 0x0700, 0x114c, 0x0000 }, { 0x8700, 0x1151, 0x3000 }, { 0x8700, 0x114f, 0x2000 }, { 0x0700, 0x114e, 0x0000 }, { 0x0700, 0x1150, 0x0000 }, { 0x8700, 0x1153, 0x2000 }, { 0x0700, 0x1152, 0x0000 }, { 0x0700, 0x1154, 0x0000 }, { 0x8700, 0x116a, 0x5000 }, { 0x8700, 0x1162, 0x4000 }, { 0x8700, 0x1159, 0x3000 }, { 0x8700, 0x1157, 0x2000 }, { 0x0700, 0x1156, 0x0000 }, { 0x0700, 0x1158, 0x0000 }, { 0x8700, 0x1160, 0x2000 }, { 0x0700, 0x115f, 0x0000 }, { 0x0700, 0x1161, 0x0000 }, { 0x8700, 0x1166, 0x3000 }, { 0x8700, 0x1164, 0x2000 }, { 0x0700, 0x1163, 0x0000 }, { 0x0700, 0x1165, 0x0000 }, { 0x8700, 0x1168, 0x2000 }, { 0x0700, 0x1167, 0x0000 }, { 0x0700, 0x1169, 0x0000 }, { 0x8700, 0x1172, 0x4000 }, { 0x8700, 0x116e, 0x3000 }, { 0x8700, 0x116c, 0x2000 }, { 0x0700, 0x116b, 0x0000 }, { 0x0700, 0x116d, 0x0000 }, { 0x8700, 0x1170, 0x2000 }, { 0x0700, 0x116f, 0x0000 }, { 0x0700, 0x1171, 0x0000 }, { 0x8700, 0x1176, 0x3000 }, { 0x8700, 0x1174, 0x2000 }, { 0x0700, 0x1173, 0x0000 }, { 0x0700, 0x1175, 0x0000 }, { 0x8700, 0x1178, 0x2000 }, { 0x0700, 0x1177, 0x0000 }, { 0x0700, 0x1179, 0x0000 }, { 0x8700, 0x11bf, 0x7000 }, { 0x8700, 0x119a, 0x6000 }, { 0x8700, 0x118a, 0x5000 }, { 0x8700, 0x1182, 0x4000 }, { 0x8700, 0x117e, 0x3000 }, { 0x8700, 0x117c, 0x2000 }, { 0x0700, 0x117b, 0x0000 }, { 0x0700, 0x117d, 0x0000 }, { 0x8700, 0x1180, 0x2000 }, { 0x0700, 0x117f, 0x0000 }, { 0x0700, 0x1181, 0x0000 }, { 0x8700, 0x1186, 0x3000 }, { 0x8700, 0x1184, 0x2000 }, { 0x0700, 0x1183, 0x0000 }, { 0x0700, 0x1185, 0x0000 }, { 0x8700, 0x1188, 0x2000 }, { 0x0700, 0x1187, 0x0000 }, { 0x0700, 0x1189, 0x0000 }, { 0x8700, 0x1192, 0x4000 }, { 0x8700, 0x118e, 0x3000 }, { 0x8700, 0x118c, 0x2000 }, { 0x0700, 0x118b, 0x0000 }, { 0x0700, 0x118d, 0x0000 }, { 0x8700, 0x1190, 0x2000 }, { 0x0700, 0x118f, 0x0000 }, { 0x0700, 0x1191, 0x0000 }, { 0x8700, 0x1196, 0x3000 }, { 0x8700, 0x1194, 0x2000 }, { 0x0700, 0x1193, 0x0000 }, { 0x0700, 0x1195, 0x0000 }, { 0x8700, 0x1198, 0x2000 }, { 0x0700, 0x1197, 0x0000 }, { 0x0700, 0x1199, 0x0000 }, { 0x8700, 0x11af, 0x5000 }, { 0x8700, 0x11a2, 0x4000 }, { 0x8700, 0x119e, 0x3000 }, { 0x8700, 0x119c, 0x2000 }, { 0x0700, 0x119b, 0x0000 }, { 0x0700, 0x119d, 0x0000 }, { 0x8700, 0x11a0, 0x2000 }, { 0x0700, 0x119f, 0x0000 }, { 0x0700, 0x11a1, 0x0000 }, { 0x8700, 0x11ab, 0x3000 }, { 0x8700, 0x11a9, 0x2000 }, { 0x0700, 0x11a8, 0x0000 }, { 0x0700, 0x11aa, 0x0000 }, { 0x8700, 0x11ad, 0x2000 }, { 0x0700, 0x11ac, 0x0000 }, { 0x0700, 0x11ae, 0x0000 }, { 0x8700, 0x11b7, 0x4000 }, { 0x8700, 0x11b3, 0x3000 }, { 0x8700, 0x11b1, 0x2000 }, { 0x0700, 0x11b0, 0x0000 }, { 0x0700, 0x11b2, 0x0000 }, { 0x8700, 0x11b5, 0x2000 }, { 0x0700, 0x11b4, 0x0000 }, { 0x0700, 0x11b6, 0x0000 }, { 0x8700, 0x11bb, 0x3000 }, { 0x8700, 0x11b9, 0x2000 }, { 0x0700, 0x11b8, 0x0000 }, { 0x0700, 0x11ba, 0x0000 }, { 0x8700, 0x11bd, 0x2000 }, { 0x0700, 0x11bc, 0x0000 }, { 0x0700, 0x11be, 0x0000 }, { 0x8700, 0x11df, 0x6000 }, { 0x8700, 0x11cf, 0x5000 }, { 0x8700, 0x11c7, 0x4000 }, { 0x8700, 0x11c3, 0x3000 }, { 0x8700, 0x11c1, 0x2000 }, { 0x0700, 0x11c0, 0x0000 }, { 0x0700, 0x11c2, 0x0000 }, { 0x8700, 0x11c5, 0x2000 }, { 0x0700, 0x11c4, 0x0000 }, { 0x0700, 0x11c6, 0x0000 }, { 0x8700, 0x11cb, 0x3000 }, { 0x8700, 0x11c9, 0x2000 }, { 0x0700, 0x11c8, 0x0000 }, { 0x0700, 0x11ca, 0x0000 }, { 0x8700, 0x11cd, 0x2000 }, { 0x0700, 0x11cc, 0x0000 }, { 0x0700, 0x11ce, 0x0000 }, { 0x8700, 0x11d7, 0x4000 }, { 0x8700, 0x11d3, 0x3000 }, { 0x8700, 0x11d1, 0x2000 }, { 0x0700, 0x11d0, 0x0000 }, { 0x0700, 0x11d2, 0x0000 }, { 0x8700, 0x11d5, 0x2000 }, { 0x0700, 0x11d4, 0x0000 }, { 0x0700, 0x11d6, 0x0000 }, { 0x8700, 0x11db, 0x3000 }, { 0x8700, 0x11d9, 0x2000 }, { 0x0700, 0x11d8, 0x0000 }, { 0x0700, 0x11da, 0x0000 }, { 0x8700, 0x11dd, 0x2000 }, { 0x0700, 0x11dc, 0x0000 }, { 0x0700, 0x11de, 0x0000 }, { 0x8700, 0x11ef, 0x5000 }, { 0x8700, 0x11e7, 0x4000 }, { 0x8700, 0x11e3, 0x3000 }, { 0x8700, 0x11e1, 0x2000 }, { 0x0700, 0x11e0, 0x0000 }, { 0x0700, 0x11e2, 0x0000 }, { 0x8700, 0x11e5, 0x2000 }, { 0x0700, 0x11e4, 0x0000 }, { 0x0700, 0x11e6, 0x0000 }, { 0x8700, 0x11eb, 0x3000 }, { 0x8700, 0x11e9, 0x2000 }, { 0x0700, 0x11e8, 0x0000 }, { 0x0700, 0x11ea, 0x0000 }, { 0x8700, 0x11ed, 0x2000 }, { 0x0700, 0x11ec, 0x0000 }, { 0x0700, 0x11ee, 0x0000 }, { 0x8700, 0x11f7, 0x4000 }, { 0x8700, 0x11f3, 0x3000 }, { 0x8700, 0x11f1, 0x2000 }, { 0x0700, 0x11f0, 0x0000 }, { 0x0700, 0x11f2, 0x0000 }, { 0x8700, 0x11f5, 0x2000 }, { 0x0700, 0x11f4, 0x0000 }, { 0x0700, 0x11f6, 0x0000 }, { 0x8700, 0x1201, 0x3000 }, { 0x8700, 0x11f9, 0x2000 }, { 0x0700, 0x11f8, 0x0000 }, { 0x0700, 0x1200, 0x0000 }, { 0x8700, 0x1203, 0x2000 }, { 0x0700, 0x1202, 0x0000 }, { 0x0700, 0x1204, 0x0000 }, { 0x8700, 0x1292, 0x8000 }, { 0x8700, 0x1246, 0x7000 }, { 0x8700, 0x1226, 0x6000 }, { 0x8700, 0x1216, 0x5000 }, { 0x8700, 0x120e, 0x4000 }, { 0x8700, 0x120a, 0x3000 }, { 0x8700, 0x1208, 0x2000 }, { 0x0700, 0x1206, 0x0000 }, { 0x0700, 0x1209, 0x0000 }, { 0x8700, 0x120c, 0x2000 }, { 0x0700, 0x120b, 0x0000 }, { 0x0700, 0x120d, 0x0000 }, { 0x8700, 0x1212, 0x3000 }, { 0x8700, 0x1210, 0x2000 }, { 0x0700, 0x120f, 0x0000 }, { 0x0700, 0x1211, 0x0000 }, { 0x8700, 0x1214, 0x2000 }, { 0x0700, 0x1213, 0x0000 }, { 0x0700, 0x1215, 0x0000 }, { 0x8700, 0x121e, 0x4000 }, { 0x8700, 0x121a, 0x3000 }, { 0x8700, 0x1218, 0x2000 }, { 0x0700, 0x1217, 0x0000 }, { 0x0700, 0x1219, 0x0000 }, { 0x8700, 0x121c, 0x2000 }, { 0x0700, 0x121b, 0x0000 }, { 0x0700, 0x121d, 0x0000 }, { 0x8700, 0x1222, 0x3000 }, { 0x8700, 0x1220, 0x2000 }, { 0x0700, 0x121f, 0x0000 }, { 0x0700, 0x1221, 0x0000 }, { 0x8700, 0x1224, 0x2000 }, { 0x0700, 0x1223, 0x0000 }, { 0x0700, 0x1225, 0x0000 }, { 0x8700, 0x1236, 0x5000 }, { 0x8700, 0x122e, 0x4000 }, { 0x8700, 0x122a, 0x3000 }, { 0x8700, 0x1228, 0x2000 }, { 0x0700, 0x1227, 0x0000 }, { 0x0700, 0x1229, 0x0000 }, { 0x8700, 0x122c, 0x2000 }, { 0x0700, 0x122b, 0x0000 }, { 0x0700, 0x122d, 0x0000 }, { 0x8700, 0x1232, 0x3000 }, { 0x8700, 0x1230, 0x2000 }, { 0x0700, 0x122f, 0x0000 }, { 0x0700, 0x1231, 0x0000 }, { 0x8700, 0x1234, 0x2000 }, { 0x0700, 0x1233, 0x0000 }, { 0x0700, 0x1235, 0x0000 }, { 0x8700, 0x123e, 0x4000 }, { 0x8700, 0x123a, 0x3000 }, { 0x8700, 0x1238, 0x2000 }, { 0x0700, 0x1237, 0x0000 }, { 0x0700, 0x1239, 0x0000 }, { 0x8700, 0x123c, 0x2000 }, { 0x0700, 0x123b, 0x0000 }, { 0x0700, 0x123d, 0x0000 }, { 0x8700, 0x1242, 0x3000 }, { 0x8700, 0x1240, 0x2000 }, { 0x0700, 0x123f, 0x0000 }, { 0x0700, 0x1241, 0x0000 }, { 0x8700, 0x1244, 0x2000 }, { 0x0700, 0x1243, 0x0000 }, { 0x0700, 0x1245, 0x0000 }, { 0x8700, 0x126e, 0x6000 }, { 0x8700, 0x125c, 0x5000 }, { 0x8700, 0x1252, 0x4000 }, { 0x8700, 0x124c, 0x3000 }, { 0x8700, 0x124a, 0x2000 }, { 0x0700, 0x1248, 0x0000 }, { 0x0700, 0x124b, 0x0000 }, { 0x8700, 0x1250, 0x2000 }, { 0x0700, 0x124d, 0x0000 }, { 0x0700, 0x1251, 0x0000 }, { 0x8700, 0x1256, 0x3000 }, { 0x8700, 0x1254, 0x2000 }, { 0x0700, 0x1253, 0x0000 }, { 0x0700, 0x1255, 0x0000 }, { 0x8700, 0x125a, 0x2000 }, { 0x0700, 0x1258, 0x0000 }, { 0x0700, 0x125b, 0x0000 }, { 0x8700, 0x1266, 0x4000 }, { 0x8700, 0x1262, 0x3000 }, { 0x8700, 0x1260, 0x2000 }, { 0x0700, 0x125d, 0x0000 }, { 0x0700, 0x1261, 0x0000 }, { 0x8700, 0x1264, 0x2000 }, { 0x0700, 0x1263, 0x0000 }, { 0x0700, 0x1265, 0x0000 }, { 0x8700, 0x126a, 0x3000 }, { 0x8700, 0x1268, 0x2000 }, { 0x0700, 0x1267, 0x0000 }, { 0x0700, 0x1269, 0x0000 }, { 0x8700, 0x126c, 0x2000 }, { 0x0700, 0x126b, 0x0000 }, { 0x0700, 0x126d, 0x0000 }, { 0x8700, 0x127e, 0x5000 }, { 0x8700, 0x1276, 0x4000 }, { 0x8700, 0x1272, 0x3000 }, { 0x8700, 0x1270, 0x2000 }, { 0x0700, 0x126f, 0x0000 }, { 0x0700, 0x1271, 0x0000 }, { 0x8700, 0x1274, 0x2000 }, { 0x0700, 0x1273, 0x0000 }, { 0x0700, 0x1275, 0x0000 }, { 0x8700, 0x127a, 0x3000 }, { 0x8700, 0x1278, 0x2000 }, { 0x0700, 0x1277, 0x0000 }, { 0x0700, 0x1279, 0x0000 }, { 0x8700, 0x127c, 0x2000 }, { 0x0700, 0x127b, 0x0000 }, { 0x0700, 0x127d, 0x0000 }, { 0x8700, 0x1286, 0x4000 }, { 0x8700, 0x1282, 0x3000 }, { 0x8700, 0x1280, 0x2000 }, { 0x0700, 0x127f, 0x0000 }, { 0x0700, 0x1281, 0x0000 }, { 0x8700, 0x1284, 0x2000 }, { 0x0700, 0x1283, 0x0000 }, { 0x0700, 0x1285, 0x0000 }, { 0x8700, 0x128c, 0x3000 }, { 0x8700, 0x128a, 0x2000 }, { 0x0700, 0x1288, 0x0000 }, { 0x0700, 0x128b, 0x0000 }, { 0x8700, 0x1290, 0x2000 }, { 0x0700, 0x128d, 0x0000 }, { 0x0700, 0x1291, 0x0000 }, { 0x8700, 0x12dc, 0x7000 }, { 0x8700, 0x12b4, 0x6000 }, { 0x8700, 0x12a2, 0x5000 }, { 0x8700, 0x129a, 0x4000 }, { 0x8700, 0x1296, 0x3000 }, { 0x8700, 0x1294, 0x2000 }, { 0x0700, 0x1293, 0x0000 }, { 0x0700, 0x1295, 0x0000 }, { 0x8700, 0x1298, 0x2000 }, { 0x0700, 0x1297, 0x0000 }, { 0x0700, 0x1299, 0x0000 }, { 0x8700, 0x129e, 0x3000 }, { 0x8700, 0x129c, 0x2000 }, { 0x0700, 0x129b, 0x0000 }, { 0x0700, 0x129d, 0x0000 }, { 0x8700, 0x12a0, 0x2000 }, { 0x0700, 0x129f, 0x0000 }, { 0x0700, 0x12a1, 0x0000 }, { 0x8700, 0x12aa, 0x4000 }, { 0x8700, 0x12a6, 0x3000 }, { 0x8700, 0x12a4, 0x2000 }, { 0x0700, 0x12a3, 0x0000 }, { 0x0700, 0x12a5, 0x0000 }, { 0x8700, 0x12a8, 0x2000 }, { 0x0700, 0x12a7, 0x0000 }, { 0x0700, 0x12a9, 0x0000 }, { 0x8700, 0x12ae, 0x3000 }, { 0x8700, 0x12ac, 0x2000 }, { 0x0700, 0x12ab, 0x0000 }, { 0x0700, 0x12ad, 0x0000 }, { 0x8700, 0x12b2, 0x2000 }, { 0x0700, 0x12b0, 0x0000 }, { 0x0700, 0x12b3, 0x0000 }, { 0x8700, 0x12ca, 0x5000 }, { 0x8700, 0x12be, 0x4000 }, { 0x8700, 0x12ba, 0x3000 }, { 0x8700, 0x12b8, 0x2000 }, { 0x0700, 0x12b5, 0x0000 }, { 0x0700, 0x12b9, 0x0000 }, { 0x8700, 0x12bc, 0x2000 }, { 0x0700, 0x12bb, 0x0000 }, { 0x0700, 0x12bd, 0x0000 }, { 0x8700, 0x12c4, 0x3000 }, { 0x8700, 0x12c2, 0x2000 }, { 0x0700, 0x12c0, 0x0000 }, { 0x0700, 0x12c3, 0x0000 }, { 0x8700, 0x12c8, 0x2000 }, { 0x0700, 0x12c5, 0x0000 }, { 0x0700, 0x12c9, 0x0000 }, { 0x8700, 0x12d3, 0x4000 }, { 0x8700, 0x12ce, 0x3000 }, { 0x8700, 0x12cc, 0x2000 }, { 0x0700, 0x12cb, 0x0000 }, { 0x0700, 0x12cd, 0x0000 }, { 0x8700, 0x12d1, 0x2000 }, { 0x0700, 0x12d0, 0x0000 }, { 0x0700, 0x12d2, 0x0000 }, { 0x8700, 0x12d8, 0x3000 }, { 0x8700, 0x12d5, 0x2000 }, { 0x0700, 0x12d4, 0x0000 }, { 0x0700, 0x12d6, 0x0000 }, { 0x8700, 0x12da, 0x2000 }, { 0x0700, 0x12d9, 0x0000 }, { 0x0700, 0x12db, 0x0000 }, { 0x8700, 0x12fd, 0x6000 }, { 0x8700, 0x12ec, 0x5000 }, { 0x8700, 0x12e4, 0x4000 }, { 0x8700, 0x12e0, 0x3000 }, { 0x8700, 0x12de, 0x2000 }, { 0x0700, 0x12dd, 0x0000 }, { 0x0700, 0x12df, 0x0000 }, { 0x8700, 0x12e2, 0x2000 }, { 0x0700, 0x12e1, 0x0000 }, { 0x0700, 0x12e3, 0x0000 }, { 0x8700, 0x12e8, 0x3000 }, { 0x8700, 0x12e6, 0x2000 }, { 0x0700, 0x12e5, 0x0000 }, { 0x0700, 0x12e7, 0x0000 }, { 0x8700, 0x12ea, 0x2000 }, { 0x0700, 0x12e9, 0x0000 }, { 0x0700, 0x12eb, 0x0000 }, { 0x8700, 0x12f5, 0x4000 }, { 0x8700, 0x12f1, 0x3000 }, { 0x8700, 0x12ee, 0x2000 }, { 0x0700, 0x12ed, 0x0000 }, { 0x0700, 0x12f0, 0x0000 }, { 0x8700, 0x12f3, 0x2000 }, { 0x0700, 0x12f2, 0x0000 }, { 0x0700, 0x12f4, 0x0000 }, { 0x8700, 0x12f9, 0x3000 }, { 0x8700, 0x12f7, 0x2000 }, { 0x0700, 0x12f6, 0x0000 }, { 0x0700, 0x12f8, 0x0000 }, { 0x8700, 0x12fb, 0x2000 }, { 0x0700, 0x12fa, 0x0000 }, { 0x0700, 0x12fc, 0x0000 }, { 0x8700, 0x130d, 0x5000 }, { 0x8700, 0x1305, 0x4000 }, { 0x8700, 0x1301, 0x3000 }, { 0x8700, 0x12ff, 0x2000 }, { 0x0700, 0x12fe, 0x0000 }, { 0x0700, 0x1300, 0x0000 }, { 0x8700, 0x1303, 0x2000 }, { 0x0700, 0x1302, 0x0000 }, { 0x0700, 0x1304, 0x0000 }, { 0x8700, 0x1309, 0x3000 }, { 0x8700, 0x1307, 0x2000 }, { 0x0700, 0x1306, 0x0000 }, { 0x0700, 0x1308, 0x0000 }, { 0x8700, 0x130b, 0x2000 }, { 0x0700, 0x130a, 0x0000 }, { 0x0700, 0x130c, 0x0000 }, { 0x8700, 0x1319, 0x4000 }, { 0x8700, 0x1313, 0x3000 }, { 0x8700, 0x1310, 0x2000 }, { 0x0700, 0x130e, 0x0000 }, { 0x0700, 0x1312, 0x0000 }, { 0x8700, 0x1315, 0x2000 }, { 0x0700, 0x1314, 0x0000 }, { 0x0700, 0x1318, 0x0000 }, { 0x8700, 0x131d, 0x3000 }, { 0x8700, 0x131b, 0x2000 }, { 0x0700, 0x131a, 0x0000 }, { 0x0700, 0x131c, 0x0000 }, { 0x8700, 0x1320, 0x2000 }, { 0x0700, 0x131e, 0x0000 }, { 0x0700, 0x1321, 0x0000 }, { 0x8700, 0x1458, 0x9000 }, { 0x8700, 0x13cc, 0x8000 }, { 0x8d00, 0x1369, 0x7000 }, { 0x8700, 0x1342, 0x6000 }, { 0x8700, 0x1332, 0x5000 }, { 0x8700, 0x132a, 0x4000 }, { 0x8700, 0x1326, 0x3000 }, { 0x8700, 0x1324, 0x2000 }, { 0x0700, 0x1323, 0x0000 }, { 0x0700, 0x1325, 0x0000 }, { 0x8700, 0x1328, 0x2000 }, { 0x0700, 0x1327, 0x0000 }, { 0x0700, 0x1329, 0x0000 }, { 0x8700, 0x132e, 0x3000 }, { 0x8700, 0x132c, 0x2000 }, { 0x0700, 0x132b, 0x0000 }, { 0x0700, 0x132d, 0x0000 }, { 0x8700, 0x1330, 0x2000 }, { 0x0700, 0x132f, 0x0000 }, { 0x0700, 0x1331, 0x0000 }, { 0x8700, 0x133a, 0x4000 }, { 0x8700, 0x1336, 0x3000 }, { 0x8700, 0x1334, 0x2000 }, { 0x0700, 0x1333, 0x0000 }, { 0x0700, 0x1335, 0x0000 }, { 0x8700, 0x1338, 0x2000 }, { 0x0700, 0x1337, 0x0000 }, { 0x0700, 0x1339, 0x0000 }, { 0x8700, 0x133e, 0x3000 }, { 0x8700, 0x133c, 0x2000 }, { 0x0700, 0x133b, 0x0000 }, { 0x0700, 0x133d, 0x0000 }, { 0x8700, 0x1340, 0x2000 }, { 0x0700, 0x133f, 0x0000 }, { 0x0700, 0x1341, 0x0000 }, { 0x8700, 0x1353, 0x5000 }, { 0x8700, 0x134b, 0x4000 }, { 0x8700, 0x1346, 0x3000 }, { 0x8700, 0x1344, 0x2000 }, { 0x0700, 0x1343, 0x0000 }, { 0x0700, 0x1345, 0x0000 }, { 0x8700, 0x1349, 0x2000 }, { 0x0700, 0x1348, 0x0000 }, { 0x0700, 0x134a, 0x0000 }, { 0x8700, 0x134f, 0x3000 }, { 0x8700, 0x134d, 0x2000 }, { 0x0700, 0x134c, 0x0000 }, { 0x0700, 0x134e, 0x0000 }, { 0x8700, 0x1351, 0x2000 }, { 0x0700, 0x1350, 0x0000 }, { 0x0700, 0x1352, 0x0000 }, { 0x9500, 0x1361, 0x4000 }, { 0x8700, 0x1357, 0x3000 }, { 0x8700, 0x1355, 0x2000 }, { 0x0700, 0x1354, 0x0000 }, { 0x0700, 0x1356, 0x0000 }, { 0x8700, 0x1359, 0x2000 }, { 0x0700, 0x1358, 0x0000 }, { 0x0700, 0x135a, 0x0000 }, { 0x9500, 0x1365, 0x3000 }, { 0x9500, 0x1363, 0x2000 }, { 0x1500, 0x1362, 0x0000 }, { 0x1500, 0x1364, 0x0000 }, { 0x9500, 0x1367, 0x2000 }, { 0x1500, 0x1366, 0x0000 }, { 0x1500, 0x1368, 0x0000 }, { 0x8700, 0x13ac, 0x6000 }, { 0x8f00, 0x1379, 0x5000 }, { 0x8d00, 0x1371, 0x4000 }, { 0x8d00, 0x136d, 0x3000 }, { 0x8d00, 0x136b, 0x2000 }, { 0x0d00, 0x136a, 0x0000 }, { 0x0d00, 0x136c, 0x0000 }, { 0x8d00, 0x136f, 0x2000 }, { 0x0d00, 0x136e, 0x0000 }, { 0x0d00, 0x1370, 0x0000 }, { 0x8f00, 0x1375, 0x3000 }, { 0x8f00, 0x1373, 0x2000 }, { 0x0f00, 0x1372, 0x0000 }, { 0x0f00, 0x1374, 0x0000 }, { 0x8f00, 0x1377, 0x2000 }, { 0x0f00, 0x1376, 0x0000 }, { 0x0f00, 0x1378, 0x0000 }, { 0x8700, 0x13a4, 0x4000 }, { 0x8700, 0x13a0, 0x3000 }, { 0x8f00, 0x137b, 0x2000 }, { 0x0f00, 0x137a, 0x0000 }, { 0x0f00, 0x137c, 0x0000 }, { 0x8700, 0x13a2, 0x2000 }, { 0x0700, 0x13a1, 0x0000 }, { 0x0700, 0x13a3, 0x0000 }, { 0x8700, 0x13a8, 0x3000 }, { 0x8700, 0x13a6, 0x2000 }, { 0x0700, 0x13a5, 0x0000 }, { 0x0700, 0x13a7, 0x0000 }, { 0x8700, 0x13aa, 0x2000 }, { 0x0700, 0x13a9, 0x0000 }, { 0x0700, 0x13ab, 0x0000 }, { 0x8700, 0x13bc, 0x5000 }, { 0x8700, 0x13b4, 0x4000 }, { 0x8700, 0x13b0, 0x3000 }, { 0x8700, 0x13ae, 0x2000 }, { 0x0700, 0x13ad, 0x0000 }, { 0x0700, 0x13af, 0x0000 }, { 0x8700, 0x13b2, 0x2000 }, { 0x0700, 0x13b1, 0x0000 }, { 0x0700, 0x13b3, 0x0000 }, { 0x8700, 0x13b8, 0x3000 }, { 0x8700, 0x13b6, 0x2000 }, { 0x0700, 0x13b5, 0x0000 }, { 0x0700, 0x13b7, 0x0000 }, { 0x8700, 0x13ba, 0x2000 }, { 0x0700, 0x13b9, 0x0000 }, { 0x0700, 0x13bb, 0x0000 }, { 0x8700, 0x13c4, 0x4000 }, { 0x8700, 0x13c0, 0x3000 }, { 0x8700, 0x13be, 0x2000 }, { 0x0700, 0x13bd, 0x0000 }, { 0x0700, 0x13bf, 0x0000 }, { 0x8700, 0x13c2, 0x2000 }, { 0x0700, 0x13c1, 0x0000 }, { 0x0700, 0x13c3, 0x0000 }, { 0x8700, 0x13c8, 0x3000 }, { 0x8700, 0x13c6, 0x2000 }, { 0x0700, 0x13c5, 0x0000 }, { 0x0700, 0x13c7, 0x0000 }, { 0x8700, 0x13ca, 0x2000 }, { 0x0700, 0x13c9, 0x0000 }, { 0x0700, 0x13cb, 0x0000 }, { 0x8700, 0x1418, 0x7000 }, { 0x8700, 0x13ec, 0x6000 }, { 0x8700, 0x13dc, 0x5000 }, { 0x8700, 0x13d4, 0x4000 }, { 0x8700, 0x13d0, 0x3000 }, { 0x8700, 0x13ce, 0x2000 }, { 0x0700, 0x13cd, 0x0000 }, { 0x0700, 0x13cf, 0x0000 }, { 0x8700, 0x13d2, 0x2000 }, { 0x0700, 0x13d1, 0x0000 }, { 0x0700, 0x13d3, 0x0000 }, { 0x8700, 0x13d8, 0x3000 }, { 0x8700, 0x13d6, 0x2000 }, { 0x0700, 0x13d5, 0x0000 }, { 0x0700, 0x13d7, 0x0000 }, { 0x8700, 0x13da, 0x2000 }, { 0x0700, 0x13d9, 0x0000 }, { 0x0700, 0x13db, 0x0000 }, { 0x8700, 0x13e4, 0x4000 }, { 0x8700, 0x13e0, 0x3000 }, { 0x8700, 0x13de, 0x2000 }, { 0x0700, 0x13dd, 0x0000 }, { 0x0700, 0x13df, 0x0000 }, { 0x8700, 0x13e2, 0x2000 }, { 0x0700, 0x13e1, 0x0000 }, { 0x0700, 0x13e3, 0x0000 }, { 0x8700, 0x13e8, 0x3000 }, { 0x8700, 0x13e6, 0x2000 }, { 0x0700, 0x13e5, 0x0000 }, { 0x0700, 0x13e7, 0x0000 }, { 0x8700, 0x13ea, 0x2000 }, { 0x0700, 0x13e9, 0x0000 }, { 0x0700, 0x13eb, 0x0000 }, { 0x8700, 0x1408, 0x5000 }, { 0x8700, 0x13f4, 0x4000 }, { 0x8700, 0x13f0, 0x3000 }, { 0x8700, 0x13ee, 0x2000 }, { 0x0700, 0x13ed, 0x0000 }, { 0x0700, 0x13ef, 0x0000 }, { 0x8700, 0x13f2, 0x2000 }, { 0x0700, 0x13f1, 0x0000 }, { 0x0700, 0x13f3, 0x0000 }, { 0x8700, 0x1404, 0x3000 }, { 0x8700, 0x1402, 0x2000 }, { 0x0700, 0x1401, 0x0000 }, { 0x0700, 0x1403, 0x0000 }, { 0x8700, 0x1406, 0x2000 }, { 0x0700, 0x1405, 0x0000 }, { 0x0700, 0x1407, 0x0000 }, { 0x8700, 0x1410, 0x4000 }, { 0x8700, 0x140c, 0x3000 }, { 0x8700, 0x140a, 0x2000 }, { 0x0700, 0x1409, 0x0000 }, { 0x0700, 0x140b, 0x0000 }, { 0x8700, 0x140e, 0x2000 }, { 0x0700, 0x140d, 0x0000 }, { 0x0700, 0x140f, 0x0000 }, { 0x8700, 0x1414, 0x3000 }, { 0x8700, 0x1412, 0x2000 }, { 0x0700, 0x1411, 0x0000 }, { 0x0700, 0x1413, 0x0000 }, { 0x8700, 0x1416, 0x2000 }, { 0x0700, 0x1415, 0x0000 }, { 0x0700, 0x1417, 0x0000 }, { 0x8700, 0x1438, 0x6000 }, { 0x8700, 0x1428, 0x5000 }, { 0x8700, 0x1420, 0x4000 }, { 0x8700, 0x141c, 0x3000 }, { 0x8700, 0x141a, 0x2000 }, { 0x0700, 0x1419, 0x0000 }, { 0x0700, 0x141b, 0x0000 }, { 0x8700, 0x141e, 0x2000 }, { 0x0700, 0x141d, 0x0000 }, { 0x0700, 0x141f, 0x0000 }, { 0x8700, 0x1424, 0x3000 }, { 0x8700, 0x1422, 0x2000 }, { 0x0700, 0x1421, 0x0000 }, { 0x0700, 0x1423, 0x0000 }, { 0x8700, 0x1426, 0x2000 }, { 0x0700, 0x1425, 0x0000 }, { 0x0700, 0x1427, 0x0000 }, { 0x8700, 0x1430, 0x4000 }, { 0x8700, 0x142c, 0x3000 }, { 0x8700, 0x142a, 0x2000 }, { 0x0700, 0x1429, 0x0000 }, { 0x0700, 0x142b, 0x0000 }, { 0x8700, 0x142e, 0x2000 }, { 0x0700, 0x142d, 0x0000 }, { 0x0700, 0x142f, 0x0000 }, { 0x8700, 0x1434, 0x3000 }, { 0x8700, 0x1432, 0x2000 }, { 0x0700, 0x1431, 0x0000 }, { 0x0700, 0x1433, 0x0000 }, { 0x8700, 0x1436, 0x2000 }, { 0x0700, 0x1435, 0x0000 }, { 0x0700, 0x1437, 0x0000 }, { 0x8700, 0x1448, 0x5000 }, { 0x8700, 0x1440, 0x4000 }, { 0x8700, 0x143c, 0x3000 }, { 0x8700, 0x143a, 0x2000 }, { 0x0700, 0x1439, 0x0000 }, { 0x0700, 0x143b, 0x0000 }, { 0x8700, 0x143e, 0x2000 }, { 0x0700, 0x143d, 0x0000 }, { 0x0700, 0x143f, 0x0000 }, { 0x8700, 0x1444, 0x3000 }, { 0x8700, 0x1442, 0x2000 }, { 0x0700, 0x1441, 0x0000 }, { 0x0700, 0x1443, 0x0000 }, { 0x8700, 0x1446, 0x2000 }, { 0x0700, 0x1445, 0x0000 }, { 0x0700, 0x1447, 0x0000 }, { 0x8700, 0x1450, 0x4000 }, { 0x8700, 0x144c, 0x3000 }, { 0x8700, 0x144a, 0x2000 }, { 0x0700, 0x1449, 0x0000 }, { 0x0700, 0x144b, 0x0000 }, { 0x8700, 0x144e, 0x2000 }, { 0x0700, 0x144d, 0x0000 }, { 0x0700, 0x144f, 0x0000 }, { 0x8700, 0x1454, 0x3000 }, { 0x8700, 0x1452, 0x2000 }, { 0x0700, 0x1451, 0x0000 }, { 0x0700, 0x1453, 0x0000 }, { 0x8700, 0x1456, 0x2000 }, { 0x0700, 0x1455, 0x0000 }, { 0x0700, 0x1457, 0x0000 }, { 0x8700, 0x14d8, 0x8000 }, { 0x8700, 0x1498, 0x7000 }, { 0x8700, 0x1478, 0x6000 }, { 0x8700, 0x1468, 0x5000 }, { 0x8700, 0x1460, 0x4000 }, { 0x8700, 0x145c, 0x3000 }, { 0x8700, 0x145a, 0x2000 }, { 0x0700, 0x1459, 0x0000 }, { 0x0700, 0x145b, 0x0000 }, { 0x8700, 0x145e, 0x2000 }, { 0x0700, 0x145d, 0x0000 }, { 0x0700, 0x145f, 0x0000 }, { 0x8700, 0x1464, 0x3000 }, { 0x8700, 0x1462, 0x2000 }, { 0x0700, 0x1461, 0x0000 }, { 0x0700, 0x1463, 0x0000 }, { 0x8700, 0x1466, 0x2000 }, { 0x0700, 0x1465, 0x0000 }, { 0x0700, 0x1467, 0x0000 }, { 0x8700, 0x1470, 0x4000 }, { 0x8700, 0x146c, 0x3000 }, { 0x8700, 0x146a, 0x2000 }, { 0x0700, 0x1469, 0x0000 }, { 0x0700, 0x146b, 0x0000 }, { 0x8700, 0x146e, 0x2000 }, { 0x0700, 0x146d, 0x0000 }, { 0x0700, 0x146f, 0x0000 }, { 0x8700, 0x1474, 0x3000 }, { 0x8700, 0x1472, 0x2000 }, { 0x0700, 0x1471, 0x0000 }, { 0x0700, 0x1473, 0x0000 }, { 0x8700, 0x1476, 0x2000 }, { 0x0700, 0x1475, 0x0000 }, { 0x0700, 0x1477, 0x0000 }, { 0x8700, 0x1488, 0x5000 }, { 0x8700, 0x1480, 0x4000 }, { 0x8700, 0x147c, 0x3000 }, { 0x8700, 0x147a, 0x2000 }, { 0x0700, 0x1479, 0x0000 }, { 0x0700, 0x147b, 0x0000 }, { 0x8700, 0x147e, 0x2000 }, { 0x0700, 0x147d, 0x0000 }, { 0x0700, 0x147f, 0x0000 }, { 0x8700, 0x1484, 0x3000 }, { 0x8700, 0x1482, 0x2000 }, { 0x0700, 0x1481, 0x0000 }, { 0x0700, 0x1483, 0x0000 }, { 0x8700, 0x1486, 0x2000 }, { 0x0700, 0x1485, 0x0000 }, { 0x0700, 0x1487, 0x0000 }, { 0x8700, 0x1490, 0x4000 }, { 0x8700, 0x148c, 0x3000 }, { 0x8700, 0x148a, 0x2000 }, { 0x0700, 0x1489, 0x0000 }, { 0x0700, 0x148b, 0x0000 }, { 0x8700, 0x148e, 0x2000 }, { 0x0700, 0x148d, 0x0000 }, { 0x0700, 0x148f, 0x0000 }, { 0x8700, 0x1494, 0x3000 }, { 0x8700, 0x1492, 0x2000 }, { 0x0700, 0x1491, 0x0000 }, { 0x0700, 0x1493, 0x0000 }, { 0x8700, 0x1496, 0x2000 }, { 0x0700, 0x1495, 0x0000 }, { 0x0700, 0x1497, 0x0000 }, { 0x8700, 0x14b8, 0x6000 }, { 0x8700, 0x14a8, 0x5000 }, { 0x8700, 0x14a0, 0x4000 }, { 0x8700, 0x149c, 0x3000 }, { 0x8700, 0x149a, 0x2000 }, { 0x0700, 0x1499, 0x0000 }, { 0x0700, 0x149b, 0x0000 }, { 0x8700, 0x149e, 0x2000 }, { 0x0700, 0x149d, 0x0000 }, { 0x0700, 0x149f, 0x0000 }, { 0x8700, 0x14a4, 0x3000 }, { 0x8700, 0x14a2, 0x2000 }, { 0x0700, 0x14a1, 0x0000 }, { 0x0700, 0x14a3, 0x0000 }, { 0x8700, 0x14a6, 0x2000 }, { 0x0700, 0x14a5, 0x0000 }, { 0x0700, 0x14a7, 0x0000 }, { 0x8700, 0x14b0, 0x4000 }, { 0x8700, 0x14ac, 0x3000 }, { 0x8700, 0x14aa, 0x2000 }, { 0x0700, 0x14a9, 0x0000 }, { 0x0700, 0x14ab, 0x0000 }, { 0x8700, 0x14ae, 0x2000 }, { 0x0700, 0x14ad, 0x0000 }, { 0x0700, 0x14af, 0x0000 }, { 0x8700, 0x14b4, 0x3000 }, { 0x8700, 0x14b2, 0x2000 }, { 0x0700, 0x14b1, 0x0000 }, { 0x0700, 0x14b3, 0x0000 }, { 0x8700, 0x14b6, 0x2000 }, { 0x0700, 0x14b5, 0x0000 }, { 0x0700, 0x14b7, 0x0000 }, { 0x8700, 0x14c8, 0x5000 }, { 0x8700, 0x14c0, 0x4000 }, { 0x8700, 0x14bc, 0x3000 }, { 0x8700, 0x14ba, 0x2000 }, { 0x0700, 0x14b9, 0x0000 }, { 0x0700, 0x14bb, 0x0000 }, { 0x8700, 0x14be, 0x2000 }, { 0x0700, 0x14bd, 0x0000 }, { 0x0700, 0x14bf, 0x0000 }, { 0x8700, 0x14c4, 0x3000 }, { 0x8700, 0x14c2, 0x2000 }, { 0x0700, 0x14c1, 0x0000 }, { 0x0700, 0x14c3, 0x0000 }, { 0x8700, 0x14c6, 0x2000 }, { 0x0700, 0x14c5, 0x0000 }, { 0x0700, 0x14c7, 0x0000 }, { 0x8700, 0x14d0, 0x4000 }, { 0x8700, 0x14cc, 0x3000 }, { 0x8700, 0x14ca, 0x2000 }, { 0x0700, 0x14c9, 0x0000 }, { 0x0700, 0x14cb, 0x0000 }, { 0x8700, 0x14ce, 0x2000 }, { 0x0700, 0x14cd, 0x0000 }, { 0x0700, 0x14cf, 0x0000 }, { 0x8700, 0x14d4, 0x3000 }, { 0x8700, 0x14d2, 0x2000 }, { 0x0700, 0x14d1, 0x0000 }, { 0x0700, 0x14d3, 0x0000 }, { 0x8700, 0x14d6, 0x2000 }, { 0x0700, 0x14d5, 0x0000 }, { 0x0700, 0x14d7, 0x0000 }, { 0x8700, 0x1518, 0x7000 }, { 0x8700, 0x14f8, 0x6000 }, { 0x8700, 0x14e8, 0x5000 }, { 0x8700, 0x14e0, 0x4000 }, { 0x8700, 0x14dc, 0x3000 }, { 0x8700, 0x14da, 0x2000 }, { 0x0700, 0x14d9, 0x0000 }, { 0x0700, 0x14db, 0x0000 }, { 0x8700, 0x14de, 0x2000 }, { 0x0700, 0x14dd, 0x0000 }, { 0x0700, 0x14df, 0x0000 }, { 0x8700, 0x14e4, 0x3000 }, { 0x8700, 0x14e2, 0x2000 }, { 0x0700, 0x14e1, 0x0000 }, { 0x0700, 0x14e3, 0x0000 }, { 0x8700, 0x14e6, 0x2000 }, { 0x0700, 0x14e5, 0x0000 }, { 0x0700, 0x14e7, 0x0000 }, { 0x8700, 0x14f0, 0x4000 }, { 0x8700, 0x14ec, 0x3000 }, { 0x8700, 0x14ea, 0x2000 }, { 0x0700, 0x14e9, 0x0000 }, { 0x0700, 0x14eb, 0x0000 }, { 0x8700, 0x14ee, 0x2000 }, { 0x0700, 0x14ed, 0x0000 }, { 0x0700, 0x14ef, 0x0000 }, { 0x8700, 0x14f4, 0x3000 }, { 0x8700, 0x14f2, 0x2000 }, { 0x0700, 0x14f1, 0x0000 }, { 0x0700, 0x14f3, 0x0000 }, { 0x8700, 0x14f6, 0x2000 }, { 0x0700, 0x14f5, 0x0000 }, { 0x0700, 0x14f7, 0x0000 }, { 0x8700, 0x1508, 0x5000 }, { 0x8700, 0x1500, 0x4000 }, { 0x8700, 0x14fc, 0x3000 }, { 0x8700, 0x14fa, 0x2000 }, { 0x0700, 0x14f9, 0x0000 }, { 0x0700, 0x14fb, 0x0000 }, { 0x8700, 0x14fe, 0x2000 }, { 0x0700, 0x14fd, 0x0000 }, { 0x0700, 0x14ff, 0x0000 }, { 0x8700, 0x1504, 0x3000 }, { 0x8700, 0x1502, 0x2000 }, { 0x0700, 0x1501, 0x0000 }, { 0x0700, 0x1503, 0x0000 }, { 0x8700, 0x1506, 0x2000 }, { 0x0700, 0x1505, 0x0000 }, { 0x0700, 0x1507, 0x0000 }, { 0x8700, 0x1510, 0x4000 }, { 0x8700, 0x150c, 0x3000 }, { 0x8700, 0x150a, 0x2000 }, { 0x0700, 0x1509, 0x0000 }, { 0x0700, 0x150b, 0x0000 }, { 0x8700, 0x150e, 0x2000 }, { 0x0700, 0x150d, 0x0000 }, { 0x0700, 0x150f, 0x0000 }, { 0x8700, 0x1514, 0x3000 }, { 0x8700, 0x1512, 0x2000 }, { 0x0700, 0x1511, 0x0000 }, { 0x0700, 0x1513, 0x0000 }, { 0x8700, 0x1516, 0x2000 }, { 0x0700, 0x1515, 0x0000 }, { 0x0700, 0x1517, 0x0000 }, { 0x8700, 0x1538, 0x6000 }, { 0x8700, 0x1528, 0x5000 }, { 0x8700, 0x1520, 0x4000 }, { 0x8700, 0x151c, 0x3000 }, { 0x8700, 0x151a, 0x2000 }, { 0x0700, 0x1519, 0x0000 }, { 0x0700, 0x151b, 0x0000 }, { 0x8700, 0x151e, 0x2000 }, { 0x0700, 0x151d, 0x0000 }, { 0x0700, 0x151f, 0x0000 }, { 0x8700, 0x1524, 0x3000 }, { 0x8700, 0x1522, 0x2000 }, { 0x0700, 0x1521, 0x0000 }, { 0x0700, 0x1523, 0x0000 }, { 0x8700, 0x1526, 0x2000 }, { 0x0700, 0x1525, 0x0000 }, { 0x0700, 0x1527, 0x0000 }, { 0x8700, 0x1530, 0x4000 }, { 0x8700, 0x152c, 0x3000 }, { 0x8700, 0x152a, 0x2000 }, { 0x0700, 0x1529, 0x0000 }, { 0x0700, 0x152b, 0x0000 }, { 0x8700, 0x152e, 0x2000 }, { 0x0700, 0x152d, 0x0000 }, { 0x0700, 0x152f, 0x0000 }, { 0x8700, 0x1534, 0x3000 }, { 0x8700, 0x1532, 0x2000 }, { 0x0700, 0x1531, 0x0000 }, { 0x0700, 0x1533, 0x0000 }, { 0x8700, 0x1536, 0x2000 }, { 0x0700, 0x1535, 0x0000 }, { 0x0700, 0x1537, 0x0000 }, { 0x8700, 0x1548, 0x5000 }, { 0x8700, 0x1540, 0x4000 }, { 0x8700, 0x153c, 0x3000 }, { 0x8700, 0x153a, 0x2000 }, { 0x0700, 0x1539, 0x0000 }, { 0x0700, 0x153b, 0x0000 }, { 0x8700, 0x153e, 0x2000 }, { 0x0700, 0x153d, 0x0000 }, { 0x0700, 0x153f, 0x0000 }, { 0x8700, 0x1544, 0x3000 }, { 0x8700, 0x1542, 0x2000 }, { 0x0700, 0x1541, 0x0000 }, { 0x0700, 0x1543, 0x0000 }, { 0x8700, 0x1546, 0x2000 }, { 0x0700, 0x1545, 0x0000 }, { 0x0700, 0x1547, 0x0000 }, { 0x8700, 0x1550, 0x4000 }, { 0x8700, 0x154c, 0x3000 }, { 0x8700, 0x154a, 0x2000 }, { 0x0700, 0x1549, 0x0000 }, { 0x0700, 0x154b, 0x0000 }, { 0x8700, 0x154e, 0x2000 }, { 0x0700, 0x154d, 0x0000 }, { 0x0700, 0x154f, 0x0000 }, { 0x8700, 0x1554, 0x3000 }, { 0x8700, 0x1552, 0x2000 }, { 0x0700, 0x1551, 0x0000 }, { 0x0700, 0x1553, 0x0000 }, { 0x8700, 0x1556, 0x2000 }, { 0x0700, 0x1555, 0x0000 }, { 0x0700, 0x1557, 0x0000 }, { 0x9900, 0x22ae, 0xc000 }, { 0x8900, 0x1e24, 0xb001 }, { 0x8700, 0x17a2, 0xa000 }, { 0x8700, 0x1658, 0x9000 }, { 0x8700, 0x15d8, 0x8000 }, { 0x8700, 0x1598, 0x7000 }, { 0x8700, 0x1578, 0x6000 }, { 0x8700, 0x1568, 0x5000 }, { 0x8700, 0x1560, 0x4000 }, { 0x8700, 0x155c, 0x3000 }, { 0x8700, 0x155a, 0x2000 }, { 0x0700, 0x1559, 0x0000 }, { 0x0700, 0x155b, 0x0000 }, { 0x8700, 0x155e, 0x2000 }, { 0x0700, 0x155d, 0x0000 }, { 0x0700, 0x155f, 0x0000 }, { 0x8700, 0x1564, 0x3000 }, { 0x8700, 0x1562, 0x2000 }, { 0x0700, 0x1561, 0x0000 }, { 0x0700, 0x1563, 0x0000 }, { 0x8700, 0x1566, 0x2000 }, { 0x0700, 0x1565, 0x0000 }, { 0x0700, 0x1567, 0x0000 }, { 0x8700, 0x1570, 0x4000 }, { 0x8700, 0x156c, 0x3000 }, { 0x8700, 0x156a, 0x2000 }, { 0x0700, 0x1569, 0x0000 }, { 0x0700, 0x156b, 0x0000 }, { 0x8700, 0x156e, 0x2000 }, { 0x0700, 0x156d, 0x0000 }, { 0x0700, 0x156f, 0x0000 }, { 0x8700, 0x1574, 0x3000 }, { 0x8700, 0x1572, 0x2000 }, { 0x0700, 0x1571, 0x0000 }, { 0x0700, 0x1573, 0x0000 }, { 0x8700, 0x1576, 0x2000 }, { 0x0700, 0x1575, 0x0000 }, { 0x0700, 0x1577, 0x0000 }, { 0x8700, 0x1588, 0x5000 }, { 0x8700, 0x1580, 0x4000 }, { 0x8700, 0x157c, 0x3000 }, { 0x8700, 0x157a, 0x2000 }, { 0x0700, 0x1579, 0x0000 }, { 0x0700, 0x157b, 0x0000 }, { 0x8700, 0x157e, 0x2000 }, { 0x0700, 0x157d, 0x0000 }, { 0x0700, 0x157f, 0x0000 }, { 0x8700, 0x1584, 0x3000 }, { 0x8700, 0x1582, 0x2000 }, { 0x0700, 0x1581, 0x0000 }, { 0x0700, 0x1583, 0x0000 }, { 0x8700, 0x1586, 0x2000 }, { 0x0700, 0x1585, 0x0000 }, { 0x0700, 0x1587, 0x0000 }, { 0x8700, 0x1590, 0x4000 }, { 0x8700, 0x158c, 0x3000 }, { 0x8700, 0x158a, 0x2000 }, { 0x0700, 0x1589, 0x0000 }, { 0x0700, 0x158b, 0x0000 }, { 0x8700, 0x158e, 0x2000 }, { 0x0700, 0x158d, 0x0000 }, { 0x0700, 0x158f, 0x0000 }, { 0x8700, 0x1594, 0x3000 }, { 0x8700, 0x1592, 0x2000 }, { 0x0700, 0x1591, 0x0000 }, { 0x0700, 0x1593, 0x0000 }, { 0x8700, 0x1596, 0x2000 }, { 0x0700, 0x1595, 0x0000 }, { 0x0700, 0x1597, 0x0000 }, { 0x8700, 0x15b8, 0x6000 }, { 0x8700, 0x15a8, 0x5000 }, { 0x8700, 0x15a0, 0x4000 }, { 0x8700, 0x159c, 0x3000 }, { 0x8700, 0x159a, 0x2000 }, { 0x0700, 0x1599, 0x0000 }, { 0x0700, 0x159b, 0x0000 }, { 0x8700, 0x159e, 0x2000 }, { 0x0700, 0x159d, 0x0000 }, { 0x0700, 0x159f, 0x0000 }, { 0x8700, 0x15a4, 0x3000 }, { 0x8700, 0x15a2, 0x2000 }, { 0x0700, 0x15a1, 0x0000 }, { 0x0700, 0x15a3, 0x0000 }, { 0x8700, 0x15a6, 0x2000 }, { 0x0700, 0x15a5, 0x0000 }, { 0x0700, 0x15a7, 0x0000 }, { 0x8700, 0x15b0, 0x4000 }, { 0x8700, 0x15ac, 0x3000 }, { 0x8700, 0x15aa, 0x2000 }, { 0x0700, 0x15a9, 0x0000 }, { 0x0700, 0x15ab, 0x0000 }, { 0x8700, 0x15ae, 0x2000 }, { 0x0700, 0x15ad, 0x0000 }, { 0x0700, 0x15af, 0x0000 }, { 0x8700, 0x15b4, 0x3000 }, { 0x8700, 0x15b2, 0x2000 }, { 0x0700, 0x15b1, 0x0000 }, { 0x0700, 0x15b3, 0x0000 }, { 0x8700, 0x15b6, 0x2000 }, { 0x0700, 0x15b5, 0x0000 }, { 0x0700, 0x15b7, 0x0000 }, { 0x8700, 0x15c8, 0x5000 }, { 0x8700, 0x15c0, 0x4000 }, { 0x8700, 0x15bc, 0x3000 }, { 0x8700, 0x15ba, 0x2000 }, { 0x0700, 0x15b9, 0x0000 }, { 0x0700, 0x15bb, 0x0000 }, { 0x8700, 0x15be, 0x2000 }, { 0x0700, 0x15bd, 0x0000 }, { 0x0700, 0x15bf, 0x0000 }, { 0x8700, 0x15c4, 0x3000 }, { 0x8700, 0x15c2, 0x2000 }, { 0x0700, 0x15c1, 0x0000 }, { 0x0700, 0x15c3, 0x0000 }, { 0x8700, 0x15c6, 0x2000 }, { 0x0700, 0x15c5, 0x0000 }, { 0x0700, 0x15c7, 0x0000 }, { 0x8700, 0x15d0, 0x4000 }, { 0x8700, 0x15cc, 0x3000 }, { 0x8700, 0x15ca, 0x2000 }, { 0x0700, 0x15c9, 0x0000 }, { 0x0700, 0x15cb, 0x0000 }, { 0x8700, 0x15ce, 0x2000 }, { 0x0700, 0x15cd, 0x0000 }, { 0x0700, 0x15cf, 0x0000 }, { 0x8700, 0x15d4, 0x3000 }, { 0x8700, 0x15d2, 0x2000 }, { 0x0700, 0x15d1, 0x0000 }, { 0x0700, 0x15d3, 0x0000 }, { 0x8700, 0x15d6, 0x2000 }, { 0x0700, 0x15d5, 0x0000 }, { 0x0700, 0x15d7, 0x0000 }, { 0x8700, 0x1618, 0x7000 }, { 0x8700, 0x15f8, 0x6000 }, { 0x8700, 0x15e8, 0x5000 }, { 0x8700, 0x15e0, 0x4000 }, { 0x8700, 0x15dc, 0x3000 }, { 0x8700, 0x15da, 0x2000 }, { 0x0700, 0x15d9, 0x0000 }, { 0x0700, 0x15db, 0x0000 }, { 0x8700, 0x15de, 0x2000 }, { 0x0700, 0x15dd, 0x0000 }, { 0x0700, 0x15df, 0x0000 }, { 0x8700, 0x15e4, 0x3000 }, { 0x8700, 0x15e2, 0x2000 }, { 0x0700, 0x15e1, 0x0000 }, { 0x0700, 0x15e3, 0x0000 }, { 0x8700, 0x15e6, 0x2000 }, { 0x0700, 0x15e5, 0x0000 }, { 0x0700, 0x15e7, 0x0000 }, { 0x8700, 0x15f0, 0x4000 }, { 0x8700, 0x15ec, 0x3000 }, { 0x8700, 0x15ea, 0x2000 }, { 0x0700, 0x15e9, 0x0000 }, { 0x0700, 0x15eb, 0x0000 }, { 0x8700, 0x15ee, 0x2000 }, { 0x0700, 0x15ed, 0x0000 }, { 0x0700, 0x15ef, 0x0000 }, { 0x8700, 0x15f4, 0x3000 }, { 0x8700, 0x15f2, 0x2000 }, { 0x0700, 0x15f1, 0x0000 }, { 0x0700, 0x15f3, 0x0000 }, { 0x8700, 0x15f6, 0x2000 }, { 0x0700, 0x15f5, 0x0000 }, { 0x0700, 0x15f7, 0x0000 }, { 0x8700, 0x1608, 0x5000 }, { 0x8700, 0x1600, 0x4000 }, { 0x8700, 0x15fc, 0x3000 }, { 0x8700, 0x15fa, 0x2000 }, { 0x0700, 0x15f9, 0x0000 }, { 0x0700, 0x15fb, 0x0000 }, { 0x8700, 0x15fe, 0x2000 }, { 0x0700, 0x15fd, 0x0000 }, { 0x0700, 0x15ff, 0x0000 }, { 0x8700, 0x1604, 0x3000 }, { 0x8700, 0x1602, 0x2000 }, { 0x0700, 0x1601, 0x0000 }, { 0x0700, 0x1603, 0x0000 }, { 0x8700, 0x1606, 0x2000 }, { 0x0700, 0x1605, 0x0000 }, { 0x0700, 0x1607, 0x0000 }, { 0x8700, 0x1610, 0x4000 }, { 0x8700, 0x160c, 0x3000 }, { 0x8700, 0x160a, 0x2000 }, { 0x0700, 0x1609, 0x0000 }, { 0x0700, 0x160b, 0x0000 }, { 0x8700, 0x160e, 0x2000 }, { 0x0700, 0x160d, 0x0000 }, { 0x0700, 0x160f, 0x0000 }, { 0x8700, 0x1614, 0x3000 }, { 0x8700, 0x1612, 0x2000 }, { 0x0700, 0x1611, 0x0000 }, { 0x0700, 0x1613, 0x0000 }, { 0x8700, 0x1616, 0x2000 }, { 0x0700, 0x1615, 0x0000 }, { 0x0700, 0x1617, 0x0000 }, { 0x8700, 0x1638, 0x6000 }, { 0x8700, 0x1628, 0x5000 }, { 0x8700, 0x1620, 0x4000 }, { 0x8700, 0x161c, 0x3000 }, { 0x8700, 0x161a, 0x2000 }, { 0x0700, 0x1619, 0x0000 }, { 0x0700, 0x161b, 0x0000 }, { 0x8700, 0x161e, 0x2000 }, { 0x0700, 0x161d, 0x0000 }, { 0x0700, 0x161f, 0x0000 }, { 0x8700, 0x1624, 0x3000 }, { 0x8700, 0x1622, 0x2000 }, { 0x0700, 0x1621, 0x0000 }, { 0x0700, 0x1623, 0x0000 }, { 0x8700, 0x1626, 0x2000 }, { 0x0700, 0x1625, 0x0000 }, { 0x0700, 0x1627, 0x0000 }, { 0x8700, 0x1630, 0x4000 }, { 0x8700, 0x162c, 0x3000 }, { 0x8700, 0x162a, 0x2000 }, { 0x0700, 0x1629, 0x0000 }, { 0x0700, 0x162b, 0x0000 }, { 0x8700, 0x162e, 0x2000 }, { 0x0700, 0x162d, 0x0000 }, { 0x0700, 0x162f, 0x0000 }, { 0x8700, 0x1634, 0x3000 }, { 0x8700, 0x1632, 0x2000 }, { 0x0700, 0x1631, 0x0000 }, { 0x0700, 0x1633, 0x0000 }, { 0x8700, 0x1636, 0x2000 }, { 0x0700, 0x1635, 0x0000 }, { 0x0700, 0x1637, 0x0000 }, { 0x8700, 0x1648, 0x5000 }, { 0x8700, 0x1640, 0x4000 }, { 0x8700, 0x163c, 0x3000 }, { 0x8700, 0x163a, 0x2000 }, { 0x0700, 0x1639, 0x0000 }, { 0x0700, 0x163b, 0x0000 }, { 0x8700, 0x163e, 0x2000 }, { 0x0700, 0x163d, 0x0000 }, { 0x0700, 0x163f, 0x0000 }, { 0x8700, 0x1644, 0x3000 }, { 0x8700, 0x1642, 0x2000 }, { 0x0700, 0x1641, 0x0000 }, { 0x0700, 0x1643, 0x0000 }, { 0x8700, 0x1646, 0x2000 }, { 0x0700, 0x1645, 0x0000 }, { 0x0700, 0x1647, 0x0000 }, { 0x8700, 0x1650, 0x4000 }, { 0x8700, 0x164c, 0x3000 }, { 0x8700, 0x164a, 0x2000 }, { 0x0700, 0x1649, 0x0000 }, { 0x0700, 0x164b, 0x0000 }, { 0x8700, 0x164e, 0x2000 }, { 0x0700, 0x164d, 0x0000 }, { 0x0700, 0x164f, 0x0000 }, { 0x8700, 0x1654, 0x3000 }, { 0x8700, 0x1652, 0x2000 }, { 0x0700, 0x1651, 0x0000 }, { 0x0700, 0x1653, 0x0000 }, { 0x8700, 0x1656, 0x2000 }, { 0x0700, 0x1655, 0x0000 }, { 0x0700, 0x1657, 0x0000 }, { 0x8700, 0x16e4, 0x8000 }, { 0x8700, 0x16a4, 0x7000 }, { 0x8700, 0x1681, 0x6000 }, { 0x8700, 0x1668, 0x5000 }, { 0x8700, 0x1660, 0x4000 }, { 0x8700, 0x165c, 0x3000 }, { 0x8700, 0x165a, 0x2000 }, { 0x0700, 0x1659, 0x0000 }, { 0x0700, 0x165b, 0x0000 }, { 0x8700, 0x165e, 0x2000 }, { 0x0700, 0x165d, 0x0000 }, { 0x0700, 0x165f, 0x0000 }, { 0x8700, 0x1664, 0x3000 }, { 0x8700, 0x1662, 0x2000 }, { 0x0700, 0x1661, 0x0000 }, { 0x0700, 0x1663, 0x0000 }, { 0x8700, 0x1666, 0x2000 }, { 0x0700, 0x1665, 0x0000 }, { 0x0700, 0x1667, 0x0000 }, { 0x8700, 0x1670, 0x4000 }, { 0x8700, 0x166c, 0x3000 }, { 0x8700, 0x166a, 0x2000 }, { 0x0700, 0x1669, 0x0000 }, { 0x0700, 0x166b, 0x0000 }, { 0x9500, 0x166e, 0x2000 }, { 0x1500, 0x166d, 0x0000 }, { 0x0700, 0x166f, 0x0000 }, { 0x8700, 0x1674, 0x3000 }, { 0x8700, 0x1672, 0x2000 }, { 0x0700, 0x1671, 0x0000 }, { 0x0700, 0x1673, 0x0000 }, { 0x8700, 0x1676, 0x2000 }, { 0x0700, 0x1675, 0x0000 }, { 0x1d00, 0x1680, 0x0000 }, { 0x8700, 0x1691, 0x5000 }, { 0x8700, 0x1689, 0x4000 }, { 0x8700, 0x1685, 0x3000 }, { 0x8700, 0x1683, 0x2000 }, { 0x0700, 0x1682, 0x0000 }, { 0x0700, 0x1684, 0x0000 }, { 0x8700, 0x1687, 0x2000 }, { 0x0700, 0x1686, 0x0000 }, { 0x0700, 0x1688, 0x0000 }, { 0x8700, 0x168d, 0x3000 }, { 0x8700, 0x168b, 0x2000 }, { 0x0700, 0x168a, 0x0000 }, { 0x0700, 0x168c, 0x0000 }, { 0x8700, 0x168f, 0x2000 }, { 0x0700, 0x168e, 0x0000 }, { 0x0700, 0x1690, 0x0000 }, { 0x8700, 0x1699, 0x4000 }, { 0x8700, 0x1695, 0x3000 }, { 0x8700, 0x1693, 0x2000 }, { 0x0700, 0x1692, 0x0000 }, { 0x0700, 0x1694, 0x0000 }, { 0x8700, 0x1697, 0x2000 }, { 0x0700, 0x1696, 0x0000 }, { 0x0700, 0x1698, 0x0000 }, { 0x8700, 0x16a0, 0x3000 }, { 0x9600, 0x169b, 0x2000 }, { 0x0700, 0x169a, 0x0000 }, { 0x1200, 0x169c, 0x0000 }, { 0x8700, 0x16a2, 0x2000 }, { 0x0700, 0x16a1, 0x0000 }, { 0x0700, 0x16a3, 0x0000 }, { 0x8700, 0x16c4, 0x6000 }, { 0x8700, 0x16b4, 0x5000 }, { 0x8700, 0x16ac, 0x4000 }, { 0x8700, 0x16a8, 0x3000 }, { 0x8700, 0x16a6, 0x2000 }, { 0x0700, 0x16a5, 0x0000 }, { 0x0700, 0x16a7, 0x0000 }, { 0x8700, 0x16aa, 0x2000 }, { 0x0700, 0x16a9, 0x0000 }, { 0x0700, 0x16ab, 0x0000 }, { 0x8700, 0x16b0, 0x3000 }, { 0x8700, 0x16ae, 0x2000 }, { 0x0700, 0x16ad, 0x0000 }, { 0x0700, 0x16af, 0x0000 }, { 0x8700, 0x16b2, 0x2000 }, { 0x0700, 0x16b1, 0x0000 }, { 0x0700, 0x16b3, 0x0000 }, { 0x8700, 0x16bc, 0x4000 }, { 0x8700, 0x16b8, 0x3000 }, { 0x8700, 0x16b6, 0x2000 }, { 0x0700, 0x16b5, 0x0000 }, { 0x0700, 0x16b7, 0x0000 }, { 0x8700, 0x16ba, 0x2000 }, { 0x0700, 0x16b9, 0x0000 }, { 0x0700, 0x16bb, 0x0000 }, { 0x8700, 0x16c0, 0x3000 }, { 0x8700, 0x16be, 0x2000 }, { 0x0700, 0x16bd, 0x0000 }, { 0x0700, 0x16bf, 0x0000 }, { 0x8700, 0x16c2, 0x2000 }, { 0x0700, 0x16c1, 0x0000 }, { 0x0700, 0x16c3, 0x0000 }, { 0x8700, 0x16d4, 0x5000 }, { 0x8700, 0x16cc, 0x4000 }, { 0x8700, 0x16c8, 0x3000 }, { 0x8700, 0x16c6, 0x2000 }, { 0x0700, 0x16c5, 0x0000 }, { 0x0700, 0x16c7, 0x0000 }, { 0x8700, 0x16ca, 0x2000 }, { 0x0700, 0x16c9, 0x0000 }, { 0x0700, 0x16cb, 0x0000 }, { 0x8700, 0x16d0, 0x3000 }, { 0x8700, 0x16ce, 0x2000 }, { 0x0700, 0x16cd, 0x0000 }, { 0x0700, 0x16cf, 0x0000 }, { 0x8700, 0x16d2, 0x2000 }, { 0x0700, 0x16d1, 0x0000 }, { 0x0700, 0x16d3, 0x0000 }, { 0x8700, 0x16dc, 0x4000 }, { 0x8700, 0x16d8, 0x3000 }, { 0x8700, 0x16d6, 0x2000 }, { 0x0700, 0x16d5, 0x0000 }, { 0x0700, 0x16d7, 0x0000 }, { 0x8700, 0x16da, 0x2000 }, { 0x0700, 0x16d9, 0x0000 }, { 0x0700, 0x16db, 0x0000 }, { 0x8700, 0x16e0, 0x3000 }, { 0x8700, 0x16de, 0x2000 }, { 0x0700, 0x16dd, 0x0000 }, { 0x0700, 0x16df, 0x0000 }, { 0x8700, 0x16e2, 0x2000 }, { 0x0700, 0x16e1, 0x0000 }, { 0x0700, 0x16e3, 0x0000 }, { 0x8700, 0x1748, 0x7000 }, { 0x8c00, 0x1714, 0x6000 }, { 0x8700, 0x1703, 0x5000 }, { 0x9500, 0x16ec, 0x4000 }, { 0x8700, 0x16e8, 0x3000 }, { 0x8700, 0x16e6, 0x2000 }, { 0x0700, 0x16e5, 0x0000 }, { 0x0700, 0x16e7, 0x0000 }, { 0x8700, 0x16ea, 0x2000 }, { 0x0700, 0x16e9, 0x0000 }, { 0x1500, 0x16eb, 0x0000 }, { 0x8e00, 0x16f0, 0x3000 }, { 0x8e00, 0x16ee, 0x2000 }, { 0x1500, 0x16ed, 0x0000 }, { 0x0e00, 0x16ef, 0x0000 }, { 0x8700, 0x1701, 0x2000 }, { 0x0700, 0x1700, 0x0000 }, { 0x0700, 0x1702, 0x0000 }, { 0x8700, 0x170b, 0x4000 }, { 0x8700, 0x1707, 0x3000 }, { 0x8700, 0x1705, 0x2000 }, { 0x0700, 0x1704, 0x0000 }, { 0x0700, 0x1706, 0x0000 }, { 0x8700, 0x1709, 0x2000 }, { 0x0700, 0x1708, 0x0000 }, { 0x0700, 0x170a, 0x0000 }, { 0x8700, 0x1710, 0x3000 }, { 0x8700, 0x170e, 0x2000 }, { 0x0700, 0x170c, 0x0000 }, { 0x0700, 0x170f, 0x0000 }, { 0x8c00, 0x1712, 0x2000 }, { 0x0700, 0x1711, 0x0000 }, { 0x0c00, 0x1713, 0x0000 }, { 0x8700, 0x172f, 0x5000 }, { 0x8700, 0x1727, 0x4000 }, { 0x8700, 0x1723, 0x3000 }, { 0x8700, 0x1721, 0x2000 }, { 0x0700, 0x1720, 0x0000 }, { 0x0700, 0x1722, 0x0000 }, { 0x8700, 0x1725, 0x2000 }, { 0x0700, 0x1724, 0x0000 }, { 0x0700, 0x1726, 0x0000 }, { 0x8700, 0x172b, 0x3000 }, { 0x8700, 0x1729, 0x2000 }, { 0x0700, 0x1728, 0x0000 }, { 0x0700, 0x172a, 0x0000 }, { 0x8700, 0x172d, 0x2000 }, { 0x0700, 0x172c, 0x0000 }, { 0x0700, 0x172e, 0x0000 }, { 0x8700, 0x1740, 0x4000 }, { 0x8c00, 0x1733, 0x3000 }, { 0x8700, 0x1731, 0x2000 }, { 0x0700, 0x1730, 0x0000 }, { 0x0c00, 0x1732, 0x0000 }, { 0x9500, 0x1735, 0x2000 }, { 0x0c00, 0x1734, 0x0000 }, { 0x1500, 0x1736, 0x0000 }, { 0x8700, 0x1744, 0x3000 }, { 0x8700, 0x1742, 0x2000 }, { 0x0700, 0x1741, 0x0000 }, { 0x0700, 0x1743, 0x0000 }, { 0x8700, 0x1746, 0x2000 }, { 0x0700, 0x1745, 0x0000 }, { 0x0700, 0x1747, 0x0000 }, { 0x8700, 0x1782, 0x6000 }, { 0x8700, 0x1764, 0x5000 }, { 0x8700, 0x1750, 0x4000 }, { 0x8700, 0x174c, 0x3000 }, { 0x8700, 0x174a, 0x2000 }, { 0x0700, 0x1749, 0x0000 }, { 0x0700, 0x174b, 0x0000 }, { 0x8700, 0x174e, 0x2000 }, { 0x0700, 0x174d, 0x0000 }, { 0x0700, 0x174f, 0x0000 }, { 0x8700, 0x1760, 0x3000 }, { 0x8c00, 0x1752, 0x2000 }, { 0x0700, 0x1751, 0x0000 }, { 0x0c00, 0x1753, 0x0000 }, { 0x8700, 0x1762, 0x2000 }, { 0x0700, 0x1761, 0x0000 }, { 0x0700, 0x1763, 0x0000 }, { 0x8700, 0x176c, 0x4000 }, { 0x8700, 0x1768, 0x3000 }, { 0x8700, 0x1766, 0x2000 }, { 0x0700, 0x1765, 0x0000 }, { 0x0700, 0x1767, 0x0000 }, { 0x8700, 0x176a, 0x2000 }, { 0x0700, 0x1769, 0x0000 }, { 0x0700, 0x176b, 0x0000 }, { 0x8c00, 0x1772, 0x3000 }, { 0x8700, 0x176f, 0x2000 }, { 0x0700, 0x176e, 0x0000 }, { 0x0700, 0x1770, 0x0000 }, { 0x8700, 0x1780, 0x2000 }, { 0x0c00, 0x1773, 0x0000 }, { 0x0700, 0x1781, 0x0000 }, { 0x8700, 0x1792, 0x5000 }, { 0x8700, 0x178a, 0x4000 }, { 0x8700, 0x1786, 0x3000 }, { 0x8700, 0x1784, 0x2000 }, { 0x0700, 0x1783, 0x0000 }, { 0x0700, 0x1785, 0x0000 }, { 0x8700, 0x1788, 0x2000 }, { 0x0700, 0x1787, 0x0000 }, { 0x0700, 0x1789, 0x0000 }, { 0x8700, 0x178e, 0x3000 }, { 0x8700, 0x178c, 0x2000 }, { 0x0700, 0x178b, 0x0000 }, { 0x0700, 0x178d, 0x0000 }, { 0x8700, 0x1790, 0x2000 }, { 0x0700, 0x178f, 0x0000 }, { 0x0700, 0x1791, 0x0000 }, { 0x8700, 0x179a, 0x4000 }, { 0x8700, 0x1796, 0x3000 }, { 0x8700, 0x1794, 0x2000 }, { 0x0700, 0x1793, 0x0000 }, { 0x0700, 0x1795, 0x0000 }, { 0x8700, 0x1798, 0x2000 }, { 0x0700, 0x1797, 0x0000 }, { 0x0700, 0x1799, 0x0000 }, { 0x8700, 0x179e, 0x3000 }, { 0x8700, 0x179c, 0x2000 }, { 0x0700, 0x179b, 0x0000 }, { 0x0700, 0x179d, 0x0000 }, { 0x8700, 0x17a0, 0x2000 }, { 0x0700, 0x179f, 0x0000 }, { 0x0700, 0x17a1, 0x0000 }, { 0x8700, 0x1915, 0x9000 }, { 0x8700, 0x1837, 0x8000 }, { 0x8d00, 0x17e4, 0x7000 }, { 0x8a00, 0x17c2, 0x6000 }, { 0x8700, 0x17b2, 0x5000 }, { 0x8700, 0x17aa, 0x4000 }, { 0x8700, 0x17a6, 0x3000 }, { 0x8700, 0x17a4, 0x2000 }, { 0x0700, 0x17a3, 0x0000 }, { 0x0700, 0x17a5, 0x0000 }, { 0x8700, 0x17a8, 0x2000 }, { 0x0700, 0x17a7, 0x0000 }, { 0x0700, 0x17a9, 0x0000 }, { 0x8700, 0x17ae, 0x3000 }, { 0x8700, 0x17ac, 0x2000 }, { 0x0700, 0x17ab, 0x0000 }, { 0x0700, 0x17ad, 0x0000 }, { 0x8700, 0x17b0, 0x2000 }, { 0x0700, 0x17af, 0x0000 }, { 0x0700, 0x17b1, 0x0000 }, { 0x8c00, 0x17ba, 0x4000 }, { 0x8a00, 0x17b6, 0x3000 }, { 0x8100, 0x17b4, 0x2000 }, { 0x0700, 0x17b3, 0x0000 }, { 0x0100, 0x17b5, 0x0000 }, { 0x8c00, 0x17b8, 0x2000 }, { 0x0c00, 0x17b7, 0x0000 }, { 0x0c00, 0x17b9, 0x0000 }, { 0x8a00, 0x17be, 0x3000 }, { 0x8c00, 0x17bc, 0x2000 }, { 0x0c00, 0x17bb, 0x0000 }, { 0x0c00, 0x17bd, 0x0000 }, { 0x8a00, 0x17c0, 0x2000 }, { 0x0a00, 0x17bf, 0x0000 }, { 0x0a00, 0x17c1, 0x0000 }, { 0x8c00, 0x17d2, 0x5000 }, { 0x8c00, 0x17ca, 0x4000 }, { 0x8c00, 0x17c6, 0x3000 }, { 0x8a00, 0x17c4, 0x2000 }, { 0x0a00, 0x17c3, 0x0000 }, { 0x0a00, 0x17c5, 0x0000 }, { 0x8a00, 0x17c8, 0x2000 }, { 0x0a00, 0x17c7, 0x0000 }, { 0x0c00, 0x17c9, 0x0000 }, { 0x8c00, 0x17ce, 0x3000 }, { 0x8c00, 0x17cc, 0x2000 }, { 0x0c00, 0x17cb, 0x0000 }, { 0x0c00, 0x17cd, 0x0000 }, { 0x8c00, 0x17d0, 0x2000 }, { 0x0c00, 0x17cf, 0x0000 }, { 0x0c00, 0x17d1, 0x0000 }, { 0x9500, 0x17da, 0x4000 }, { 0x9500, 0x17d6, 0x3000 }, { 0x9500, 0x17d4, 0x2000 }, { 0x0c00, 0x17d3, 0x0000 }, { 0x1500, 0x17d5, 0x0000 }, { 0x9500, 0x17d8, 0x2000 }, { 0x0600, 0x17d7, 0x0000 }, { 0x1500, 0x17d9, 0x0000 }, { 0x8d00, 0x17e0, 0x3000 }, { 0x8700, 0x17dc, 0x2000 }, { 0x1700, 0x17db, 0x0000 }, { 0x0c00, 0x17dd, 0x0000 }, { 0x8d00, 0x17e2, 0x2000 }, { 0x0d00, 0x17e1, 0x0000 }, { 0x0d00, 0x17e3, 0x0000 }, { 0x8d00, 0x1811, 0x6000 }, { 0x9500, 0x1800, 0x5000 }, { 0x8f00, 0x17f2, 0x4000 }, { 0x8d00, 0x17e8, 0x3000 }, { 0x8d00, 0x17e6, 0x2000 }, { 0x0d00, 0x17e5, 0x0000 }, { 0x0d00, 0x17e7, 0x0000 }, { 0x8f00, 0x17f0, 0x2000 }, { 0x0d00, 0x17e9, 0x0000 }, { 0x0f00, 0x17f1, 0x0000 }, { 0x8f00, 0x17f6, 0x3000 }, { 0x8f00, 0x17f4, 0x2000 }, { 0x0f00, 0x17f3, 0x0000 }, { 0x0f00, 0x17f5, 0x0000 }, { 0x8f00, 0x17f8, 0x2000 }, { 0x0f00, 0x17f7, 0x0000 }, { 0x0f00, 0x17f9, 0x0000 }, { 0x9500, 0x1808, 0x4000 }, { 0x9500, 0x1804, 0x3000 }, { 0x9500, 0x1802, 0x2000 }, { 0x1500, 0x1801, 0x0000 }, { 0x1500, 0x1803, 0x0000 }, { 0x9100, 0x1806, 0x2000 }, { 0x1500, 0x1805, 0x0000 }, { 0x1500, 0x1807, 0x0000 }, { 0x8c00, 0x180c, 0x3000 }, { 0x9500, 0x180a, 0x2000 }, { 0x1500, 0x1809, 0x0000 }, { 0x0c00, 0x180b, 0x0000 }, { 0x9d00, 0x180e, 0x2000 }, { 0x0c00, 0x180d, 0x0000 }, { 0x0d00, 0x1810, 0x0000 }, { 0x8700, 0x1827, 0x5000 }, { 0x8d00, 0x1819, 0x4000 }, { 0x8d00, 0x1815, 0x3000 }, { 0x8d00, 0x1813, 0x2000 }, { 0x0d00, 0x1812, 0x0000 }, { 0x0d00, 0x1814, 0x0000 }, { 0x8d00, 0x1817, 0x2000 }, { 0x0d00, 0x1816, 0x0000 }, { 0x0d00, 0x1818, 0x0000 }, { 0x8700, 0x1823, 0x3000 }, { 0x8700, 0x1821, 0x2000 }, { 0x0700, 0x1820, 0x0000 }, { 0x0700, 0x1822, 0x0000 }, { 0x8700, 0x1825, 0x2000 }, { 0x0700, 0x1824, 0x0000 }, { 0x0700, 0x1826, 0x0000 }, { 0x8700, 0x182f, 0x4000 }, { 0x8700, 0x182b, 0x3000 }, { 0x8700, 0x1829, 0x2000 }, { 0x0700, 0x1828, 0x0000 }, { 0x0700, 0x182a, 0x0000 }, { 0x8700, 0x182d, 0x2000 }, { 0x0700, 0x182c, 0x0000 }, { 0x0700, 0x182e, 0x0000 }, { 0x8700, 0x1833, 0x3000 }, { 0x8700, 0x1831, 0x2000 }, { 0x0700, 0x1830, 0x0000 }, { 0x0700, 0x1832, 0x0000 }, { 0x8700, 0x1835, 0x2000 }, { 0x0700, 0x1834, 0x0000 }, { 0x0700, 0x1836, 0x0000 }, { 0x8700, 0x1877, 0x7000 }, { 0x8700, 0x1857, 0x6000 }, { 0x8700, 0x1847, 0x5000 }, { 0x8700, 0x183f, 0x4000 }, { 0x8700, 0x183b, 0x3000 }, { 0x8700, 0x1839, 0x2000 }, { 0x0700, 0x1838, 0x0000 }, { 0x0700, 0x183a, 0x0000 }, { 0x8700, 0x183d, 0x2000 }, { 0x0700, 0x183c, 0x0000 }, { 0x0700, 0x183e, 0x0000 }, { 0x8600, 0x1843, 0x3000 }, { 0x8700, 0x1841, 0x2000 }, { 0x0700, 0x1840, 0x0000 }, { 0x0700, 0x1842, 0x0000 }, { 0x8700, 0x1845, 0x2000 }, { 0x0700, 0x1844, 0x0000 }, { 0x0700, 0x1846, 0x0000 }, { 0x8700, 0x184f, 0x4000 }, { 0x8700, 0x184b, 0x3000 }, { 0x8700, 0x1849, 0x2000 }, { 0x0700, 0x1848, 0x0000 }, { 0x0700, 0x184a, 0x0000 }, { 0x8700, 0x184d, 0x2000 }, { 0x0700, 0x184c, 0x0000 }, { 0x0700, 0x184e, 0x0000 }, { 0x8700, 0x1853, 0x3000 }, { 0x8700, 0x1851, 0x2000 }, { 0x0700, 0x1850, 0x0000 }, { 0x0700, 0x1852, 0x0000 }, { 0x8700, 0x1855, 0x2000 }, { 0x0700, 0x1854, 0x0000 }, { 0x0700, 0x1856, 0x0000 }, { 0x8700, 0x1867, 0x5000 }, { 0x8700, 0x185f, 0x4000 }, { 0x8700, 0x185b, 0x3000 }, { 0x8700, 0x1859, 0x2000 }, { 0x0700, 0x1858, 0x0000 }, { 0x0700, 0x185a, 0x0000 }, { 0x8700, 0x185d, 0x2000 }, { 0x0700, 0x185c, 0x0000 }, { 0x0700, 0x185e, 0x0000 }, { 0x8700, 0x1863, 0x3000 }, { 0x8700, 0x1861, 0x2000 }, { 0x0700, 0x1860, 0x0000 }, { 0x0700, 0x1862, 0x0000 }, { 0x8700, 0x1865, 0x2000 }, { 0x0700, 0x1864, 0x0000 }, { 0x0700, 0x1866, 0x0000 }, { 0x8700, 0x186f, 0x4000 }, { 0x8700, 0x186b, 0x3000 }, { 0x8700, 0x1869, 0x2000 }, { 0x0700, 0x1868, 0x0000 }, { 0x0700, 0x186a, 0x0000 }, { 0x8700, 0x186d, 0x2000 }, { 0x0700, 0x186c, 0x0000 }, { 0x0700, 0x186e, 0x0000 }, { 0x8700, 0x1873, 0x3000 }, { 0x8700, 0x1871, 0x2000 }, { 0x0700, 0x1870, 0x0000 }, { 0x0700, 0x1872, 0x0000 }, { 0x8700, 0x1875, 0x2000 }, { 0x0700, 0x1874, 0x0000 }, { 0x0700, 0x1876, 0x0000 }, { 0x8700, 0x189f, 0x6000 }, { 0x8700, 0x188f, 0x5000 }, { 0x8700, 0x1887, 0x4000 }, { 0x8700, 0x1883, 0x3000 }, { 0x8700, 0x1881, 0x2000 }, { 0x0700, 0x1880, 0x0000 }, { 0x0700, 0x1882, 0x0000 }, { 0x8700, 0x1885, 0x2000 }, { 0x0700, 0x1884, 0x0000 }, { 0x0700, 0x1886, 0x0000 }, { 0x8700, 0x188b, 0x3000 }, { 0x8700, 0x1889, 0x2000 }, { 0x0700, 0x1888, 0x0000 }, { 0x0700, 0x188a, 0x0000 }, { 0x8700, 0x188d, 0x2000 }, { 0x0700, 0x188c, 0x0000 }, { 0x0700, 0x188e, 0x0000 }, { 0x8700, 0x1897, 0x4000 }, { 0x8700, 0x1893, 0x3000 }, { 0x8700, 0x1891, 0x2000 }, { 0x0700, 0x1890, 0x0000 }, { 0x0700, 0x1892, 0x0000 }, { 0x8700, 0x1895, 0x2000 }, { 0x0700, 0x1894, 0x0000 }, { 0x0700, 0x1896, 0x0000 }, { 0x8700, 0x189b, 0x3000 }, { 0x8700, 0x1899, 0x2000 }, { 0x0700, 0x1898, 0x0000 }, { 0x0700, 0x189a, 0x0000 }, { 0x8700, 0x189d, 0x2000 }, { 0x0700, 0x189c, 0x0000 }, { 0x0700, 0x189e, 0x0000 }, { 0x8700, 0x1905, 0x5000 }, { 0x8700, 0x18a7, 0x4000 }, { 0x8700, 0x18a3, 0x3000 }, { 0x8700, 0x18a1, 0x2000 }, { 0x0700, 0x18a0, 0x0000 }, { 0x0700, 0x18a2, 0x0000 }, { 0x8700, 0x18a5, 0x2000 }, { 0x0700, 0x18a4, 0x0000 }, { 0x0700, 0x18a6, 0x0000 }, { 0x8700, 0x1901, 0x3000 }, { 0x8c00, 0x18a9, 0x2000 }, { 0x0700, 0x18a8, 0x0000 }, { 0x0700, 0x1900, 0x0000 }, { 0x8700, 0x1903, 0x2000 }, { 0x0700, 0x1902, 0x0000 }, { 0x0700, 0x1904, 0x0000 }, { 0x8700, 0x190d, 0x4000 }, { 0x8700, 0x1909, 0x3000 }, { 0x8700, 0x1907, 0x2000 }, { 0x0700, 0x1906, 0x0000 }, { 0x0700, 0x1908, 0x0000 }, { 0x8700, 0x190b, 0x2000 }, { 0x0700, 0x190a, 0x0000 }, { 0x0700, 0x190c, 0x0000 }, { 0x8700, 0x1911, 0x3000 }, { 0x8700, 0x190f, 0x2000 }, { 0x0700, 0x190e, 0x0000 }, { 0x0700, 0x1910, 0x0000 }, { 0x8700, 0x1913, 0x2000 }, { 0x0700, 0x1912, 0x0000 }, { 0x0700, 0x1914, 0x0000 }, { 0x8500, 0x1d10, 0x8000 }, { 0x8700, 0x1963, 0x7000 }, { 0x9a00, 0x1940, 0x6000 }, { 0x8c00, 0x1928, 0x5000 }, { 0x8c00, 0x1920, 0x4000 }, { 0x8700, 0x1919, 0x3000 }, { 0x8700, 0x1917, 0x2000 }, { 0x0700, 0x1916, 0x0000 }, { 0x0700, 0x1918, 0x0000 }, { 0x8700, 0x191b, 0x2000 }, { 0x0700, 0x191a, 0x0000 }, { 0x0700, 0x191c, 0x0000 }, { 0x8a00, 0x1924, 0x3000 }, { 0x8c00, 0x1922, 0x2000 }, { 0x0c00, 0x1921, 0x0000 }, { 0x0a00, 0x1923, 0x0000 }, { 0x8a00, 0x1926, 0x2000 }, { 0x0a00, 0x1925, 0x0000 }, { 0x0c00, 0x1927, 0x0000 }, { 0x8a00, 0x1934, 0x4000 }, { 0x8a00, 0x1930, 0x3000 }, { 0x8a00, 0x192a, 0x2000 }, { 0x0a00, 0x1929, 0x0000 }, { 0x0a00, 0x192b, 0x0000 }, { 0x8c00, 0x1932, 0x2000 }, { 0x0a00, 0x1931, 0x0000 }, { 0x0a00, 0x1933, 0x0000 }, { 0x8a00, 0x1938, 0x3000 }, { 0x8a00, 0x1936, 0x2000 }, { 0x0a00, 0x1935, 0x0000 }, { 0x0a00, 0x1937, 0x0000 }, { 0x8c00, 0x193a, 0x2000 }, { 0x0c00, 0x1939, 0x0000 }, { 0x0c00, 0x193b, 0x0000 }, { 0x8700, 0x1953, 0x5000 }, { 0x8d00, 0x194b, 0x4000 }, { 0x8d00, 0x1947, 0x3000 }, { 0x9500, 0x1945, 0x2000 }, { 0x1500, 0x1944, 0x0000 }, { 0x0d00, 0x1946, 0x0000 }, { 0x8d00, 0x1949, 0x2000 }, { 0x0d00, 0x1948, 0x0000 }, { 0x0d00, 0x194a, 0x0000 }, { 0x8d00, 0x194f, 0x3000 }, { 0x8d00, 0x194d, 0x2000 }, { 0x0d00, 0x194c, 0x0000 }, { 0x0d00, 0x194e, 0x0000 }, { 0x8700, 0x1951, 0x2000 }, { 0x0700, 0x1950, 0x0000 }, { 0x0700, 0x1952, 0x0000 }, { 0x8700, 0x195b, 0x4000 }, { 0x8700, 0x1957, 0x3000 }, { 0x8700, 0x1955, 0x2000 }, { 0x0700, 0x1954, 0x0000 }, { 0x0700, 0x1956, 0x0000 }, { 0x8700, 0x1959, 0x2000 }, { 0x0700, 0x1958, 0x0000 }, { 0x0700, 0x195a, 0x0000 }, { 0x8700, 0x195f, 0x3000 }, { 0x8700, 0x195d, 0x2000 }, { 0x0700, 0x195c, 0x0000 }, { 0x0700, 0x195e, 0x0000 }, { 0x8700, 0x1961, 0x2000 }, { 0x0700, 0x1960, 0x0000 }, { 0x0700, 0x1962, 0x0000 }, { 0x9a00, 0x19f0, 0x6000 }, { 0x9a00, 0x19e0, 0x5000 }, { 0x8700, 0x196b, 0x4000 }, { 0x8700, 0x1967, 0x3000 }, { 0x8700, 0x1965, 0x2000 }, { 0x0700, 0x1964, 0x0000 }, { 0x0700, 0x1966, 0x0000 }, { 0x8700, 0x1969, 0x2000 }, { 0x0700, 0x1968, 0x0000 }, { 0x0700, 0x196a, 0x0000 }, { 0x8700, 0x1971, 0x3000 }, { 0x8700, 0x196d, 0x2000 }, { 0x0700, 0x196c, 0x0000 }, { 0x0700, 0x1970, 0x0000 }, { 0x8700, 0x1973, 0x2000 }, { 0x0700, 0x1972, 0x0000 }, { 0x0700, 0x1974, 0x0000 }, { 0x9a00, 0x19e8, 0x4000 }, { 0x9a00, 0x19e4, 0x3000 }, { 0x9a00, 0x19e2, 0x2000 }, { 0x1a00, 0x19e1, 0x0000 }, { 0x1a00, 0x19e3, 0x0000 }, { 0x9a00, 0x19e6, 0x2000 }, { 0x1a00, 0x19e5, 0x0000 }, { 0x1a00, 0x19e7, 0x0000 }, { 0x9a00, 0x19ec, 0x3000 }, { 0x9a00, 0x19ea, 0x2000 }, { 0x1a00, 0x19e9, 0x0000 }, { 0x1a00, 0x19eb, 0x0000 }, { 0x9a00, 0x19ee, 0x2000 }, { 0x1a00, 0x19ed, 0x0000 }, { 0x1a00, 0x19ef, 0x0000 }, { 0x8500, 0x1d00, 0x5000 }, { 0x9a00, 0x19f8, 0x4000 }, { 0x9a00, 0x19f4, 0x3000 }, { 0x9a00, 0x19f2, 0x2000 }, { 0x1a00, 0x19f1, 0x0000 }, { 0x1a00, 0x19f3, 0x0000 }, { 0x9a00, 0x19f6, 0x2000 }, { 0x1a00, 0x19f5, 0x0000 }, { 0x1a00, 0x19f7, 0x0000 }, { 0x9a00, 0x19fc, 0x3000 }, { 0x9a00, 0x19fa, 0x2000 }, { 0x1a00, 0x19f9, 0x0000 }, { 0x1a00, 0x19fb, 0x0000 }, { 0x9a00, 0x19fe, 0x2000 }, { 0x1a00, 0x19fd, 0x0000 }, { 0x1a00, 0x19ff, 0x0000 }, { 0x8500, 0x1d08, 0x4000 }, { 0x8500, 0x1d04, 0x3000 }, { 0x8500, 0x1d02, 0x2000 }, { 0x0500, 0x1d01, 0x0000 }, { 0x0500, 0x1d03, 0x0000 }, { 0x8500, 0x1d06, 0x2000 }, { 0x0500, 0x1d05, 0x0000 }, { 0x0500, 0x1d07, 0x0000 }, { 0x8500, 0x1d0c, 0x3000 }, { 0x8500, 0x1d0a, 0x2000 }, { 0x0500, 0x1d09, 0x0000 }, { 0x0500, 0x1d0b, 0x0000 }, { 0x8500, 0x1d0e, 0x2000 }, { 0x0500, 0x1d0d, 0x0000 }, { 0x0500, 0x1d0f, 0x0000 }, { 0x8600, 0x1d50, 0x7000 }, { 0x8600, 0x1d30, 0x6000 }, { 0x8500, 0x1d20, 0x5000 }, { 0x8500, 0x1d18, 0x4000 }, { 0x8500, 0x1d14, 0x3000 }, { 0x8500, 0x1d12, 0x2000 }, { 0x0500, 0x1d11, 0x0000 }, { 0x0500, 0x1d13, 0x0000 }, { 0x8500, 0x1d16, 0x2000 }, { 0x0500, 0x1d15, 0x0000 }, { 0x0500, 0x1d17, 0x0000 }, { 0x8500, 0x1d1c, 0x3000 }, { 0x8500, 0x1d1a, 0x2000 }, { 0x0500, 0x1d19, 0x0000 }, { 0x0500, 0x1d1b, 0x0000 }, { 0x8500, 0x1d1e, 0x2000 }, { 0x0500, 0x1d1d, 0x0000 }, { 0x0500, 0x1d1f, 0x0000 }, { 0x8500, 0x1d28, 0x4000 }, { 0x8500, 0x1d24, 0x3000 }, { 0x8500, 0x1d22, 0x2000 }, { 0x0500, 0x1d21, 0x0000 }, { 0x0500, 0x1d23, 0x0000 }, { 0x8500, 0x1d26, 0x2000 }, { 0x0500, 0x1d25, 0x0000 }, { 0x0500, 0x1d27, 0x0000 }, { 0x8600, 0x1d2c, 0x3000 }, { 0x8500, 0x1d2a, 0x2000 }, { 0x0500, 0x1d29, 0x0000 }, { 0x0500, 0x1d2b, 0x0000 }, { 0x8600, 0x1d2e, 0x2000 }, { 0x0600, 0x1d2d, 0x0000 }, { 0x0600, 0x1d2f, 0x0000 }, { 0x8600, 0x1d40, 0x5000 }, { 0x8600, 0x1d38, 0x4000 }, { 0x8600, 0x1d34, 0x3000 }, { 0x8600, 0x1d32, 0x2000 }, { 0x0600, 0x1d31, 0x0000 }, { 0x0600, 0x1d33, 0x0000 }, { 0x8600, 0x1d36, 0x2000 }, { 0x0600, 0x1d35, 0x0000 }, { 0x0600, 0x1d37, 0x0000 }, { 0x8600, 0x1d3c, 0x3000 }, { 0x8600, 0x1d3a, 0x2000 }, { 0x0600, 0x1d39, 0x0000 }, { 0x0600, 0x1d3b, 0x0000 }, { 0x8600, 0x1d3e, 0x2000 }, { 0x0600, 0x1d3d, 0x0000 }, { 0x0600, 0x1d3f, 0x0000 }, { 0x8600, 0x1d48, 0x4000 }, { 0x8600, 0x1d44, 0x3000 }, { 0x8600, 0x1d42, 0x2000 }, { 0x0600, 0x1d41, 0x0000 }, { 0x0600, 0x1d43, 0x0000 }, { 0x8600, 0x1d46, 0x2000 }, { 0x0600, 0x1d45, 0x0000 }, { 0x0600, 0x1d47, 0x0000 }, { 0x8600, 0x1d4c, 0x3000 }, { 0x8600, 0x1d4a, 0x2000 }, { 0x0600, 0x1d49, 0x0000 }, { 0x0600, 0x1d4b, 0x0000 }, { 0x8600, 0x1d4e, 0x2000 }, { 0x0600, 0x1d4d, 0x0000 }, { 0x0600, 0x1d4f, 0x0000 }, { 0x8900, 0x1e04, 0x6001 }, { 0x8600, 0x1d60, 0x5000 }, { 0x8600, 0x1d58, 0x4000 }, { 0x8600, 0x1d54, 0x3000 }, { 0x8600, 0x1d52, 0x2000 }, { 0x0600, 0x1d51, 0x0000 }, { 0x0600, 0x1d53, 0x0000 }, { 0x8600, 0x1d56, 0x2000 }, { 0x0600, 0x1d55, 0x0000 }, { 0x0600, 0x1d57, 0x0000 }, { 0x8600, 0x1d5c, 0x3000 }, { 0x8600, 0x1d5a, 0x2000 }, { 0x0600, 0x1d59, 0x0000 }, { 0x0600, 0x1d5b, 0x0000 }, { 0x8600, 0x1d5e, 0x2000 }, { 0x0600, 0x1d5d, 0x0000 }, { 0x0600, 0x1d5f, 0x0000 }, { 0x8500, 0x1d68, 0x4000 }, { 0x8500, 0x1d64, 0x3000 }, { 0x8500, 0x1d62, 0x2000 }, { 0x0600, 0x1d61, 0x0000 }, { 0x0500, 0x1d63, 0x0000 }, { 0x8500, 0x1d66, 0x2000 }, { 0x0500, 0x1d65, 0x0000 }, { 0x0500, 0x1d67, 0x0000 }, { 0x8900, 0x1e00, 0x3001 }, { 0x8500, 0x1d6a, 0x2000 }, { 0x0500, 0x1d69, 0x0000 }, { 0x0500, 0x1d6b, 0x0000 }, { 0x8900, 0x1e02, 0x2001 }, { 0x0500, 0x1e01, 0x0fff }, { 0x0500, 0x1e03, 0x0fff }, { 0x8900, 0x1e14, 0x5001 }, { 0x8900, 0x1e0c, 0x4001 }, { 0x8900, 0x1e08, 0x3001 }, { 0x8900, 0x1e06, 0x2001 }, { 0x0500, 0x1e05, 0x0fff }, { 0x0500, 0x1e07, 0x0fff }, { 0x8900, 0x1e0a, 0x2001 }, { 0x0500, 0x1e09, 0x0fff }, { 0x0500, 0x1e0b, 0x0fff }, { 0x8900, 0x1e10, 0x3001 }, { 0x8900, 0x1e0e, 0x2001 }, { 0x0500, 0x1e0d, 0x0fff }, { 0x0500, 0x1e0f, 0x0fff }, { 0x8900, 0x1e12, 0x2001 }, { 0x0500, 0x1e11, 0x0fff }, { 0x0500, 0x1e13, 0x0fff }, { 0x8900, 0x1e1c, 0x4001 }, { 0x8900, 0x1e18, 0x3001 }, { 0x8900, 0x1e16, 0x2001 }, { 0x0500, 0x1e15, 0x0fff }, { 0x0500, 0x1e17, 0x0fff }, { 0x8900, 0x1e1a, 0x2001 }, { 0x0500, 0x1e19, 0x0fff }, { 0x0500, 0x1e1b, 0x0fff }, { 0x8900, 0x1e20, 0x3001 }, { 0x8900, 0x1e1e, 0x2001 }, { 0x0500, 0x1e1d, 0x0fff }, { 0x0500, 0x1e1f, 0x0fff }, { 0x8900, 0x1e22, 0x2001 }, { 0x0500, 0x1e21, 0x0fff }, { 0x0500, 0x1e23, 0x0fff }, { 0x9600, 0x2045, 0xa000 }, { 0x8500, 0x1f32, 0x9008 }, { 0x8900, 0x1ea8, 0x8001 }, { 0x8900, 0x1e64, 0x7001 }, { 0x8900, 0x1e44, 0x6001 }, { 0x8900, 0x1e34, 0x5001 }, { 0x8900, 0x1e2c, 0x4001 }, { 0x8900, 0x1e28, 0x3001 }, { 0x8900, 0x1e26, 0x2001 }, { 0x0500, 0x1e25, 0x0fff }, { 0x0500, 0x1e27, 0x0fff }, { 0x8900, 0x1e2a, 0x2001 }, { 0x0500, 0x1e29, 0x0fff }, { 0x0500, 0x1e2b, 0x0fff }, { 0x8900, 0x1e30, 0x3001 }, { 0x8900, 0x1e2e, 0x2001 }, { 0x0500, 0x1e2d, 0x0fff }, { 0x0500, 0x1e2f, 0x0fff }, { 0x8900, 0x1e32, 0x2001 }, { 0x0500, 0x1e31, 0x0fff }, { 0x0500, 0x1e33, 0x0fff }, { 0x8900, 0x1e3c, 0x4001 }, { 0x8900, 0x1e38, 0x3001 }, { 0x8900, 0x1e36, 0x2001 }, { 0x0500, 0x1e35, 0x0fff }, { 0x0500, 0x1e37, 0x0fff }, { 0x8900, 0x1e3a, 0x2001 }, { 0x0500, 0x1e39, 0x0fff }, { 0x0500, 0x1e3b, 0x0fff }, { 0x8900, 0x1e40, 0x3001 }, { 0x8900, 0x1e3e, 0x2001 }, { 0x0500, 0x1e3d, 0x0fff }, { 0x0500, 0x1e3f, 0x0fff }, { 0x8900, 0x1e42, 0x2001 }, { 0x0500, 0x1e41, 0x0fff }, { 0x0500, 0x1e43, 0x0fff }, { 0x8900, 0x1e54, 0x5001 }, { 0x8900, 0x1e4c, 0x4001 }, { 0x8900, 0x1e48, 0x3001 }, { 0x8900, 0x1e46, 0x2001 }, { 0x0500, 0x1e45, 0x0fff }, { 0x0500, 0x1e47, 0x0fff }, { 0x8900, 0x1e4a, 0x2001 }, { 0x0500, 0x1e49, 0x0fff }, { 0x0500, 0x1e4b, 0x0fff }, { 0x8900, 0x1e50, 0x3001 }, { 0x8900, 0x1e4e, 0x2001 }, { 0x0500, 0x1e4d, 0x0fff }, { 0x0500, 0x1e4f, 0x0fff }, { 0x8900, 0x1e52, 0x2001 }, { 0x0500, 0x1e51, 0x0fff }, { 0x0500, 0x1e53, 0x0fff }, { 0x8900, 0x1e5c, 0x4001 }, { 0x8900, 0x1e58, 0x3001 }, { 0x8900, 0x1e56, 0x2001 }, { 0x0500, 0x1e55, 0x0fff }, { 0x0500, 0x1e57, 0x0fff }, { 0x8900, 0x1e5a, 0x2001 }, { 0x0500, 0x1e59, 0x0fff }, { 0x0500, 0x1e5b, 0x0fff }, { 0x8900, 0x1e60, 0x3001 }, { 0x8900, 0x1e5e, 0x2001 }, { 0x0500, 0x1e5d, 0x0fff }, { 0x0500, 0x1e5f, 0x0fff }, { 0x8900, 0x1e62, 0x2001 }, { 0x0500, 0x1e61, 0x0fff }, { 0x0500, 0x1e63, 0x0fff }, { 0x8900, 0x1e84, 0x6001 }, { 0x8900, 0x1e74, 0x5001 }, { 0x8900, 0x1e6c, 0x4001 }, { 0x8900, 0x1e68, 0x3001 }, { 0x8900, 0x1e66, 0x2001 }, { 0x0500, 0x1e65, 0x0fff }, { 0x0500, 0x1e67, 0x0fff }, { 0x8900, 0x1e6a, 0x2001 }, { 0x0500, 0x1e69, 0x0fff }, { 0x0500, 0x1e6b, 0x0fff }, { 0x8900, 0x1e70, 0x3001 }, { 0x8900, 0x1e6e, 0x2001 }, { 0x0500, 0x1e6d, 0x0fff }, { 0x0500, 0x1e6f, 0x0fff }, { 0x8900, 0x1e72, 0x2001 }, { 0x0500, 0x1e71, 0x0fff }, { 0x0500, 0x1e73, 0x0fff }, { 0x8900, 0x1e7c, 0x4001 }, { 0x8900, 0x1e78, 0x3001 }, { 0x8900, 0x1e76, 0x2001 }, { 0x0500, 0x1e75, 0x0fff }, { 0x0500, 0x1e77, 0x0fff }, { 0x8900, 0x1e7a, 0x2001 }, { 0x0500, 0x1e79, 0x0fff }, { 0x0500, 0x1e7b, 0x0fff }, { 0x8900, 0x1e80, 0x3001 }, { 0x8900, 0x1e7e, 0x2001 }, { 0x0500, 0x1e7d, 0x0fff }, { 0x0500, 0x1e7f, 0x0fff }, { 0x8900, 0x1e82, 0x2001 }, { 0x0500, 0x1e81, 0x0fff }, { 0x0500, 0x1e83, 0x0fff }, { 0x8900, 0x1e94, 0x5001 }, { 0x8900, 0x1e8c, 0x4001 }, { 0x8900, 0x1e88, 0x3001 }, { 0x8900, 0x1e86, 0x2001 }, { 0x0500, 0x1e85, 0x0fff }, { 0x0500, 0x1e87, 0x0fff }, { 0x8900, 0x1e8a, 0x2001 }, { 0x0500, 0x1e89, 0x0fff }, { 0x0500, 0x1e8b, 0x0fff }, { 0x8900, 0x1e90, 0x3001 }, { 0x8900, 0x1e8e, 0x2001 }, { 0x0500, 0x1e8d, 0x0fff }, { 0x0500, 0x1e8f, 0x0fff }, { 0x8900, 0x1e92, 0x2001 }, { 0x0500, 0x1e91, 0x0fff }, { 0x0500, 0x1e93, 0x0fff }, { 0x8900, 0x1ea0, 0x4001 }, { 0x8500, 0x1e98, 0x3000 }, { 0x8500, 0x1e96, 0x2000 }, { 0x0500, 0x1e95, 0x0fff }, { 0x0500, 0x1e97, 0x0000 }, { 0x8500, 0x1e9a, 0x2000 }, { 0x0500, 0x1e99, 0x0000 }, { 0x0500, 0x1e9b, 0x0fc5 }, { 0x8900, 0x1ea4, 0x3001 }, { 0x8900, 0x1ea2, 0x2001 }, { 0x0500, 0x1ea1, 0x0fff }, { 0x0500, 0x1ea3, 0x0fff }, { 0x8900, 0x1ea6, 0x2001 }, { 0x0500, 0x1ea5, 0x0fff }, { 0x0500, 0x1ea7, 0x0fff }, { 0x8900, 0x1ee8, 0x7001 }, { 0x8900, 0x1ec8, 0x6001 }, { 0x8900, 0x1eb8, 0x5001 }, { 0x8900, 0x1eb0, 0x4001 }, { 0x8900, 0x1eac, 0x3001 }, { 0x8900, 0x1eaa, 0x2001 }, { 0x0500, 0x1ea9, 0x0fff }, { 0x0500, 0x1eab, 0x0fff }, { 0x8900, 0x1eae, 0x2001 }, { 0x0500, 0x1ead, 0x0fff }, { 0x0500, 0x1eaf, 0x0fff }, { 0x8900, 0x1eb4, 0x3001 }, { 0x8900, 0x1eb2, 0x2001 }, { 0x0500, 0x1eb1, 0x0fff }, { 0x0500, 0x1eb3, 0x0fff }, { 0x8900, 0x1eb6, 0x2001 }, { 0x0500, 0x1eb5, 0x0fff }, { 0x0500, 0x1eb7, 0x0fff }, { 0x8900, 0x1ec0, 0x4001 }, { 0x8900, 0x1ebc, 0x3001 }, { 0x8900, 0x1eba, 0x2001 }, { 0x0500, 0x1eb9, 0x0fff }, { 0x0500, 0x1ebb, 0x0fff }, { 0x8900, 0x1ebe, 0x2001 }, { 0x0500, 0x1ebd, 0x0fff }, { 0x0500, 0x1ebf, 0x0fff }, { 0x8900, 0x1ec4, 0x3001 }, { 0x8900, 0x1ec2, 0x2001 }, { 0x0500, 0x1ec1, 0x0fff }, { 0x0500, 0x1ec3, 0x0fff }, { 0x8900, 0x1ec6, 0x2001 }, { 0x0500, 0x1ec5, 0x0fff }, { 0x0500, 0x1ec7, 0x0fff }, { 0x8900, 0x1ed8, 0x5001 }, { 0x8900, 0x1ed0, 0x4001 }, { 0x8900, 0x1ecc, 0x3001 }, { 0x8900, 0x1eca, 0x2001 }, { 0x0500, 0x1ec9, 0x0fff }, { 0x0500, 0x1ecb, 0x0fff }, { 0x8900, 0x1ece, 0x2001 }, { 0x0500, 0x1ecd, 0x0fff }, { 0x0500, 0x1ecf, 0x0fff }, { 0x8900, 0x1ed4, 0x3001 }, { 0x8900, 0x1ed2, 0x2001 }, { 0x0500, 0x1ed1, 0x0fff }, { 0x0500, 0x1ed3, 0x0fff }, { 0x8900, 0x1ed6, 0x2001 }, { 0x0500, 0x1ed5, 0x0fff }, { 0x0500, 0x1ed7, 0x0fff }, { 0x8900, 0x1ee0, 0x4001 }, { 0x8900, 0x1edc, 0x3001 }, { 0x8900, 0x1eda, 0x2001 }, { 0x0500, 0x1ed9, 0x0fff }, { 0x0500, 0x1edb, 0x0fff }, { 0x8900, 0x1ede, 0x2001 }, { 0x0500, 0x1edd, 0x0fff }, { 0x0500, 0x1edf, 0x0fff }, { 0x8900, 0x1ee4, 0x3001 }, { 0x8900, 0x1ee2, 0x2001 }, { 0x0500, 0x1ee1, 0x0fff }, { 0x0500, 0x1ee3, 0x0fff }, { 0x8900, 0x1ee6, 0x2001 }, { 0x0500, 0x1ee5, 0x0fff }, { 0x0500, 0x1ee7, 0x0fff }, { 0x8900, 0x1f0e, 0x6ff8 }, { 0x8900, 0x1ef8, 0x5001 }, { 0x8900, 0x1ef0, 0x4001 }, { 0x8900, 0x1eec, 0x3001 }, { 0x8900, 0x1eea, 0x2001 }, { 0x0500, 0x1ee9, 0x0fff }, { 0x0500, 0x1eeb, 0x0fff }, { 0x8900, 0x1eee, 0x2001 }, { 0x0500, 0x1eed, 0x0fff }, { 0x0500, 0x1eef, 0x0fff }, { 0x8900, 0x1ef4, 0x3001 }, { 0x8900, 0x1ef2, 0x2001 }, { 0x0500, 0x1ef1, 0x0fff }, { 0x0500, 0x1ef3, 0x0fff }, { 0x8900, 0x1ef6, 0x2001 }, { 0x0500, 0x1ef5, 0x0fff }, { 0x0500, 0x1ef7, 0x0fff }, { 0x8500, 0x1f06, 0x4008 }, { 0x8500, 0x1f02, 0x3008 }, { 0x8500, 0x1f00, 0x2008 }, { 0x0500, 0x1ef9, 0x0fff }, { 0x0500, 0x1f01, 0x0008 }, { 0x8500, 0x1f04, 0x2008 }, { 0x0500, 0x1f03, 0x0008 }, { 0x0500, 0x1f05, 0x0008 }, { 0x8900, 0x1f0a, 0x3ff8 }, { 0x8900, 0x1f08, 0x2ff8 }, { 0x0500, 0x1f07, 0x0008 }, { 0x0900, 0x1f09, 0x0ff8 }, { 0x8900, 0x1f0c, 0x2ff8 }, { 0x0900, 0x1f0b, 0x0ff8 }, { 0x0900, 0x1f0d, 0x0ff8 }, { 0x8500, 0x1f22, 0x5008 }, { 0x8900, 0x1f18, 0x4ff8 }, { 0x8500, 0x1f12, 0x3008 }, { 0x8500, 0x1f10, 0x2008 }, { 0x0900, 0x1f0f, 0x0ff8 }, { 0x0500, 0x1f11, 0x0008 }, { 0x8500, 0x1f14, 0x2008 }, { 0x0500, 0x1f13, 0x0008 }, { 0x0500, 0x1f15, 0x0008 }, { 0x8900, 0x1f1c, 0x3ff8 }, { 0x8900, 0x1f1a, 0x2ff8 }, { 0x0900, 0x1f19, 0x0ff8 }, { 0x0900, 0x1f1b, 0x0ff8 }, { 0x8500, 0x1f20, 0x2008 }, { 0x0900, 0x1f1d, 0x0ff8 }, { 0x0500, 0x1f21, 0x0008 }, { 0x8900, 0x1f2a, 0x4ff8 }, { 0x8500, 0x1f26, 0x3008 }, { 0x8500, 0x1f24, 0x2008 }, { 0x0500, 0x1f23, 0x0008 }, { 0x0500, 0x1f25, 0x0008 }, { 0x8900, 0x1f28, 0x2ff8 }, { 0x0500, 0x1f27, 0x0008 }, { 0x0900, 0x1f29, 0x0ff8 }, { 0x8900, 0x1f2e, 0x3ff8 }, { 0x8900, 0x1f2c, 0x2ff8 }, { 0x0900, 0x1f2b, 0x0ff8 }, { 0x0900, 0x1f2d, 0x0ff8 }, { 0x8500, 0x1f30, 0x2008 }, { 0x0900, 0x1f2f, 0x0ff8 }, { 0x0500, 0x1f31, 0x0008 }, { 0x9800, 0x1fbd, 0x8000 }, { 0x8500, 0x1f7a, 0x7070 }, { 0x8500, 0x1f56, 0x6000 }, { 0x8500, 0x1f42, 0x5008 }, { 0x8900, 0x1f3a, 0x4ff8 }, { 0x8500, 0x1f36, 0x3008 }, { 0x8500, 0x1f34, 0x2008 }, { 0x0500, 0x1f33, 0x0008 }, { 0x0500, 0x1f35, 0x0008 }, { 0x8900, 0x1f38, 0x2ff8 }, { 0x0500, 0x1f37, 0x0008 }, { 0x0900, 0x1f39, 0x0ff8 }, { 0x8900, 0x1f3e, 0x3ff8 }, { 0x8900, 0x1f3c, 0x2ff8 }, { 0x0900, 0x1f3b, 0x0ff8 }, { 0x0900, 0x1f3d, 0x0ff8 }, { 0x8500, 0x1f40, 0x2008 }, { 0x0900, 0x1f3f, 0x0ff8 }, { 0x0500, 0x1f41, 0x0008 }, { 0x8900, 0x1f4c, 0x4ff8 }, { 0x8900, 0x1f48, 0x3ff8 }, { 0x8500, 0x1f44, 0x2008 }, { 0x0500, 0x1f43, 0x0008 }, { 0x0500, 0x1f45, 0x0008 }, { 0x8900, 0x1f4a, 0x2ff8 }, { 0x0900, 0x1f49, 0x0ff8 }, { 0x0900, 0x1f4b, 0x0ff8 }, { 0x8500, 0x1f52, 0x3000 }, { 0x8500, 0x1f50, 0x2000 }, { 0x0900, 0x1f4d, 0x0ff8 }, { 0x0500, 0x1f51, 0x0008 }, { 0x8500, 0x1f54, 0x2000 }, { 0x0500, 0x1f53, 0x0008 }, { 0x0500, 0x1f55, 0x0008 }, { 0x8900, 0x1f6a, 0x5ff8 }, { 0x8500, 0x1f62, 0x4008 }, { 0x8900, 0x1f5d, 0x3ff8 }, { 0x8900, 0x1f59, 0x2ff8 }, { 0x0500, 0x1f57, 0x0008 }, { 0x0900, 0x1f5b, 0x0ff8 }, { 0x8500, 0x1f60, 0x2008 }, { 0x0900, 0x1f5f, 0x0ff8 }, { 0x0500, 0x1f61, 0x0008 }, { 0x8500, 0x1f66, 0x3008 }, { 0x8500, 0x1f64, 0x2008 }, { 0x0500, 0x1f63, 0x0008 }, { 0x0500, 0x1f65, 0x0008 }, { 0x8900, 0x1f68, 0x2ff8 }, { 0x0500, 0x1f67, 0x0008 }, { 0x0900, 0x1f69, 0x0ff8 }, { 0x8500, 0x1f72, 0x4056 }, { 0x8900, 0x1f6e, 0x3ff8 }, { 0x8900, 0x1f6c, 0x2ff8 }, { 0x0900, 0x1f6b, 0x0ff8 }, { 0x0900, 0x1f6d, 0x0ff8 }, { 0x8500, 0x1f70, 0x204a }, { 0x0900, 0x1f6f, 0x0ff8 }, { 0x0500, 0x1f71, 0x004a }, { 0x8500, 0x1f76, 0x3064 }, { 0x8500, 0x1f74, 0x2056 }, { 0x0500, 0x1f73, 0x0056 }, { 0x0500, 0x1f75, 0x0056 }, { 0x8500, 0x1f78, 0x2080 }, { 0x0500, 0x1f77, 0x0064 }, { 0x0500, 0x1f79, 0x0080 }, { 0x8800, 0x1f9c, 0x6000 }, { 0x8800, 0x1f8c, 0x5000 }, { 0x8500, 0x1f84, 0x4008 }, { 0x8500, 0x1f80, 0x3008 }, { 0x8500, 0x1f7c, 0x207e }, { 0x0500, 0x1f7b, 0x0070 }, { 0x0500, 0x1f7d, 0x007e }, { 0x8500, 0x1f82, 0x2008 }, { 0x0500, 0x1f81, 0x0008 }, { 0x0500, 0x1f83, 0x0008 }, { 0x8800, 0x1f88, 0x3000 }, { 0x8500, 0x1f86, 0x2008 }, { 0x0500, 0x1f85, 0x0008 }, { 0x0500, 0x1f87, 0x0008 }, { 0x8800, 0x1f8a, 0x2000 }, { 0x0800, 0x1f89, 0x0000 }, { 0x0800, 0x1f8b, 0x0000 }, { 0x8500, 0x1f94, 0x4008 }, { 0x8500, 0x1f90, 0x3008 }, { 0x8800, 0x1f8e, 0x2000 }, { 0x0800, 0x1f8d, 0x0000 }, { 0x0800, 0x1f8f, 0x0000 }, { 0x8500, 0x1f92, 0x2008 }, { 0x0500, 0x1f91, 0x0008 }, { 0x0500, 0x1f93, 0x0008 }, { 0x8800, 0x1f98, 0x3000 }, { 0x8500, 0x1f96, 0x2008 }, { 0x0500, 0x1f95, 0x0008 }, { 0x0500, 0x1f97, 0x0008 }, { 0x8800, 0x1f9a, 0x2000 }, { 0x0800, 0x1f99, 0x0000 }, { 0x0800, 0x1f9b, 0x0000 }, { 0x8800, 0x1fac, 0x5000 }, { 0x8500, 0x1fa4, 0x4008 }, { 0x8500, 0x1fa0, 0x3008 }, { 0x8800, 0x1f9e, 0x2000 }, { 0x0800, 0x1f9d, 0x0000 }, { 0x0800, 0x1f9f, 0x0000 }, { 0x8500, 0x1fa2, 0x2008 }, { 0x0500, 0x1fa1, 0x0008 }, { 0x0500, 0x1fa3, 0x0008 }, { 0x8800, 0x1fa8, 0x3000 }, { 0x8500, 0x1fa6, 0x2008 }, { 0x0500, 0x1fa5, 0x0008 }, { 0x0500, 0x1fa7, 0x0008 }, { 0x8800, 0x1faa, 0x2000 }, { 0x0800, 0x1fa9, 0x0000 }, { 0x0800, 0x1fab, 0x0000 }, { 0x8500, 0x1fb4, 0x4000 }, { 0x8500, 0x1fb0, 0x3008 }, { 0x8800, 0x1fae, 0x2000 }, { 0x0800, 0x1fad, 0x0000 }, { 0x0800, 0x1faf, 0x0000 }, { 0x8500, 0x1fb2, 0x2000 }, { 0x0500, 0x1fb1, 0x0008 }, { 0x0500, 0x1fb3, 0x0009 }, { 0x8900, 0x1fb9, 0x3ff8 }, { 0x8500, 0x1fb7, 0x2000 }, { 0x0500, 0x1fb6, 0x0000 }, { 0x0900, 0x1fb8, 0x0ff8 }, { 0x8900, 0x1fbb, 0x2fb6 }, { 0x0900, 0x1fba, 0x0fb6 }, { 0x0800, 0x1fbc, 0x0000 }, { 0x9d00, 0x2005, 0x7000 }, { 0x8500, 0x1fe1, 0x6008 }, { 0x9800, 0x1fce, 0x5000 }, { 0x8500, 0x1fc6, 0x4000 }, { 0x9800, 0x1fc1, 0x3000 }, { 0x9800, 0x1fbf, 0x2000 }, { 0x0500, 0x1fbe, 0x0000 }, { 0x1800, 0x1fc0, 0x0000 }, { 0x8500, 0x1fc3, 0x2009 }, { 0x0500, 0x1fc2, 0x0000 }, { 0x0500, 0x1fc4, 0x0000 }, { 0x8900, 0x1fca, 0x3faa }, { 0x8900, 0x1fc8, 0x2faa }, { 0x0500, 0x1fc7, 0x0000 }, { 0x0900, 0x1fc9, 0x0faa }, { 0x8800, 0x1fcc, 0x2000 }, { 0x0900, 0x1fcb, 0x0faa }, { 0x1800, 0x1fcd, 0x0000 }, { 0x8900, 0x1fd8, 0x4ff8 }, { 0x8500, 0x1fd2, 0x3000 }, { 0x8500, 0x1fd0, 0x2008 }, { 0x1800, 0x1fcf, 0x0000 }, { 0x0500, 0x1fd1, 0x0008 }, { 0x8500, 0x1fd6, 0x2000 }, { 0x0500, 0x1fd3, 0x0000 }, { 0x0500, 0x1fd7, 0x0000 }, { 0x9800, 0x1fdd, 0x3000 }, { 0x8900, 0x1fda, 0x2f9c }, { 0x0900, 0x1fd9, 0x0ff8 }, { 0x0900, 0x1fdb, 0x0f9c }, { 0x9800, 0x1fdf, 0x2000 }, { 0x1800, 0x1fde, 0x0000 }, { 0x0500, 0x1fe0, 0x0008 }, { 0x8500, 0x1ff3, 0x5009 }, { 0x8900, 0x1fe9, 0x4ff8 }, { 0x8500, 0x1fe5, 0x3007 }, { 0x8500, 0x1fe3, 0x2000 }, { 0x0500, 0x1fe2, 0x0000 }, { 0x0500, 0x1fe4, 0x0000 }, { 0x8500, 0x1fe7, 0x2000 }, { 0x0500, 0x1fe6, 0x0000 }, { 0x0900, 0x1fe8, 0x0ff8 }, { 0x9800, 0x1fed, 0x3000 }, { 0x8900, 0x1feb, 0x2f90 }, { 0x0900, 0x1fea, 0x0f90 }, { 0x0900, 0x1fec, 0x0ff9 }, { 0x9800, 0x1fef, 0x2000 }, { 0x1800, 0x1fee, 0x0000 }, { 0x0500, 0x1ff2, 0x0000 }, { 0x8800, 0x1ffc, 0x4000 }, { 0x8900, 0x1ff8, 0x3f80 }, { 0x8500, 0x1ff6, 0x2000 }, { 0x0500, 0x1ff4, 0x0000 }, { 0x0500, 0x1ff7, 0x0000 }, { 0x8900, 0x1ffa, 0x2f82 }, { 0x0900, 0x1ff9, 0x0f80 }, { 0x0900, 0x1ffb, 0x0f82 }, { 0x9d00, 0x2001, 0x3000 }, { 0x9800, 0x1ffe, 0x2000 }, { 0x1800, 0x1ffd, 0x0000 }, { 0x1d00, 0x2000, 0x0000 }, { 0x9d00, 0x2003, 0x2000 }, { 0x1d00, 0x2002, 0x0000 }, { 0x1d00, 0x2004, 0x0000 }, { 0x9500, 0x2025, 0x6000 }, { 0x9100, 0x2015, 0x5000 }, { 0x8100, 0x200d, 0x4000 }, { 0x9d00, 0x2009, 0x3000 }, { 0x9d00, 0x2007, 0x2000 }, { 0x1d00, 0x2006, 0x0000 }, { 0x1d00, 0x2008, 0x0000 }, { 0x9d00, 0x200b, 0x2000 }, { 0x1d00, 0x200a, 0x0000 }, { 0x0100, 0x200c, 0x0000 }, { 0x9100, 0x2011, 0x3000 }, { 0x8100, 0x200f, 0x2000 }, { 0x0100, 0x200e, 0x0000 }, { 0x1100, 0x2010, 0x0000 }, { 0x9100, 0x2013, 0x2000 }, { 0x1100, 0x2012, 0x0000 }, { 0x1100, 0x2014, 0x0000 }, { 0x9300, 0x201d, 0x4000 }, { 0x9300, 0x2019, 0x3000 }, { 0x9500, 0x2017, 0x2000 }, { 0x1500, 0x2016, 0x0000 }, { 0x1400, 0x2018, 0x0000 }, { 0x9400, 0x201b, 0x2000 }, { 0x1600, 0x201a, 0x0000 }, { 0x1400, 0x201c, 0x0000 }, { 0x9500, 0x2021, 0x3000 }, { 0x9400, 0x201f, 0x2000 }, { 0x1600, 0x201e, 0x0000 }, { 0x1500, 0x2020, 0x0000 }, { 0x9500, 0x2023, 0x2000 }, { 0x1500, 0x2022, 0x0000 }, { 0x1500, 0x2024, 0x0000 }, { 0x9500, 0x2035, 0x5000 }, { 0x8100, 0x202d, 0x4000 }, { 0x9c00, 0x2029, 0x3000 }, { 0x9500, 0x2027, 0x2000 }, { 0x1500, 0x2026, 0x0000 }, { 0x1b00, 0x2028, 0x0000 }, { 0x8100, 0x202b, 0x2000 }, { 0x0100, 0x202a, 0x0000 }, { 0x0100, 0x202c, 0x0000 }, { 0x9500, 0x2031, 0x3000 }, { 0x9d00, 0x202f, 0x2000 }, { 0x0100, 0x202e, 0x0000 }, { 0x1500, 0x2030, 0x0000 }, { 0x9500, 0x2033, 0x2000 }, { 0x1500, 0x2032, 0x0000 }, { 0x1500, 0x2034, 0x0000 }, { 0x9500, 0x203d, 0x4000 }, { 0x9400, 0x2039, 0x3000 }, { 0x9500, 0x2037, 0x2000 }, { 0x1500, 0x2036, 0x0000 }, { 0x1500, 0x2038, 0x0000 }, { 0x9500, 0x203b, 0x2000 }, { 0x1300, 0x203a, 0x0000 }, { 0x1500, 0x203c, 0x0000 }, { 0x9500, 0x2041, 0x3000 }, { 0x9000, 0x203f, 0x2000 }, { 0x1500, 0x203e, 0x0000 }, { 0x1000, 0x2040, 0x0000 }, { 0x9500, 0x2043, 0x2000 }, { 0x1500, 0x2042, 0x0000 }, { 0x1900, 0x2044, 0x0000 }, { 0x9900, 0x21ae, 0x9000 }, { 0x8900, 0x211a, 0x8000 }, { 0x9700, 0x20a7, 0x7000 }, { 0x8f00, 0x2076, 0x6000 }, { 0x9500, 0x2057, 0x5000 }, { 0x9500, 0x204d, 0x4000 }, { 0x9500, 0x2049, 0x3000 }, { 0x9500, 0x2047, 0x2000 }, { 0x1200, 0x2046, 0x0000 }, { 0x1500, 0x2048, 0x0000 }, { 0x9500, 0x204b, 0x2000 }, { 0x1500, 0x204a, 0x0000 }, { 0x1500, 0x204c, 0x0000 }, { 0x9500, 0x2051, 0x3000 }, { 0x9500, 0x204f, 0x2000 }, { 0x1500, 0x204e, 0x0000 }, { 0x1500, 0x2050, 0x0000 }, { 0x9500, 0x2053, 0x2000 }, { 0x1900, 0x2052, 0x0000 }, { 0x1000, 0x2054, 0x0000 }, { 0x8100, 0x206c, 0x4000 }, { 0x8100, 0x2062, 0x3000 }, { 0x8100, 0x2060, 0x2000 }, { 0x1d00, 0x205f, 0x0000 }, { 0x0100, 0x2061, 0x0000 }, { 0x8100, 0x206a, 0x2000 }, { 0x0100, 0x2063, 0x0000 }, { 0x0100, 0x206b, 0x0000 }, { 0x8f00, 0x2070, 0x3000 }, { 0x8100, 0x206e, 0x2000 }, { 0x0100, 0x206d, 0x0000 }, { 0x0100, 0x206f, 0x0000 }, { 0x8f00, 0x2074, 0x2000 }, { 0x0500, 0x2071, 0x0000 }, { 0x0f00, 0x2075, 0x0000 }, { 0x8f00, 0x2086, 0x5000 }, { 0x9200, 0x207e, 0x4000 }, { 0x9900, 0x207a, 0x3000 }, { 0x8f00, 0x2078, 0x2000 }, { 0x0f00, 0x2077, 0x0000 }, { 0x0f00, 0x2079, 0x0000 }, { 0x9900, 0x207c, 0x2000 }, { 0x1900, 0x207b, 0x0000 }, { 0x1600, 0x207d, 0x0000 }, { 0x8f00, 0x2082, 0x3000 }, { 0x8f00, 0x2080, 0x2000 }, { 0x0500, 0x207f, 0x0000 }, { 0x0f00, 0x2081, 0x0000 }, { 0x8f00, 0x2084, 0x2000 }, { 0x0f00, 0x2083, 0x0000 }, { 0x0f00, 0x2085, 0x0000 }, { 0x9200, 0x208e, 0x4000 }, { 0x9900, 0x208a, 0x3000 }, { 0x8f00, 0x2088, 0x2000 }, { 0x0f00, 0x2087, 0x0000 }, { 0x0f00, 0x2089, 0x0000 }, { 0x9900, 0x208c, 0x2000 }, { 0x1900, 0x208b, 0x0000 }, { 0x1600, 0x208d, 0x0000 }, { 0x9700, 0x20a3, 0x3000 }, { 0x9700, 0x20a1, 0x2000 }, { 0x1700, 0x20a0, 0x0000 }, { 0x1700, 0x20a2, 0x0000 }, { 0x9700, 0x20a5, 0x2000 }, { 0x1700, 0x20a4, 0x0000 }, { 0x1700, 0x20a6, 0x0000 }, { 0x8c00, 0x20e5, 0x6000 }, { 0x8c00, 0x20d5, 0x5000 }, { 0x9700, 0x20af, 0x4000 }, { 0x9700, 0x20ab, 0x3000 }, { 0x9700, 0x20a9, 0x2000 }, { 0x1700, 0x20a8, 0x0000 }, { 0x1700, 0x20aa, 0x0000 }, { 0x9700, 0x20ad, 0x2000 }, { 0x1700, 0x20ac, 0x0000 }, { 0x1700, 0x20ae, 0x0000 }, { 0x8c00, 0x20d1, 0x3000 }, { 0x9700, 0x20b1, 0x2000 }, { 0x1700, 0x20b0, 0x0000 }, { 0x0c00, 0x20d0, 0x0000 }, { 0x8c00, 0x20d3, 0x2000 }, { 0x0c00, 0x20d2, 0x0000 }, { 0x0c00, 0x20d4, 0x0000 }, { 0x8b00, 0x20dd, 0x4000 }, { 0x8c00, 0x20d9, 0x3000 }, { 0x8c00, 0x20d7, 0x2000 }, { 0x0c00, 0x20d6, 0x0000 }, { 0x0c00, 0x20d8, 0x0000 }, { 0x8c00, 0x20db, 0x2000 }, { 0x0c00, 0x20da, 0x0000 }, { 0x0c00, 0x20dc, 0x0000 }, { 0x8c00, 0x20e1, 0x3000 }, { 0x8b00, 0x20df, 0x2000 }, { 0x0b00, 0x20de, 0x0000 }, { 0x0b00, 0x20e0, 0x0000 }, { 0x8b00, 0x20e3, 0x2000 }, { 0x0b00, 0x20e2, 0x0000 }, { 0x0b00, 0x20e4, 0x0000 }, { 0x8500, 0x210a, 0x5000 }, { 0x8900, 0x2102, 0x4000 }, { 0x8c00, 0x20e9, 0x3000 }, { 0x8c00, 0x20e7, 0x2000 }, { 0x0c00, 0x20e6, 0x0000 }, { 0x0c00, 0x20e8, 0x0000 }, { 0x9a00, 0x2100, 0x2000 }, { 0x0c00, 0x20ea, 0x0000 }, { 0x1a00, 0x2101, 0x0000 }, { 0x9a00, 0x2106, 0x3000 }, { 0x9a00, 0x2104, 0x2000 }, { 0x1a00, 0x2103, 0x0000 }, { 0x1a00, 0x2105, 0x0000 }, { 0x9a00, 0x2108, 0x2000 }, { 0x0900, 0x2107, 0x0000 }, { 0x1a00, 0x2109, 0x0000 }, { 0x8900, 0x2112, 0x4000 }, { 0x8500, 0x210e, 0x3000 }, { 0x8900, 0x210c, 0x2000 }, { 0x0900, 0x210b, 0x0000 }, { 0x0900, 0x210d, 0x0000 }, { 0x8900, 0x2110, 0x2000 }, { 0x0500, 0x210f, 0x0000 }, { 0x0900, 0x2111, 0x0000 }, { 0x9a00, 0x2116, 0x3000 }, { 0x9a00, 0x2114, 0x2000 }, { 0x0500, 0x2113, 0x0000 }, { 0x0900, 0x2115, 0x0000 }, { 0x9a00, 0x2118, 0x2000 }, { 0x1a00, 0x2117, 0x0000 }, { 0x0900, 0x2119, 0x0000 }, { 0x8e00, 0x2162, 0x7000 }, { 0x9a00, 0x213a, 0x6000 }, { 0x8900, 0x212a, 0x5000 }, { 0x9a00, 0x2122, 0x4000 }, { 0x9a00, 0x211e, 0x3000 }, { 0x8900, 0x211c, 0x2000 }, { 0x0900, 0x211b, 0x0000 }, { 0x0900, 0x211d, 0x0000 }, { 0x9a00, 0x2120, 0x2000 }, { 0x1a00, 0x211f, 0x0000 }, { 0x1a00, 0x2121, 0x0000 }, { 0x8900, 0x2126, 0x3000 }, { 0x8900, 0x2124, 0x2000 }, { 0x1a00, 0x2123, 0x0000 }, { 0x1a00, 0x2125, 0x0000 }, { 0x8900, 0x2128, 0x2000 }, { 0x1a00, 0x2127, 0x0000 }, { 0x1a00, 0x2129, 0x0000 }, { 0x9a00, 0x2132, 0x4000 }, { 0x9a00, 0x212e, 0x3000 }, { 0x8900, 0x212c, 0x2000 }, { 0x0900, 0x212b, 0x0000 }, { 0x0900, 0x212d, 0x0000 }, { 0x8900, 0x2130, 0x2000 }, { 0x0500, 0x212f, 0x0000 }, { 0x0900, 0x2131, 0x0000 }, { 0x8700, 0x2136, 0x3000 }, { 0x8500, 0x2134, 0x2000 }, { 0x0900, 0x2133, 0x0000 }, { 0x0700, 0x2135, 0x0000 }, { 0x8700, 0x2138, 0x2000 }, { 0x0700, 0x2137, 0x0000 }, { 0x0500, 0x2139, 0x0000 }, { 0x9900, 0x214b, 0x5000 }, { 0x9900, 0x2143, 0x4000 }, { 0x8900, 0x213f, 0x3000 }, { 0x8500, 0x213d, 0x2000 }, { 0x1a00, 0x213b, 0x0000 }, { 0x0900, 0x213e, 0x0000 }, { 0x9900, 0x2141, 0x2000 }, { 0x1900, 0x2140, 0x0000 }, { 0x1900, 0x2142, 0x0000 }, { 0x8500, 0x2147, 0x3000 }, { 0x8900, 0x2145, 0x2000 }, { 0x1900, 0x2144, 0x0000 }, { 0x0500, 0x2146, 0x0000 }, { 0x8500, 0x2149, 0x2000 }, { 0x0500, 0x2148, 0x0000 }, { 0x1a00, 0x214a, 0x0000 }, { 0x8f00, 0x215a, 0x4000 }, { 0x8f00, 0x2156, 0x3000 }, { 0x8f00, 0x2154, 0x2000 }, { 0x0f00, 0x2153, 0x0000 }, { 0x0f00, 0x2155, 0x0000 }, { 0x8f00, 0x2158, 0x2000 }, { 0x0f00, 0x2157, 0x0000 }, { 0x0f00, 0x2159, 0x0000 }, { 0x8f00, 0x215e, 0x3000 }, { 0x8f00, 0x215c, 0x2000 }, { 0x0f00, 0x215b, 0x0000 }, { 0x0f00, 0x215d, 0x0000 }, { 0x8e00, 0x2160, 0x2000 }, { 0x0f00, 0x215f, 0x0000 }, { 0x0e00, 0x2161, 0x0000 }, { 0x8e00, 0x2182, 0x6000 }, { 0x8e00, 0x2172, 0x5000 }, { 0x8e00, 0x216a, 0x4000 }, { 0x8e00, 0x2166, 0x3000 }, { 0x8e00, 0x2164, 0x2000 }, { 0x0e00, 0x2163, 0x0000 }, { 0x0e00, 0x2165, 0x0000 }, { 0x8e00, 0x2168, 0x2000 }, { 0x0e00, 0x2167, 0x0000 }, { 0x0e00, 0x2169, 0x0000 }, { 0x8e00, 0x216e, 0x3000 }, { 0x8e00, 0x216c, 0x2000 }, { 0x0e00, 0x216b, 0x0000 }, { 0x0e00, 0x216d, 0x0000 }, { 0x8e00, 0x2170, 0x2000 }, { 0x0e00, 0x216f, 0x0000 }, { 0x0e00, 0x2171, 0x0000 }, { 0x8e00, 0x217a, 0x4000 }, { 0x8e00, 0x2176, 0x3000 }, { 0x8e00, 0x2174, 0x2000 }, { 0x0e00, 0x2173, 0x0000 }, { 0x0e00, 0x2175, 0x0000 }, { 0x8e00, 0x2178, 0x2000 }, { 0x0e00, 0x2177, 0x0000 }, { 0x0e00, 0x2179, 0x0000 }, { 0x8e00, 0x217e, 0x3000 }, { 0x8e00, 0x217c, 0x2000 }, { 0x0e00, 0x217b, 0x0000 }, { 0x0e00, 0x217d, 0x0000 }, { 0x8e00, 0x2180, 0x2000 }, { 0x0e00, 0x217f, 0x0000 }, { 0x0e00, 0x2181, 0x0000 }, { 0x9a00, 0x219e, 0x5000 }, { 0x9a00, 0x2196, 0x4000 }, { 0x9900, 0x2192, 0x3000 }, { 0x9900, 0x2190, 0x2000 }, { 0x0e00, 0x2183, 0x0000 }, { 0x1900, 0x2191, 0x0000 }, { 0x9900, 0x2194, 0x2000 }, { 0x1900, 0x2193, 0x0000 }, { 0x1a00, 0x2195, 0x0000 }, { 0x9900, 0x219a, 0x3000 }, { 0x9a00, 0x2198, 0x2000 }, { 0x1a00, 0x2197, 0x0000 }, { 0x1a00, 0x2199, 0x0000 }, { 0x9a00, 0x219c, 0x2000 }, { 0x1900, 0x219b, 0x0000 }, { 0x1a00, 0x219d, 0x0000 }, { 0x9900, 0x21a6, 0x4000 }, { 0x9a00, 0x21a2, 0x3000 }, { 0x9900, 0x21a0, 0x2000 }, { 0x1a00, 0x219f, 0x0000 }, { 0x1a00, 0x21a1, 0x0000 }, { 0x9a00, 0x21a4, 0x2000 }, { 0x1900, 0x21a3, 0x0000 }, { 0x1a00, 0x21a5, 0x0000 }, { 0x9a00, 0x21aa, 0x3000 }, { 0x9a00, 0x21a8, 0x2000 }, { 0x1a00, 0x21a7, 0x0000 }, { 0x1a00, 0x21a9, 0x0000 }, { 0x9a00, 0x21ac, 0x2000 }, { 0x1a00, 0x21ab, 0x0000 }, { 0x1a00, 0x21ad, 0x0000 }, { 0x9900, 0x222e, 0x8000 }, { 0x9a00, 0x21ee, 0x7000 }, { 0x9900, 0x21ce, 0x6000 }, { 0x9a00, 0x21be, 0x5000 }, { 0x9a00, 0x21b6, 0x4000 }, { 0x9a00, 0x21b2, 0x3000 }, { 0x9a00, 0x21b0, 0x2000 }, { 0x1a00, 0x21af, 0x0000 }, { 0x1a00, 0x21b1, 0x0000 }, { 0x9a00, 0x21b4, 0x2000 }, { 0x1a00, 0x21b3, 0x0000 }, { 0x1a00, 0x21b5, 0x0000 }, { 0x9a00, 0x21ba, 0x3000 }, { 0x9a00, 0x21b8, 0x2000 }, { 0x1a00, 0x21b7, 0x0000 }, { 0x1a00, 0x21b9, 0x0000 }, { 0x9a00, 0x21bc, 0x2000 }, { 0x1a00, 0x21bb, 0x0000 }, { 0x1a00, 0x21bd, 0x0000 }, { 0x9a00, 0x21c6, 0x4000 }, { 0x9a00, 0x21c2, 0x3000 }, { 0x9a00, 0x21c0, 0x2000 }, { 0x1a00, 0x21bf, 0x0000 }, { 0x1a00, 0x21c1, 0x0000 }, { 0x9a00, 0x21c4, 0x2000 }, { 0x1a00, 0x21c3, 0x0000 }, { 0x1a00, 0x21c5, 0x0000 }, { 0x9a00, 0x21ca, 0x3000 }, { 0x9a00, 0x21c8, 0x2000 }, { 0x1a00, 0x21c7, 0x0000 }, { 0x1a00, 0x21c9, 0x0000 }, { 0x9a00, 0x21cc, 0x2000 }, { 0x1a00, 0x21cb, 0x0000 }, { 0x1a00, 0x21cd, 0x0000 }, { 0x9a00, 0x21de, 0x5000 }, { 0x9a00, 0x21d6, 0x4000 }, { 0x9900, 0x21d2, 0x3000 }, { 0x9a00, 0x21d0, 0x2000 }, { 0x1900, 0x21cf, 0x0000 }, { 0x1a00, 0x21d1, 0x0000 }, { 0x9900, 0x21d4, 0x2000 }, { 0x1a00, 0x21d3, 0x0000 }, { 0x1a00, 0x21d5, 0x0000 }, { 0x9a00, 0x21da, 0x3000 }, { 0x9a00, 0x21d8, 0x2000 }, { 0x1a00, 0x21d7, 0x0000 }, { 0x1a00, 0x21d9, 0x0000 }, { 0x9a00, 0x21dc, 0x2000 }, { 0x1a00, 0x21db, 0x0000 }, { 0x1a00, 0x21dd, 0x0000 }, { 0x9a00, 0x21e6, 0x4000 }, { 0x9a00, 0x21e2, 0x3000 }, { 0x9a00, 0x21e0, 0x2000 }, { 0x1a00, 0x21df, 0x0000 }, { 0x1a00, 0x21e1, 0x0000 }, { 0x9a00, 0x21e4, 0x2000 }, { 0x1a00, 0x21e3, 0x0000 }, { 0x1a00, 0x21e5, 0x0000 }, { 0x9a00, 0x21ea, 0x3000 }, { 0x9a00, 0x21e8, 0x2000 }, { 0x1a00, 0x21e7, 0x0000 }, { 0x1a00, 0x21e9, 0x0000 }, { 0x9a00, 0x21ec, 0x2000 }, { 0x1a00, 0x21eb, 0x0000 }, { 0x1a00, 0x21ed, 0x0000 }, { 0x9900, 0x220e, 0x6000 }, { 0x9900, 0x21fe, 0x5000 }, { 0x9900, 0x21f6, 0x4000 }, { 0x9a00, 0x21f2, 0x3000 }, { 0x9a00, 0x21f0, 0x2000 }, { 0x1a00, 0x21ef, 0x0000 }, { 0x1a00, 0x21f1, 0x0000 }, { 0x9900, 0x21f4, 0x2000 }, { 0x1a00, 0x21f3, 0x0000 }, { 0x1900, 0x21f5, 0x0000 }, { 0x9900, 0x21fa, 0x3000 }, { 0x9900, 0x21f8, 0x2000 }, { 0x1900, 0x21f7, 0x0000 }, { 0x1900, 0x21f9, 0x0000 }, { 0x9900, 0x21fc, 0x2000 }, { 0x1900, 0x21fb, 0x0000 }, { 0x1900, 0x21fd, 0x0000 }, { 0x9900, 0x2206, 0x4000 }, { 0x9900, 0x2202, 0x3000 }, { 0x9900, 0x2200, 0x2000 }, { 0x1900, 0x21ff, 0x0000 }, { 0x1900, 0x2201, 0x0000 }, { 0x9900, 0x2204, 0x2000 }, { 0x1900, 0x2203, 0x0000 }, { 0x1900, 0x2205, 0x0000 }, { 0x9900, 0x220a, 0x3000 }, { 0x9900, 0x2208, 0x2000 }, { 0x1900, 0x2207, 0x0000 }, { 0x1900, 0x2209, 0x0000 }, { 0x9900, 0x220c, 0x2000 }, { 0x1900, 0x220b, 0x0000 }, { 0x1900, 0x220d, 0x0000 }, { 0x9900, 0x221e, 0x5000 }, { 0x9900, 0x2216, 0x4000 }, { 0x9900, 0x2212, 0x3000 }, { 0x9900, 0x2210, 0x2000 }, { 0x1900, 0x220f, 0x0000 }, { 0x1900, 0x2211, 0x0000 }, { 0x9900, 0x2214, 0x2000 }, { 0x1900, 0x2213, 0x0000 }, { 0x1900, 0x2215, 0x0000 }, { 0x9900, 0x221a, 0x3000 }, { 0x9900, 0x2218, 0x2000 }, { 0x1900, 0x2217, 0x0000 }, { 0x1900, 0x2219, 0x0000 }, { 0x9900, 0x221c, 0x2000 }, { 0x1900, 0x221b, 0x0000 }, { 0x1900, 0x221d, 0x0000 }, { 0x9900, 0x2226, 0x4000 }, { 0x9900, 0x2222, 0x3000 }, { 0x9900, 0x2220, 0x2000 }, { 0x1900, 0x221f, 0x0000 }, { 0x1900, 0x2221, 0x0000 }, { 0x9900, 0x2224, 0x2000 }, { 0x1900, 0x2223, 0x0000 }, { 0x1900, 0x2225, 0x0000 }, { 0x9900, 0x222a, 0x3000 }, { 0x9900, 0x2228, 0x2000 }, { 0x1900, 0x2227, 0x0000 }, { 0x1900, 0x2229, 0x0000 }, { 0x9900, 0x222c, 0x2000 }, { 0x1900, 0x222b, 0x0000 }, { 0x1900, 0x222d, 0x0000 }, { 0x9900, 0x226e, 0x7000 }, { 0x9900, 0x224e, 0x6000 }, { 0x9900, 0x223e, 0x5000 }, { 0x9900, 0x2236, 0x4000 }, { 0x9900, 0x2232, 0x3000 }, { 0x9900, 0x2230, 0x2000 }, { 0x1900, 0x222f, 0x0000 }, { 0x1900, 0x2231, 0x0000 }, { 0x9900, 0x2234, 0x2000 }, { 0x1900, 0x2233, 0x0000 }, { 0x1900, 0x2235, 0x0000 }, { 0x9900, 0x223a, 0x3000 }, { 0x9900, 0x2238, 0x2000 }, { 0x1900, 0x2237, 0x0000 }, { 0x1900, 0x2239, 0x0000 }, { 0x9900, 0x223c, 0x2000 }, { 0x1900, 0x223b, 0x0000 }, { 0x1900, 0x223d, 0x0000 }, { 0x9900, 0x2246, 0x4000 }, { 0x9900, 0x2242, 0x3000 }, { 0x9900, 0x2240, 0x2000 }, { 0x1900, 0x223f, 0x0000 }, { 0x1900, 0x2241, 0x0000 }, { 0x9900, 0x2244, 0x2000 }, { 0x1900, 0x2243, 0x0000 }, { 0x1900, 0x2245, 0x0000 }, { 0x9900, 0x224a, 0x3000 }, { 0x9900, 0x2248, 0x2000 }, { 0x1900, 0x2247, 0x0000 }, { 0x1900, 0x2249, 0x0000 }, { 0x9900, 0x224c, 0x2000 }, { 0x1900, 0x224b, 0x0000 }, { 0x1900, 0x224d, 0x0000 }, { 0x9900, 0x225e, 0x5000 }, { 0x9900, 0x2256, 0x4000 }, { 0x9900, 0x2252, 0x3000 }, { 0x9900, 0x2250, 0x2000 }, { 0x1900, 0x224f, 0x0000 }, { 0x1900, 0x2251, 0x0000 }, { 0x9900, 0x2254, 0x2000 }, { 0x1900, 0x2253, 0x0000 }, { 0x1900, 0x2255, 0x0000 }, { 0x9900, 0x225a, 0x3000 }, { 0x9900, 0x2258, 0x2000 }, { 0x1900, 0x2257, 0x0000 }, { 0x1900, 0x2259, 0x0000 }, { 0x9900, 0x225c, 0x2000 }, { 0x1900, 0x225b, 0x0000 }, { 0x1900, 0x225d, 0x0000 }, { 0x9900, 0x2266, 0x4000 }, { 0x9900, 0x2262, 0x3000 }, { 0x9900, 0x2260, 0x2000 }, { 0x1900, 0x225f, 0x0000 }, { 0x1900, 0x2261, 0x0000 }, { 0x9900, 0x2264, 0x2000 }, { 0x1900, 0x2263, 0x0000 }, { 0x1900, 0x2265, 0x0000 }, { 0x9900, 0x226a, 0x3000 }, { 0x9900, 0x2268, 0x2000 }, { 0x1900, 0x2267, 0x0000 }, { 0x1900, 0x2269, 0x0000 }, { 0x9900, 0x226c, 0x2000 }, { 0x1900, 0x226b, 0x0000 }, { 0x1900, 0x226d, 0x0000 }, { 0x9900, 0x228e, 0x6000 }, { 0x9900, 0x227e, 0x5000 }, { 0x9900, 0x2276, 0x4000 }, { 0x9900, 0x2272, 0x3000 }, { 0x9900, 0x2270, 0x2000 }, { 0x1900, 0x226f, 0x0000 }, { 0x1900, 0x2271, 0x0000 }, { 0x9900, 0x2274, 0x2000 }, { 0x1900, 0x2273, 0x0000 }, { 0x1900, 0x2275, 0x0000 }, { 0x9900, 0x227a, 0x3000 }, { 0x9900, 0x2278, 0x2000 }, { 0x1900, 0x2277, 0x0000 }, { 0x1900, 0x2279, 0x0000 }, { 0x9900, 0x227c, 0x2000 }, { 0x1900, 0x227b, 0x0000 }, { 0x1900, 0x227d, 0x0000 }, { 0x9900, 0x2286, 0x4000 }, { 0x9900, 0x2282, 0x3000 }, { 0x9900, 0x2280, 0x2000 }, { 0x1900, 0x227f, 0x0000 }, { 0x1900, 0x2281, 0x0000 }, { 0x9900, 0x2284, 0x2000 }, { 0x1900, 0x2283, 0x0000 }, { 0x1900, 0x2285, 0x0000 }, { 0x9900, 0x228a, 0x3000 }, { 0x9900, 0x2288, 0x2000 }, { 0x1900, 0x2287, 0x0000 }, { 0x1900, 0x2289, 0x0000 }, { 0x9900, 0x228c, 0x2000 }, { 0x1900, 0x228b, 0x0000 }, { 0x1900, 0x228d, 0x0000 }, { 0x9900, 0x229e, 0x5000 }, { 0x9900, 0x2296, 0x4000 }, { 0x9900, 0x2292, 0x3000 }, { 0x9900, 0x2290, 0x2000 }, { 0x1900, 0x228f, 0x0000 }, { 0x1900, 0x2291, 0x0000 }, { 0x9900, 0x2294, 0x2000 }, { 0x1900, 0x2293, 0x0000 }, { 0x1900, 0x2295, 0x0000 }, { 0x9900, 0x229a, 0x3000 }, { 0x9900, 0x2298, 0x2000 }, { 0x1900, 0x2297, 0x0000 }, { 0x1900, 0x2299, 0x0000 }, { 0x9900, 0x229c, 0x2000 }, { 0x1900, 0x229b, 0x0000 }, { 0x1900, 0x229d, 0x0000 }, { 0x9900, 0x22a6, 0x4000 }, { 0x9900, 0x22a2, 0x3000 }, { 0x9900, 0x22a0, 0x2000 }, { 0x1900, 0x229f, 0x0000 }, { 0x1900, 0x22a1, 0x0000 }, { 0x9900, 0x22a4, 0x2000 }, { 0x1900, 0x22a3, 0x0000 }, { 0x1900, 0x22a5, 0x0000 }, { 0x9900, 0x22aa, 0x3000 }, { 0x9900, 0x22a8, 0x2000 }, { 0x1900, 0x22a7, 0x0000 }, { 0x1900, 0x22a9, 0x0000 }, { 0x9900, 0x22ac, 0x2000 }, { 0x1900, 0x22ab, 0x0000 }, { 0x1900, 0x22ad, 0x0000 }, { 0x8f00, 0x2787, 0xb000 }, { 0x9a00, 0x250b, 0xa000 }, { 0x9900, 0x23ae, 0x9000 }, { 0x9a00, 0x232e, 0x8000 }, { 0x9900, 0x22ee, 0x7000 }, { 0x9900, 0x22ce, 0x6000 }, { 0x9900, 0x22be, 0x5000 }, { 0x9900, 0x22b6, 0x4000 }, { 0x9900, 0x22b2, 0x3000 }, { 0x9900, 0x22b0, 0x2000 }, { 0x1900, 0x22af, 0x0000 }, { 0x1900, 0x22b1, 0x0000 }, { 0x9900, 0x22b4, 0x2000 }, { 0x1900, 0x22b3, 0x0000 }, { 0x1900, 0x22b5, 0x0000 }, { 0x9900, 0x22ba, 0x3000 }, { 0x9900, 0x22b8, 0x2000 }, { 0x1900, 0x22b7, 0x0000 }, { 0x1900, 0x22b9, 0x0000 }, { 0x9900, 0x22bc, 0x2000 }, { 0x1900, 0x22bb, 0x0000 }, { 0x1900, 0x22bd, 0x0000 }, { 0x9900, 0x22c6, 0x4000 }, { 0x9900, 0x22c2, 0x3000 }, { 0x9900, 0x22c0, 0x2000 }, { 0x1900, 0x22bf, 0x0000 }, { 0x1900, 0x22c1, 0x0000 }, { 0x9900, 0x22c4, 0x2000 }, { 0x1900, 0x22c3, 0x0000 }, { 0x1900, 0x22c5, 0x0000 }, { 0x9900, 0x22ca, 0x3000 }, { 0x9900, 0x22c8, 0x2000 }, { 0x1900, 0x22c7, 0x0000 }, { 0x1900, 0x22c9, 0x0000 }, { 0x9900, 0x22cc, 0x2000 }, { 0x1900, 0x22cb, 0x0000 }, { 0x1900, 0x22cd, 0x0000 }, { 0x9900, 0x22de, 0x5000 }, { 0x9900, 0x22d6, 0x4000 }, { 0x9900, 0x22d2, 0x3000 }, { 0x9900, 0x22d0, 0x2000 }, { 0x1900, 0x22cf, 0x0000 }, { 0x1900, 0x22d1, 0x0000 }, { 0x9900, 0x22d4, 0x2000 }, { 0x1900, 0x22d3, 0x0000 }, { 0x1900, 0x22d5, 0x0000 }, { 0x9900, 0x22da, 0x3000 }, { 0x9900, 0x22d8, 0x2000 }, { 0x1900, 0x22d7, 0x0000 }, { 0x1900, 0x22d9, 0x0000 }, { 0x9900, 0x22dc, 0x2000 }, { 0x1900, 0x22db, 0x0000 }, { 0x1900, 0x22dd, 0x0000 }, { 0x9900, 0x22e6, 0x4000 }, { 0x9900, 0x22e2, 0x3000 }, { 0x9900, 0x22e0, 0x2000 }, { 0x1900, 0x22df, 0x0000 }, { 0x1900, 0x22e1, 0x0000 }, { 0x9900, 0x22e4, 0x2000 }, { 0x1900, 0x22e3, 0x0000 }, { 0x1900, 0x22e5, 0x0000 }, { 0x9900, 0x22ea, 0x3000 }, { 0x9900, 0x22e8, 0x2000 }, { 0x1900, 0x22e7, 0x0000 }, { 0x1900, 0x22e9, 0x0000 }, { 0x9900, 0x22ec, 0x2000 }, { 0x1900, 0x22eb, 0x0000 }, { 0x1900, 0x22ed, 0x0000 }, { 0x9a00, 0x230e, 0x6000 }, { 0x9900, 0x22fe, 0x5000 }, { 0x9900, 0x22f6, 0x4000 }, { 0x9900, 0x22f2, 0x3000 }, { 0x9900, 0x22f0, 0x2000 }, { 0x1900, 0x22ef, 0x0000 }, { 0x1900, 0x22f1, 0x0000 }, { 0x9900, 0x22f4, 0x2000 }, { 0x1900, 0x22f3, 0x0000 }, { 0x1900, 0x22f5, 0x0000 }, { 0x9900, 0x22fa, 0x3000 }, { 0x9900, 0x22f8, 0x2000 }, { 0x1900, 0x22f7, 0x0000 }, { 0x1900, 0x22f9, 0x0000 }, { 0x9900, 0x22fc, 0x2000 }, { 0x1900, 0x22fb, 0x0000 }, { 0x1900, 0x22fd, 0x0000 }, { 0x9a00, 0x2306, 0x4000 }, { 0x9a00, 0x2302, 0x3000 }, { 0x9a00, 0x2300, 0x2000 }, { 0x1900, 0x22ff, 0x0000 }, { 0x1a00, 0x2301, 0x0000 }, { 0x9a00, 0x2304, 0x2000 }, { 0x1a00, 0x2303, 0x0000 }, { 0x1a00, 0x2305, 0x0000 }, { 0x9900, 0x230a, 0x3000 }, { 0x9900, 0x2308, 0x2000 }, { 0x1a00, 0x2307, 0x0000 }, { 0x1900, 0x2309, 0x0000 }, { 0x9a00, 0x230c, 0x2000 }, { 0x1900, 0x230b, 0x0000 }, { 0x1a00, 0x230d, 0x0000 }, { 0x9a00, 0x231e, 0x5000 }, { 0x9a00, 0x2316, 0x4000 }, { 0x9a00, 0x2312, 0x3000 }, { 0x9a00, 0x2310, 0x2000 }, { 0x1a00, 0x230f, 0x0000 }, { 0x1a00, 0x2311, 0x0000 }, { 0x9a00, 0x2314, 0x2000 }, { 0x1a00, 0x2313, 0x0000 }, { 0x1a00, 0x2315, 0x0000 }, { 0x9a00, 0x231a, 0x3000 }, { 0x9a00, 0x2318, 0x2000 }, { 0x1a00, 0x2317, 0x0000 }, { 0x1a00, 0x2319, 0x0000 }, { 0x9a00, 0x231c, 0x2000 }, { 0x1a00, 0x231b, 0x0000 }, { 0x1a00, 0x231d, 0x0000 }, { 0x9a00, 0x2326, 0x4000 }, { 0x9a00, 0x2322, 0x3000 }, { 0x9900, 0x2320, 0x2000 }, { 0x1a00, 0x231f, 0x0000 }, { 0x1900, 0x2321, 0x0000 }, { 0x9a00, 0x2324, 0x2000 }, { 0x1a00, 0x2323, 0x0000 }, { 0x1a00, 0x2325, 0x0000 }, { 0x9200, 0x232a, 0x3000 }, { 0x9a00, 0x2328, 0x2000 }, { 0x1a00, 0x2327, 0x0000 }, { 0x1600, 0x2329, 0x0000 }, { 0x9a00, 0x232c, 0x2000 }, { 0x1a00, 0x232b, 0x0000 }, { 0x1a00, 0x232d, 0x0000 }, { 0x9a00, 0x236e, 0x7000 }, { 0x9a00, 0x234e, 0x6000 }, { 0x9a00, 0x233e, 0x5000 }, { 0x9a00, 0x2336, 0x4000 }, { 0x9a00, 0x2332, 0x3000 }, { 0x9a00, 0x2330, 0x2000 }, { 0x1a00, 0x232f, 0x0000 }, { 0x1a00, 0x2331, 0x0000 }, { 0x9a00, 0x2334, 0x2000 }, { 0x1a00, 0x2333, 0x0000 }, { 0x1a00, 0x2335, 0x0000 }, { 0x9a00, 0x233a, 0x3000 }, { 0x9a00, 0x2338, 0x2000 }, { 0x1a00, 0x2337, 0x0000 }, { 0x1a00, 0x2339, 0x0000 }, { 0x9a00, 0x233c, 0x2000 }, { 0x1a00, 0x233b, 0x0000 }, { 0x1a00, 0x233d, 0x0000 }, { 0x9a00, 0x2346, 0x4000 }, { 0x9a00, 0x2342, 0x3000 }, { 0x9a00, 0x2340, 0x2000 }, { 0x1a00, 0x233f, 0x0000 }, { 0x1a00, 0x2341, 0x0000 }, { 0x9a00, 0x2344, 0x2000 }, { 0x1a00, 0x2343, 0x0000 }, { 0x1a00, 0x2345, 0x0000 }, { 0x9a00, 0x234a, 0x3000 }, { 0x9a00, 0x2348, 0x2000 }, { 0x1a00, 0x2347, 0x0000 }, { 0x1a00, 0x2349, 0x0000 }, { 0x9a00, 0x234c, 0x2000 }, { 0x1a00, 0x234b, 0x0000 }, { 0x1a00, 0x234d, 0x0000 }, { 0x9a00, 0x235e, 0x5000 }, { 0x9a00, 0x2356, 0x4000 }, { 0x9a00, 0x2352, 0x3000 }, { 0x9a00, 0x2350, 0x2000 }, { 0x1a00, 0x234f, 0x0000 }, { 0x1a00, 0x2351, 0x0000 }, { 0x9a00, 0x2354, 0x2000 }, { 0x1a00, 0x2353, 0x0000 }, { 0x1a00, 0x2355, 0x0000 }, { 0x9a00, 0x235a, 0x3000 }, { 0x9a00, 0x2358, 0x2000 }, { 0x1a00, 0x2357, 0x0000 }, { 0x1a00, 0x2359, 0x0000 }, { 0x9a00, 0x235c, 0x2000 }, { 0x1a00, 0x235b, 0x0000 }, { 0x1a00, 0x235d, 0x0000 }, { 0x9a00, 0x2366, 0x4000 }, { 0x9a00, 0x2362, 0x3000 }, { 0x9a00, 0x2360, 0x2000 }, { 0x1a00, 0x235f, 0x0000 }, { 0x1a00, 0x2361, 0x0000 }, { 0x9a00, 0x2364, 0x2000 }, { 0x1a00, 0x2363, 0x0000 }, { 0x1a00, 0x2365, 0x0000 }, { 0x9a00, 0x236a, 0x3000 }, { 0x9a00, 0x2368, 0x2000 }, { 0x1a00, 0x2367, 0x0000 }, { 0x1a00, 0x2369, 0x0000 }, { 0x9a00, 0x236c, 0x2000 }, { 0x1a00, 0x236b, 0x0000 }, { 0x1a00, 0x236d, 0x0000 }, { 0x9a00, 0x238e, 0x6000 }, { 0x9a00, 0x237e, 0x5000 }, { 0x9a00, 0x2376, 0x4000 }, { 0x9a00, 0x2372, 0x3000 }, { 0x9a00, 0x2370, 0x2000 }, { 0x1a00, 0x236f, 0x0000 }, { 0x1a00, 0x2371, 0x0000 }, { 0x9a00, 0x2374, 0x2000 }, { 0x1a00, 0x2373, 0x0000 }, { 0x1a00, 0x2375, 0x0000 }, { 0x9a00, 0x237a, 0x3000 }, { 0x9a00, 0x2378, 0x2000 }, { 0x1a00, 0x2377, 0x0000 }, { 0x1a00, 0x2379, 0x0000 }, { 0x9900, 0x237c, 0x2000 }, { 0x1a00, 0x237b, 0x0000 }, { 0x1a00, 0x237d, 0x0000 }, { 0x9a00, 0x2386, 0x4000 }, { 0x9a00, 0x2382, 0x3000 }, { 0x9a00, 0x2380, 0x2000 }, { 0x1a00, 0x237f, 0x0000 }, { 0x1a00, 0x2381, 0x0000 }, { 0x9a00, 0x2384, 0x2000 }, { 0x1a00, 0x2383, 0x0000 }, { 0x1a00, 0x2385, 0x0000 }, { 0x9a00, 0x238a, 0x3000 }, { 0x9a00, 0x2388, 0x2000 }, { 0x1a00, 0x2387, 0x0000 }, { 0x1a00, 0x2389, 0x0000 }, { 0x9a00, 0x238c, 0x2000 }, { 0x1a00, 0x238b, 0x0000 }, { 0x1a00, 0x238d, 0x0000 }, { 0x9900, 0x239e, 0x5000 }, { 0x9a00, 0x2396, 0x4000 }, { 0x9a00, 0x2392, 0x3000 }, { 0x9a00, 0x2390, 0x2000 }, { 0x1a00, 0x238f, 0x0000 }, { 0x1a00, 0x2391, 0x0000 }, { 0x9a00, 0x2394, 0x2000 }, { 0x1a00, 0x2393, 0x0000 }, { 0x1a00, 0x2395, 0x0000 }, { 0x9a00, 0x239a, 0x3000 }, { 0x9a00, 0x2398, 0x2000 }, { 0x1a00, 0x2397, 0x0000 }, { 0x1a00, 0x2399, 0x0000 }, { 0x9900, 0x239c, 0x2000 }, { 0x1900, 0x239b, 0x0000 }, { 0x1900, 0x239d, 0x0000 }, { 0x9900, 0x23a6, 0x4000 }, { 0x9900, 0x23a2, 0x3000 }, { 0x9900, 0x23a0, 0x2000 }, { 0x1900, 0x239f, 0x0000 }, { 0x1900, 0x23a1, 0x0000 }, { 0x9900, 0x23a4, 0x2000 }, { 0x1900, 0x23a3, 0x0000 }, { 0x1900, 0x23a5, 0x0000 }, { 0x9900, 0x23aa, 0x3000 }, { 0x9900, 0x23a8, 0x2000 }, { 0x1900, 0x23a7, 0x0000 }, { 0x1900, 0x23a9, 0x0000 }, { 0x9900, 0x23ac, 0x2000 }, { 0x1900, 0x23ab, 0x0000 }, { 0x1900, 0x23ad, 0x0000 }, { 0x8f00, 0x248b, 0x8000 }, { 0x9a00, 0x241d, 0x7000 }, { 0x9a00, 0x23ce, 0x6000 }, { 0x9a00, 0x23be, 0x5000 }, { 0x9500, 0x23b6, 0x4000 }, { 0x9900, 0x23b2, 0x3000 }, { 0x9900, 0x23b0, 0x2000 }, { 0x1900, 0x23af, 0x0000 }, { 0x1900, 0x23b1, 0x0000 }, { 0x9600, 0x23b4, 0x2000 }, { 0x1900, 0x23b3, 0x0000 }, { 0x1200, 0x23b5, 0x0000 }, { 0x9a00, 0x23ba, 0x3000 }, { 0x9a00, 0x23b8, 0x2000 }, { 0x1a00, 0x23b7, 0x0000 }, { 0x1a00, 0x23b9, 0x0000 }, { 0x9a00, 0x23bc, 0x2000 }, { 0x1a00, 0x23bb, 0x0000 }, { 0x1a00, 0x23bd, 0x0000 }, { 0x9a00, 0x23c6, 0x4000 }, { 0x9a00, 0x23c2, 0x3000 }, { 0x9a00, 0x23c0, 0x2000 }, { 0x1a00, 0x23bf, 0x0000 }, { 0x1a00, 0x23c1, 0x0000 }, { 0x9a00, 0x23c4, 0x2000 }, { 0x1a00, 0x23c3, 0x0000 }, { 0x1a00, 0x23c5, 0x0000 }, { 0x9a00, 0x23ca, 0x3000 }, { 0x9a00, 0x23c8, 0x2000 }, { 0x1a00, 0x23c7, 0x0000 }, { 0x1a00, 0x23c9, 0x0000 }, { 0x9a00, 0x23cc, 0x2000 }, { 0x1a00, 0x23cb, 0x0000 }, { 0x1a00, 0x23cd, 0x0000 }, { 0x9a00, 0x240d, 0x5000 }, { 0x9a00, 0x2405, 0x4000 }, { 0x9a00, 0x2401, 0x3000 }, { 0x9a00, 0x23d0, 0x2000 }, { 0x1a00, 0x23cf, 0x0000 }, { 0x1a00, 0x2400, 0x0000 }, { 0x9a00, 0x2403, 0x2000 }, { 0x1a00, 0x2402, 0x0000 }, { 0x1a00, 0x2404, 0x0000 }, { 0x9a00, 0x2409, 0x3000 }, { 0x9a00, 0x2407, 0x2000 }, { 0x1a00, 0x2406, 0x0000 }, { 0x1a00, 0x2408, 0x0000 }, { 0x9a00, 0x240b, 0x2000 }, { 0x1a00, 0x240a, 0x0000 }, { 0x1a00, 0x240c, 0x0000 }, { 0x9a00, 0x2415, 0x4000 }, { 0x9a00, 0x2411, 0x3000 }, { 0x9a00, 0x240f, 0x2000 }, { 0x1a00, 0x240e, 0x0000 }, { 0x1a00, 0x2410, 0x0000 }, { 0x9a00, 0x2413, 0x2000 }, { 0x1a00, 0x2412, 0x0000 }, { 0x1a00, 0x2414, 0x0000 }, { 0x9a00, 0x2419, 0x3000 }, { 0x9a00, 0x2417, 0x2000 }, { 0x1a00, 0x2416, 0x0000 }, { 0x1a00, 0x2418, 0x0000 }, { 0x9a00, 0x241b, 0x2000 }, { 0x1a00, 0x241a, 0x0000 }, { 0x1a00, 0x241c, 0x0000 }, { 0x8f00, 0x246b, 0x6000 }, { 0x9a00, 0x2446, 0x5000 }, { 0x9a00, 0x2425, 0x4000 }, { 0x9a00, 0x2421, 0x3000 }, { 0x9a00, 0x241f, 0x2000 }, { 0x1a00, 0x241e, 0x0000 }, { 0x1a00, 0x2420, 0x0000 }, { 0x9a00, 0x2423, 0x2000 }, { 0x1a00, 0x2422, 0x0000 }, { 0x1a00, 0x2424, 0x0000 }, { 0x9a00, 0x2442, 0x3000 }, { 0x9a00, 0x2440, 0x2000 }, { 0x1a00, 0x2426, 0x0000 }, { 0x1a00, 0x2441, 0x0000 }, { 0x9a00, 0x2444, 0x2000 }, { 0x1a00, 0x2443, 0x0000 }, { 0x1a00, 0x2445, 0x0000 }, { 0x8f00, 0x2463, 0x4000 }, { 0x9a00, 0x244a, 0x3000 }, { 0x9a00, 0x2448, 0x2000 }, { 0x1a00, 0x2447, 0x0000 }, { 0x1a00, 0x2449, 0x0000 }, { 0x8f00, 0x2461, 0x2000 }, { 0x0f00, 0x2460, 0x0000 }, { 0x0f00, 0x2462, 0x0000 }, { 0x8f00, 0x2467, 0x3000 }, { 0x8f00, 0x2465, 0x2000 }, { 0x0f00, 0x2464, 0x0000 }, { 0x0f00, 0x2466, 0x0000 }, { 0x8f00, 0x2469, 0x2000 }, { 0x0f00, 0x2468, 0x0000 }, { 0x0f00, 0x246a, 0x0000 }, { 0x8f00, 0x247b, 0x5000 }, { 0x8f00, 0x2473, 0x4000 }, { 0x8f00, 0x246f, 0x3000 }, { 0x8f00, 0x246d, 0x2000 }, { 0x0f00, 0x246c, 0x0000 }, { 0x0f00, 0x246e, 0x0000 }, { 0x8f00, 0x2471, 0x2000 }, { 0x0f00, 0x2470, 0x0000 }, { 0x0f00, 0x2472, 0x0000 }, { 0x8f00, 0x2477, 0x3000 }, { 0x8f00, 0x2475, 0x2000 }, { 0x0f00, 0x2474, 0x0000 }, { 0x0f00, 0x2476, 0x0000 }, { 0x8f00, 0x2479, 0x2000 }, { 0x0f00, 0x2478, 0x0000 }, { 0x0f00, 0x247a, 0x0000 }, { 0x8f00, 0x2483, 0x4000 }, { 0x8f00, 0x247f, 0x3000 }, { 0x8f00, 0x247d, 0x2000 }, { 0x0f00, 0x247c, 0x0000 }, { 0x0f00, 0x247e, 0x0000 }, { 0x8f00, 0x2481, 0x2000 }, { 0x0f00, 0x2480, 0x0000 }, { 0x0f00, 0x2482, 0x0000 }, { 0x8f00, 0x2487, 0x3000 }, { 0x8f00, 0x2485, 0x2000 }, { 0x0f00, 0x2484, 0x0000 }, { 0x0f00, 0x2486, 0x0000 }, { 0x8f00, 0x2489, 0x2000 }, { 0x0f00, 0x2488, 0x0000 }, { 0x0f00, 0x248a, 0x0000 }, { 0x9a00, 0x24cb, 0x7000 }, { 0x9a00, 0x24ab, 0x6000 }, { 0x8f00, 0x249b, 0x5000 }, { 0x8f00, 0x2493, 0x4000 }, { 0x8f00, 0x248f, 0x3000 }, { 0x8f00, 0x248d, 0x2000 }, { 0x0f00, 0x248c, 0x0000 }, { 0x0f00, 0x248e, 0x0000 }, { 0x8f00, 0x2491, 0x2000 }, { 0x0f00, 0x2490, 0x0000 }, { 0x0f00, 0x2492, 0x0000 }, { 0x8f00, 0x2497, 0x3000 }, { 0x8f00, 0x2495, 0x2000 }, { 0x0f00, 0x2494, 0x0000 }, { 0x0f00, 0x2496, 0x0000 }, { 0x8f00, 0x2499, 0x2000 }, { 0x0f00, 0x2498, 0x0000 }, { 0x0f00, 0x249a, 0x0000 }, { 0x9a00, 0x24a3, 0x4000 }, { 0x9a00, 0x249f, 0x3000 }, { 0x9a00, 0x249d, 0x2000 }, { 0x1a00, 0x249c, 0x0000 }, { 0x1a00, 0x249e, 0x0000 }, { 0x9a00, 0x24a1, 0x2000 }, { 0x1a00, 0x24a0, 0x0000 }, { 0x1a00, 0x24a2, 0x0000 }, { 0x9a00, 0x24a7, 0x3000 }, { 0x9a00, 0x24a5, 0x2000 }, { 0x1a00, 0x24a4, 0x0000 }, { 0x1a00, 0x24a6, 0x0000 }, { 0x9a00, 0x24a9, 0x2000 }, { 0x1a00, 0x24a8, 0x0000 }, { 0x1a00, 0x24aa, 0x0000 }, { 0x9a00, 0x24bb, 0x5000 }, { 0x9a00, 0x24b3, 0x4000 }, { 0x9a00, 0x24af, 0x3000 }, { 0x9a00, 0x24ad, 0x2000 }, { 0x1a00, 0x24ac, 0x0000 }, { 0x1a00, 0x24ae, 0x0000 }, { 0x9a00, 0x24b1, 0x2000 }, { 0x1a00, 0x24b0, 0x0000 }, { 0x1a00, 0x24b2, 0x0000 }, { 0x9a00, 0x24b7, 0x3000 }, { 0x9a00, 0x24b5, 0x2000 }, { 0x1a00, 0x24b4, 0x0000 }, { 0x1a00, 0x24b6, 0x0000 }, { 0x9a00, 0x24b9, 0x2000 }, { 0x1a00, 0x24b8, 0x0000 }, { 0x1a00, 0x24ba, 0x0000 }, { 0x9a00, 0x24c3, 0x4000 }, { 0x9a00, 0x24bf, 0x3000 }, { 0x9a00, 0x24bd, 0x2000 }, { 0x1a00, 0x24bc, 0x0000 }, { 0x1a00, 0x24be, 0x0000 }, { 0x9a00, 0x24c1, 0x2000 }, { 0x1a00, 0x24c0, 0x0000 }, { 0x1a00, 0x24c2, 0x0000 }, { 0x9a00, 0x24c7, 0x3000 }, { 0x9a00, 0x24c5, 0x2000 }, { 0x1a00, 0x24c4, 0x0000 }, { 0x1a00, 0x24c6, 0x0000 }, { 0x9a00, 0x24c9, 0x2000 }, { 0x1a00, 0x24c8, 0x0000 }, { 0x1a00, 0x24ca, 0x0000 }, { 0x8f00, 0x24eb, 0x6000 }, { 0x9a00, 0x24db, 0x5000 }, { 0x9a00, 0x24d3, 0x4000 }, { 0x9a00, 0x24cf, 0x3000 }, { 0x9a00, 0x24cd, 0x2000 }, { 0x1a00, 0x24cc, 0x0000 }, { 0x1a00, 0x24ce, 0x0000 }, { 0x9a00, 0x24d1, 0x2000 }, { 0x1a00, 0x24d0, 0x0000 }, { 0x1a00, 0x24d2, 0x0000 }, { 0x9a00, 0x24d7, 0x3000 }, { 0x9a00, 0x24d5, 0x2000 }, { 0x1a00, 0x24d4, 0x0000 }, { 0x1a00, 0x24d6, 0x0000 }, { 0x9a00, 0x24d9, 0x2000 }, { 0x1a00, 0x24d8, 0x0000 }, { 0x1a00, 0x24da, 0x0000 }, { 0x9a00, 0x24e3, 0x4000 }, { 0x9a00, 0x24df, 0x3000 }, { 0x9a00, 0x24dd, 0x2000 }, { 0x1a00, 0x24dc, 0x0000 }, { 0x1a00, 0x24de, 0x0000 }, { 0x9a00, 0x24e1, 0x2000 }, { 0x1a00, 0x24e0, 0x0000 }, { 0x1a00, 0x24e2, 0x0000 }, { 0x9a00, 0x24e7, 0x3000 }, { 0x9a00, 0x24e5, 0x2000 }, { 0x1a00, 0x24e4, 0x0000 }, { 0x1a00, 0x24e6, 0x0000 }, { 0x9a00, 0x24e9, 0x2000 }, { 0x1a00, 0x24e8, 0x0000 }, { 0x0f00, 0x24ea, 0x0000 }, { 0x8f00, 0x24fb, 0x5000 }, { 0x8f00, 0x24f3, 0x4000 }, { 0x8f00, 0x24ef, 0x3000 }, { 0x8f00, 0x24ed, 0x2000 }, { 0x0f00, 0x24ec, 0x0000 }, { 0x0f00, 0x24ee, 0x0000 }, { 0x8f00, 0x24f1, 0x2000 }, { 0x0f00, 0x24f0, 0x0000 }, { 0x0f00, 0x24f2, 0x0000 }, { 0x8f00, 0x24f7, 0x3000 }, { 0x8f00, 0x24f5, 0x2000 }, { 0x0f00, 0x24f4, 0x0000 }, { 0x0f00, 0x24f6, 0x0000 }, { 0x8f00, 0x24f9, 0x2000 }, { 0x0f00, 0x24f8, 0x0000 }, { 0x0f00, 0x24fa, 0x0000 }, { 0x9a00, 0x2503, 0x4000 }, { 0x8f00, 0x24ff, 0x3000 }, { 0x8f00, 0x24fd, 0x2000 }, { 0x0f00, 0x24fc, 0x0000 }, { 0x0f00, 0x24fe, 0x0000 }, { 0x9a00, 0x2501, 0x2000 }, { 0x1a00, 0x2500, 0x0000 }, { 0x1a00, 0x2502, 0x0000 }, { 0x9a00, 0x2507, 0x3000 }, { 0x9a00, 0x2505, 0x2000 }, { 0x1a00, 0x2504, 0x0000 }, { 0x1a00, 0x2506, 0x0000 }, { 0x9a00, 0x2509, 0x2000 }, { 0x1a00, 0x2508, 0x0000 }, { 0x1a00, 0x250a, 0x0000 }, { 0x9a00, 0x260b, 0x9000 }, { 0x9a00, 0x258b, 0x8000 }, { 0x9a00, 0x254b, 0x7000 }, { 0x9a00, 0x252b, 0x6000 }, { 0x9a00, 0x251b, 0x5000 }, { 0x9a00, 0x2513, 0x4000 }, { 0x9a00, 0x250f, 0x3000 }, { 0x9a00, 0x250d, 0x2000 }, { 0x1a00, 0x250c, 0x0000 }, { 0x1a00, 0x250e, 0x0000 }, { 0x9a00, 0x2511, 0x2000 }, { 0x1a00, 0x2510, 0x0000 }, { 0x1a00, 0x2512, 0x0000 }, { 0x9a00, 0x2517, 0x3000 }, { 0x9a00, 0x2515, 0x2000 }, { 0x1a00, 0x2514, 0x0000 }, { 0x1a00, 0x2516, 0x0000 }, { 0x9a00, 0x2519, 0x2000 }, { 0x1a00, 0x2518, 0x0000 }, { 0x1a00, 0x251a, 0x0000 }, { 0x9a00, 0x2523, 0x4000 }, { 0x9a00, 0x251f, 0x3000 }, { 0x9a00, 0x251d, 0x2000 }, { 0x1a00, 0x251c, 0x0000 }, { 0x1a00, 0x251e, 0x0000 }, { 0x9a00, 0x2521, 0x2000 }, { 0x1a00, 0x2520, 0x0000 }, { 0x1a00, 0x2522, 0x0000 }, { 0x9a00, 0x2527, 0x3000 }, { 0x9a00, 0x2525, 0x2000 }, { 0x1a00, 0x2524, 0x0000 }, { 0x1a00, 0x2526, 0x0000 }, { 0x9a00, 0x2529, 0x2000 }, { 0x1a00, 0x2528, 0x0000 }, { 0x1a00, 0x252a, 0x0000 }, { 0x9a00, 0x253b, 0x5000 }, { 0x9a00, 0x2533, 0x4000 }, { 0x9a00, 0x252f, 0x3000 }, { 0x9a00, 0x252d, 0x2000 }, { 0x1a00, 0x252c, 0x0000 }, { 0x1a00, 0x252e, 0x0000 }, { 0x9a00, 0x2531, 0x2000 }, { 0x1a00, 0x2530, 0x0000 }, { 0x1a00, 0x2532, 0x0000 }, { 0x9a00, 0x2537, 0x3000 }, { 0x9a00, 0x2535, 0x2000 }, { 0x1a00, 0x2534, 0x0000 }, { 0x1a00, 0x2536, 0x0000 }, { 0x9a00, 0x2539, 0x2000 }, { 0x1a00, 0x2538, 0x0000 }, { 0x1a00, 0x253a, 0x0000 }, { 0x9a00, 0x2543, 0x4000 }, { 0x9a00, 0x253f, 0x3000 }, { 0x9a00, 0x253d, 0x2000 }, { 0x1a00, 0x253c, 0x0000 }, { 0x1a00, 0x253e, 0x0000 }, { 0x9a00, 0x2541, 0x2000 }, { 0x1a00, 0x2540, 0x0000 }, { 0x1a00, 0x2542, 0x0000 }, { 0x9a00, 0x2547, 0x3000 }, { 0x9a00, 0x2545, 0x2000 }, { 0x1a00, 0x2544, 0x0000 }, { 0x1a00, 0x2546, 0x0000 }, { 0x9a00, 0x2549, 0x2000 }, { 0x1a00, 0x2548, 0x0000 }, { 0x1a00, 0x254a, 0x0000 }, { 0x9a00, 0x256b, 0x6000 }, { 0x9a00, 0x255b, 0x5000 }, { 0x9a00, 0x2553, 0x4000 }, { 0x9a00, 0x254f, 0x3000 }, { 0x9a00, 0x254d, 0x2000 }, { 0x1a00, 0x254c, 0x0000 }, { 0x1a00, 0x254e, 0x0000 }, { 0x9a00, 0x2551, 0x2000 }, { 0x1a00, 0x2550, 0x0000 }, { 0x1a00, 0x2552, 0x0000 }, { 0x9a00, 0x2557, 0x3000 }, { 0x9a00, 0x2555, 0x2000 }, { 0x1a00, 0x2554, 0x0000 }, { 0x1a00, 0x2556, 0x0000 }, { 0x9a00, 0x2559, 0x2000 }, { 0x1a00, 0x2558, 0x0000 }, { 0x1a00, 0x255a, 0x0000 }, { 0x9a00, 0x2563, 0x4000 }, { 0x9a00, 0x255f, 0x3000 }, { 0x9a00, 0x255d, 0x2000 }, { 0x1a00, 0x255c, 0x0000 }, { 0x1a00, 0x255e, 0x0000 }, { 0x9a00, 0x2561, 0x2000 }, { 0x1a00, 0x2560, 0x0000 }, { 0x1a00, 0x2562, 0x0000 }, { 0x9a00, 0x2567, 0x3000 }, { 0x9a00, 0x2565, 0x2000 }, { 0x1a00, 0x2564, 0x0000 }, { 0x1a00, 0x2566, 0x0000 }, { 0x9a00, 0x2569, 0x2000 }, { 0x1a00, 0x2568, 0x0000 }, { 0x1a00, 0x256a, 0x0000 }, { 0x9a00, 0x257b, 0x5000 }, { 0x9a00, 0x2573, 0x4000 }, { 0x9a00, 0x256f, 0x3000 }, { 0x9a00, 0x256d, 0x2000 }, { 0x1a00, 0x256c, 0x0000 }, { 0x1a00, 0x256e, 0x0000 }, { 0x9a00, 0x2571, 0x2000 }, { 0x1a00, 0x2570, 0x0000 }, { 0x1a00, 0x2572, 0x0000 }, { 0x9a00, 0x2577, 0x3000 }, { 0x9a00, 0x2575, 0x2000 }, { 0x1a00, 0x2574, 0x0000 }, { 0x1a00, 0x2576, 0x0000 }, { 0x9a00, 0x2579, 0x2000 }, { 0x1a00, 0x2578, 0x0000 }, { 0x1a00, 0x257a, 0x0000 }, { 0x9a00, 0x2583, 0x4000 }, { 0x9a00, 0x257f, 0x3000 }, { 0x9a00, 0x257d, 0x2000 }, { 0x1a00, 0x257c, 0x0000 }, { 0x1a00, 0x257e, 0x0000 }, { 0x9a00, 0x2581, 0x2000 }, { 0x1a00, 0x2580, 0x0000 }, { 0x1a00, 0x2582, 0x0000 }, { 0x9a00, 0x2587, 0x3000 }, { 0x9a00, 0x2585, 0x2000 }, { 0x1a00, 0x2584, 0x0000 }, { 0x1a00, 0x2586, 0x0000 }, { 0x9a00, 0x2589, 0x2000 }, { 0x1a00, 0x2588, 0x0000 }, { 0x1a00, 0x258a, 0x0000 }, { 0x9a00, 0x25cb, 0x7000 }, { 0x9a00, 0x25ab, 0x6000 }, { 0x9a00, 0x259b, 0x5000 }, { 0x9a00, 0x2593, 0x4000 }, { 0x9a00, 0x258f, 0x3000 }, { 0x9a00, 0x258d, 0x2000 }, { 0x1a00, 0x258c, 0x0000 }, { 0x1a00, 0x258e, 0x0000 }, { 0x9a00, 0x2591, 0x2000 }, { 0x1a00, 0x2590, 0x0000 }, { 0x1a00, 0x2592, 0x0000 }, { 0x9a00, 0x2597, 0x3000 }, { 0x9a00, 0x2595, 0x2000 }, { 0x1a00, 0x2594, 0x0000 }, { 0x1a00, 0x2596, 0x0000 }, { 0x9a00, 0x2599, 0x2000 }, { 0x1a00, 0x2598, 0x0000 }, { 0x1a00, 0x259a, 0x0000 }, { 0x9a00, 0x25a3, 0x4000 }, { 0x9a00, 0x259f, 0x3000 }, { 0x9a00, 0x259d, 0x2000 }, { 0x1a00, 0x259c, 0x0000 }, { 0x1a00, 0x259e, 0x0000 }, { 0x9a00, 0x25a1, 0x2000 }, { 0x1a00, 0x25a0, 0x0000 }, { 0x1a00, 0x25a2, 0x0000 }, { 0x9a00, 0x25a7, 0x3000 }, { 0x9a00, 0x25a5, 0x2000 }, { 0x1a00, 0x25a4, 0x0000 }, { 0x1a00, 0x25a6, 0x0000 }, { 0x9a00, 0x25a9, 0x2000 }, { 0x1a00, 0x25a8, 0x0000 }, { 0x1a00, 0x25aa, 0x0000 }, { 0x9a00, 0x25bb, 0x5000 }, { 0x9a00, 0x25b3, 0x4000 }, { 0x9a00, 0x25af, 0x3000 }, { 0x9a00, 0x25ad, 0x2000 }, { 0x1a00, 0x25ac, 0x0000 }, { 0x1a00, 0x25ae, 0x0000 }, { 0x9a00, 0x25b1, 0x2000 }, { 0x1a00, 0x25b0, 0x0000 }, { 0x1a00, 0x25b2, 0x0000 }, { 0x9900, 0x25b7, 0x3000 }, { 0x9a00, 0x25b5, 0x2000 }, { 0x1a00, 0x25b4, 0x0000 }, { 0x1a00, 0x25b6, 0x0000 }, { 0x9a00, 0x25b9, 0x2000 }, { 0x1a00, 0x25b8, 0x0000 }, { 0x1a00, 0x25ba, 0x0000 }, { 0x9a00, 0x25c3, 0x4000 }, { 0x9a00, 0x25bf, 0x3000 }, { 0x9a00, 0x25bd, 0x2000 }, { 0x1a00, 0x25bc, 0x0000 }, { 0x1a00, 0x25be, 0x0000 }, { 0x9900, 0x25c1, 0x2000 }, { 0x1a00, 0x25c0, 0x0000 }, { 0x1a00, 0x25c2, 0x0000 }, { 0x9a00, 0x25c7, 0x3000 }, { 0x9a00, 0x25c5, 0x2000 }, { 0x1a00, 0x25c4, 0x0000 }, { 0x1a00, 0x25c6, 0x0000 }, { 0x9a00, 0x25c9, 0x2000 }, { 0x1a00, 0x25c8, 0x0000 }, { 0x1a00, 0x25ca, 0x0000 }, { 0x9a00, 0x25eb, 0x6000 }, { 0x9a00, 0x25db, 0x5000 }, { 0x9a00, 0x25d3, 0x4000 }, { 0x9a00, 0x25cf, 0x3000 }, { 0x9a00, 0x25cd, 0x2000 }, { 0x1a00, 0x25cc, 0x0000 }, { 0x1a00, 0x25ce, 0x0000 }, { 0x9a00, 0x25d1, 0x2000 }, { 0x1a00, 0x25d0, 0x0000 }, { 0x1a00, 0x25d2, 0x0000 }, { 0x9a00, 0x25d7, 0x3000 }, { 0x9a00, 0x25d5, 0x2000 }, { 0x1a00, 0x25d4, 0x0000 }, { 0x1a00, 0x25d6, 0x0000 }, { 0x9a00, 0x25d9, 0x2000 }, { 0x1a00, 0x25d8, 0x0000 }, { 0x1a00, 0x25da, 0x0000 }, { 0x9a00, 0x25e3, 0x4000 }, { 0x9a00, 0x25df, 0x3000 }, { 0x9a00, 0x25dd, 0x2000 }, { 0x1a00, 0x25dc, 0x0000 }, { 0x1a00, 0x25de, 0x0000 }, { 0x9a00, 0x25e1, 0x2000 }, { 0x1a00, 0x25e0, 0x0000 }, { 0x1a00, 0x25e2, 0x0000 }, { 0x9a00, 0x25e7, 0x3000 }, { 0x9a00, 0x25e5, 0x2000 }, { 0x1a00, 0x25e4, 0x0000 }, { 0x1a00, 0x25e6, 0x0000 }, { 0x9a00, 0x25e9, 0x2000 }, { 0x1a00, 0x25e8, 0x0000 }, { 0x1a00, 0x25ea, 0x0000 }, { 0x9900, 0x25fb, 0x5000 }, { 0x9a00, 0x25f3, 0x4000 }, { 0x9a00, 0x25ef, 0x3000 }, { 0x9a00, 0x25ed, 0x2000 }, { 0x1a00, 0x25ec, 0x0000 }, { 0x1a00, 0x25ee, 0x0000 }, { 0x9a00, 0x25f1, 0x2000 }, { 0x1a00, 0x25f0, 0x0000 }, { 0x1a00, 0x25f2, 0x0000 }, { 0x9a00, 0x25f7, 0x3000 }, { 0x9a00, 0x25f5, 0x2000 }, { 0x1a00, 0x25f4, 0x0000 }, { 0x1a00, 0x25f6, 0x0000 }, { 0x9900, 0x25f9, 0x2000 }, { 0x1900, 0x25f8, 0x0000 }, { 0x1900, 0x25fa, 0x0000 }, { 0x9a00, 0x2603, 0x4000 }, { 0x9900, 0x25ff, 0x3000 }, { 0x9900, 0x25fd, 0x2000 }, { 0x1900, 0x25fc, 0x0000 }, { 0x1900, 0x25fe, 0x0000 }, { 0x9a00, 0x2601, 0x2000 }, { 0x1a00, 0x2600, 0x0000 }, { 0x1a00, 0x2602, 0x0000 }, { 0x9a00, 0x2607, 0x3000 }, { 0x9a00, 0x2605, 0x2000 }, { 0x1a00, 0x2604, 0x0000 }, { 0x1a00, 0x2606, 0x0000 }, { 0x9a00, 0x2609, 0x2000 }, { 0x1a00, 0x2608, 0x0000 }, { 0x1a00, 0x260a, 0x0000 }, { 0x9a00, 0x268e, 0x8000 }, { 0x9a00, 0x264c, 0x7000 }, { 0x9a00, 0x262c, 0x6000 }, { 0x9a00, 0x261c, 0x5000 }, { 0x9a00, 0x2613, 0x4000 }, { 0x9a00, 0x260f, 0x3000 }, { 0x9a00, 0x260d, 0x2000 }, { 0x1a00, 0x260c, 0x0000 }, { 0x1a00, 0x260e, 0x0000 }, { 0x9a00, 0x2611, 0x2000 }, { 0x1a00, 0x2610, 0x0000 }, { 0x1a00, 0x2612, 0x0000 }, { 0x9a00, 0x2617, 0x3000 }, { 0x9a00, 0x2615, 0x2000 }, { 0x1a00, 0x2614, 0x0000 }, { 0x1a00, 0x2616, 0x0000 }, { 0x9a00, 0x261a, 0x2000 }, { 0x1a00, 0x2619, 0x0000 }, { 0x1a00, 0x261b, 0x0000 }, { 0x9a00, 0x2624, 0x4000 }, { 0x9a00, 0x2620, 0x3000 }, { 0x9a00, 0x261e, 0x2000 }, { 0x1a00, 0x261d, 0x0000 }, { 0x1a00, 0x261f, 0x0000 }, { 0x9a00, 0x2622, 0x2000 }, { 0x1a00, 0x2621, 0x0000 }, { 0x1a00, 0x2623, 0x0000 }, { 0x9a00, 0x2628, 0x3000 }, { 0x9a00, 0x2626, 0x2000 }, { 0x1a00, 0x2625, 0x0000 }, { 0x1a00, 0x2627, 0x0000 }, { 0x9a00, 0x262a, 0x2000 }, { 0x1a00, 0x2629, 0x0000 }, { 0x1a00, 0x262b, 0x0000 }, { 0x9a00, 0x263c, 0x5000 }, { 0x9a00, 0x2634, 0x4000 }, { 0x9a00, 0x2630, 0x3000 }, { 0x9a00, 0x262e, 0x2000 }, { 0x1a00, 0x262d, 0x0000 }, { 0x1a00, 0x262f, 0x0000 }, { 0x9a00, 0x2632, 0x2000 }, { 0x1a00, 0x2631, 0x0000 }, { 0x1a00, 0x2633, 0x0000 }, { 0x9a00, 0x2638, 0x3000 }, { 0x9a00, 0x2636, 0x2000 }, { 0x1a00, 0x2635, 0x0000 }, { 0x1a00, 0x2637, 0x0000 }, { 0x9a00, 0x263a, 0x2000 }, { 0x1a00, 0x2639, 0x0000 }, { 0x1a00, 0x263b, 0x0000 }, { 0x9a00, 0x2644, 0x4000 }, { 0x9a00, 0x2640, 0x3000 }, { 0x9a00, 0x263e, 0x2000 }, { 0x1a00, 0x263d, 0x0000 }, { 0x1a00, 0x263f, 0x0000 }, { 0x9a00, 0x2642, 0x2000 }, { 0x1a00, 0x2641, 0x0000 }, { 0x1a00, 0x2643, 0x0000 }, { 0x9a00, 0x2648, 0x3000 }, { 0x9a00, 0x2646, 0x2000 }, { 0x1a00, 0x2645, 0x0000 }, { 0x1a00, 0x2647, 0x0000 }, { 0x9a00, 0x264a, 0x2000 }, { 0x1a00, 0x2649, 0x0000 }, { 0x1a00, 0x264b, 0x0000 }, { 0x9a00, 0x266c, 0x6000 }, { 0x9a00, 0x265c, 0x5000 }, { 0x9a00, 0x2654, 0x4000 }, { 0x9a00, 0x2650, 0x3000 }, { 0x9a00, 0x264e, 0x2000 }, { 0x1a00, 0x264d, 0x0000 }, { 0x1a00, 0x264f, 0x0000 }, { 0x9a00, 0x2652, 0x2000 }, { 0x1a00, 0x2651, 0x0000 }, { 0x1a00, 0x2653, 0x0000 }, { 0x9a00, 0x2658, 0x3000 }, { 0x9a00, 0x2656, 0x2000 }, { 0x1a00, 0x2655, 0x0000 }, { 0x1a00, 0x2657, 0x0000 }, { 0x9a00, 0x265a, 0x2000 }, { 0x1a00, 0x2659, 0x0000 }, { 0x1a00, 0x265b, 0x0000 }, { 0x9a00, 0x2664, 0x4000 }, { 0x9a00, 0x2660, 0x3000 }, { 0x9a00, 0x265e, 0x2000 }, { 0x1a00, 0x265d, 0x0000 }, { 0x1a00, 0x265f, 0x0000 }, { 0x9a00, 0x2662, 0x2000 }, { 0x1a00, 0x2661, 0x0000 }, { 0x1a00, 0x2663, 0x0000 }, { 0x9a00, 0x2668, 0x3000 }, { 0x9a00, 0x2666, 0x2000 }, { 0x1a00, 0x2665, 0x0000 }, { 0x1a00, 0x2667, 0x0000 }, { 0x9a00, 0x266a, 0x2000 }, { 0x1a00, 0x2669, 0x0000 }, { 0x1a00, 0x266b, 0x0000 }, { 0x9a00, 0x267c, 0x5000 }, { 0x9a00, 0x2674, 0x4000 }, { 0x9a00, 0x2670, 0x3000 }, { 0x9a00, 0x266e, 0x2000 }, { 0x1a00, 0x266d, 0x0000 }, { 0x1900, 0x266f, 0x0000 }, { 0x9a00, 0x2672, 0x2000 }, { 0x1a00, 0x2671, 0x0000 }, { 0x1a00, 0x2673, 0x0000 }, { 0x9a00, 0x2678, 0x3000 }, { 0x9a00, 0x2676, 0x2000 }, { 0x1a00, 0x2675, 0x0000 }, { 0x1a00, 0x2677, 0x0000 }, { 0x9a00, 0x267a, 0x2000 }, { 0x1a00, 0x2679, 0x0000 }, { 0x1a00, 0x267b, 0x0000 }, { 0x9a00, 0x2686, 0x4000 }, { 0x9a00, 0x2682, 0x3000 }, { 0x9a00, 0x2680, 0x2000 }, { 0x1a00, 0x267d, 0x0000 }, { 0x1a00, 0x2681, 0x0000 }, { 0x9a00, 0x2684, 0x2000 }, { 0x1a00, 0x2683, 0x0000 }, { 0x1a00, 0x2685, 0x0000 }, { 0x9a00, 0x268a, 0x3000 }, { 0x9a00, 0x2688, 0x2000 }, { 0x1a00, 0x2687, 0x0000 }, { 0x1a00, 0x2689, 0x0000 }, { 0x9a00, 0x268c, 0x2000 }, { 0x1a00, 0x268b, 0x0000 }, { 0x1a00, 0x268d, 0x0000 }, { 0x9a00, 0x273f, 0x7000 }, { 0x9a00, 0x271e, 0x6000 }, { 0x9a00, 0x270e, 0x5000 }, { 0x9a00, 0x2703, 0x4000 }, { 0x9a00, 0x26a0, 0x3000 }, { 0x9a00, 0x2690, 0x2000 }, { 0x1a00, 0x268f, 0x0000 }, { 0x1a00, 0x2691, 0x0000 }, { 0x9a00, 0x2701, 0x2000 }, { 0x1a00, 0x26a1, 0x0000 }, { 0x1a00, 0x2702, 0x0000 }, { 0x9a00, 0x2708, 0x3000 }, { 0x9a00, 0x2706, 0x2000 }, { 0x1a00, 0x2704, 0x0000 }, { 0x1a00, 0x2707, 0x0000 }, { 0x9a00, 0x270c, 0x2000 }, { 0x1a00, 0x2709, 0x0000 }, { 0x1a00, 0x270d, 0x0000 }, { 0x9a00, 0x2716, 0x4000 }, { 0x9a00, 0x2712, 0x3000 }, { 0x9a00, 0x2710, 0x2000 }, { 0x1a00, 0x270f, 0x0000 }, { 0x1a00, 0x2711, 0x0000 }, { 0x9a00, 0x2714, 0x2000 }, { 0x1a00, 0x2713, 0x0000 }, { 0x1a00, 0x2715, 0x0000 }, { 0x9a00, 0x271a, 0x3000 }, { 0x9a00, 0x2718, 0x2000 }, { 0x1a00, 0x2717, 0x0000 }, { 0x1a00, 0x2719, 0x0000 }, { 0x9a00, 0x271c, 0x2000 }, { 0x1a00, 0x271b, 0x0000 }, { 0x1a00, 0x271d, 0x0000 }, { 0x9a00, 0x272f, 0x5000 }, { 0x9a00, 0x2726, 0x4000 }, { 0x9a00, 0x2722, 0x3000 }, { 0x9a00, 0x2720, 0x2000 }, { 0x1a00, 0x271f, 0x0000 }, { 0x1a00, 0x2721, 0x0000 }, { 0x9a00, 0x2724, 0x2000 }, { 0x1a00, 0x2723, 0x0000 }, { 0x1a00, 0x2725, 0x0000 }, { 0x9a00, 0x272b, 0x3000 }, { 0x9a00, 0x2729, 0x2000 }, { 0x1a00, 0x2727, 0x0000 }, { 0x1a00, 0x272a, 0x0000 }, { 0x9a00, 0x272d, 0x2000 }, { 0x1a00, 0x272c, 0x0000 }, { 0x1a00, 0x272e, 0x0000 }, { 0x9a00, 0x2737, 0x4000 }, { 0x9a00, 0x2733, 0x3000 }, { 0x9a00, 0x2731, 0x2000 }, { 0x1a00, 0x2730, 0x0000 }, { 0x1a00, 0x2732, 0x0000 }, { 0x9a00, 0x2735, 0x2000 }, { 0x1a00, 0x2734, 0x0000 }, { 0x1a00, 0x2736, 0x0000 }, { 0x9a00, 0x273b, 0x3000 }, { 0x9a00, 0x2739, 0x2000 }, { 0x1a00, 0x2738, 0x0000 }, { 0x1a00, 0x273a, 0x0000 }, { 0x9a00, 0x273d, 0x2000 }, { 0x1a00, 0x273c, 0x0000 }, { 0x1a00, 0x273e, 0x0000 }, { 0x9a00, 0x2767, 0x6000 }, { 0x9a00, 0x2751, 0x5000 }, { 0x9a00, 0x2747, 0x4000 }, { 0x9a00, 0x2743, 0x3000 }, { 0x9a00, 0x2741, 0x2000 }, { 0x1a00, 0x2740, 0x0000 }, { 0x1a00, 0x2742, 0x0000 }, { 0x9a00, 0x2745, 0x2000 }, { 0x1a00, 0x2744, 0x0000 }, { 0x1a00, 0x2746, 0x0000 }, { 0x9a00, 0x274b, 0x3000 }, { 0x9a00, 0x2749, 0x2000 }, { 0x1a00, 0x2748, 0x0000 }, { 0x1a00, 0x274a, 0x0000 }, { 0x9a00, 0x274f, 0x2000 }, { 0x1a00, 0x274d, 0x0000 }, { 0x1a00, 0x2750, 0x0000 }, { 0x9a00, 0x275d, 0x4000 }, { 0x9a00, 0x2759, 0x3000 }, { 0x9a00, 0x2756, 0x2000 }, { 0x1a00, 0x2752, 0x0000 }, { 0x1a00, 0x2758, 0x0000 }, { 0x9a00, 0x275b, 0x2000 }, { 0x1a00, 0x275a, 0x0000 }, { 0x1a00, 0x275c, 0x0000 }, { 0x9a00, 0x2763, 0x3000 }, { 0x9a00, 0x2761, 0x2000 }, { 0x1a00, 0x275e, 0x0000 }, { 0x1a00, 0x2762, 0x0000 }, { 0x9a00, 0x2765, 0x2000 }, { 0x1a00, 0x2764, 0x0000 }, { 0x1a00, 0x2766, 0x0000 }, { 0x8f00, 0x2777, 0x5000 }, { 0x9200, 0x276f, 0x4000 }, { 0x9200, 0x276b, 0x3000 }, { 0x9200, 0x2769, 0x2000 }, { 0x1600, 0x2768, 0x0000 }, { 0x1600, 0x276a, 0x0000 }, { 0x9200, 0x276d, 0x2000 }, { 0x1600, 0x276c, 0x0000 }, { 0x1600, 0x276e, 0x0000 }, { 0x9200, 0x2773, 0x3000 }, { 0x9200, 0x2771, 0x2000 }, { 0x1600, 0x2770, 0x0000 }, { 0x1600, 0x2772, 0x0000 }, { 0x9200, 0x2775, 0x2000 }, { 0x1600, 0x2774, 0x0000 }, { 0x0f00, 0x2776, 0x0000 }, { 0x8f00, 0x277f, 0x4000 }, { 0x8f00, 0x277b, 0x3000 }, { 0x8f00, 0x2779, 0x2000 }, { 0x0f00, 0x2778, 0x0000 }, { 0x0f00, 0x277a, 0x0000 }, { 0x8f00, 0x277d, 0x2000 }, { 0x0f00, 0x277c, 0x0000 }, { 0x0f00, 0x277e, 0x0000 }, { 0x8f00, 0x2783, 0x3000 }, { 0x8f00, 0x2781, 0x2000 }, { 0x0f00, 0x2780, 0x0000 }, { 0x0f00, 0x2782, 0x0000 }, { 0x8f00, 0x2785, 0x2000 }, { 0x0f00, 0x2784, 0x0000 }, { 0x0f00, 0x2786, 0x0000 }, { 0x9900, 0x29a0, 0xa000 }, { 0x9a00, 0x28a0, 0x9000 }, { 0x9a00, 0x2820, 0x8000 }, { 0x9900, 0x27dc, 0x7000 }, { 0x9a00, 0x27aa, 0x6000 }, { 0x9a00, 0x279a, 0x5000 }, { 0x8f00, 0x278f, 0x4000 }, { 0x8f00, 0x278b, 0x3000 }, { 0x8f00, 0x2789, 0x2000 }, { 0x0f00, 0x2788, 0x0000 }, { 0x0f00, 0x278a, 0x0000 }, { 0x8f00, 0x278d, 0x2000 }, { 0x0f00, 0x278c, 0x0000 }, { 0x0f00, 0x278e, 0x0000 }, { 0x8f00, 0x2793, 0x3000 }, { 0x8f00, 0x2791, 0x2000 }, { 0x0f00, 0x2790, 0x0000 }, { 0x0f00, 0x2792, 0x0000 }, { 0x9a00, 0x2798, 0x2000 }, { 0x1a00, 0x2794, 0x0000 }, { 0x1a00, 0x2799, 0x0000 }, { 0x9a00, 0x27a2, 0x4000 }, { 0x9a00, 0x279e, 0x3000 }, { 0x9a00, 0x279c, 0x2000 }, { 0x1a00, 0x279b, 0x0000 }, { 0x1a00, 0x279d, 0x0000 }, { 0x9a00, 0x27a0, 0x2000 }, { 0x1a00, 0x279f, 0x0000 }, { 0x1a00, 0x27a1, 0x0000 }, { 0x9a00, 0x27a6, 0x3000 }, { 0x9a00, 0x27a4, 0x2000 }, { 0x1a00, 0x27a3, 0x0000 }, { 0x1a00, 0x27a5, 0x0000 }, { 0x9a00, 0x27a8, 0x2000 }, { 0x1a00, 0x27a7, 0x0000 }, { 0x1a00, 0x27a9, 0x0000 }, { 0x9a00, 0x27bb, 0x5000 }, { 0x9a00, 0x27b3, 0x4000 }, { 0x9a00, 0x27ae, 0x3000 }, { 0x9a00, 0x27ac, 0x2000 }, { 0x1a00, 0x27ab, 0x0000 }, { 0x1a00, 0x27ad, 0x0000 }, { 0x9a00, 0x27b1, 0x2000 }, { 0x1a00, 0x27af, 0x0000 }, { 0x1a00, 0x27b2, 0x0000 }, { 0x9a00, 0x27b7, 0x3000 }, { 0x9a00, 0x27b5, 0x2000 }, { 0x1a00, 0x27b4, 0x0000 }, { 0x1a00, 0x27b6, 0x0000 }, { 0x9a00, 0x27b9, 0x2000 }, { 0x1a00, 0x27b8, 0x0000 }, { 0x1a00, 0x27ba, 0x0000 }, { 0x9900, 0x27d4, 0x4000 }, { 0x9900, 0x27d0, 0x3000 }, { 0x9a00, 0x27bd, 0x2000 }, { 0x1a00, 0x27bc, 0x0000 }, { 0x1a00, 0x27be, 0x0000 }, { 0x9900, 0x27d2, 0x2000 }, { 0x1900, 0x27d1, 0x0000 }, { 0x1900, 0x27d3, 0x0000 }, { 0x9900, 0x27d8, 0x3000 }, { 0x9900, 0x27d6, 0x2000 }, { 0x1900, 0x27d5, 0x0000 }, { 0x1900, 0x27d7, 0x0000 }, { 0x9900, 0x27da, 0x2000 }, { 0x1900, 0x27d9, 0x0000 }, { 0x1900, 0x27db, 0x0000 }, { 0x9a00, 0x2800, 0x6000 }, { 0x9900, 0x27f0, 0x5000 }, { 0x9900, 0x27e4, 0x4000 }, { 0x9900, 0x27e0, 0x3000 }, { 0x9900, 0x27de, 0x2000 }, { 0x1900, 0x27dd, 0x0000 }, { 0x1900, 0x27df, 0x0000 }, { 0x9900, 0x27e2, 0x2000 }, { 0x1900, 0x27e1, 0x0000 }, { 0x1900, 0x27e3, 0x0000 }, { 0x9600, 0x27e8, 0x3000 }, { 0x9600, 0x27e6, 0x2000 }, { 0x1900, 0x27e5, 0x0000 }, { 0x1200, 0x27e7, 0x0000 }, { 0x9600, 0x27ea, 0x2000 }, { 0x1200, 0x27e9, 0x0000 }, { 0x1200, 0x27eb, 0x0000 }, { 0x9900, 0x27f8, 0x4000 }, { 0x9900, 0x27f4, 0x3000 }, { 0x9900, 0x27f2, 0x2000 }, { 0x1900, 0x27f1, 0x0000 }, { 0x1900, 0x27f3, 0x0000 }, { 0x9900, 0x27f6, 0x2000 }, { 0x1900, 0x27f5, 0x0000 }, { 0x1900, 0x27f7, 0x0000 }, { 0x9900, 0x27fc, 0x3000 }, { 0x9900, 0x27fa, 0x2000 }, { 0x1900, 0x27f9, 0x0000 }, { 0x1900, 0x27fb, 0x0000 }, { 0x9900, 0x27fe, 0x2000 }, { 0x1900, 0x27fd, 0x0000 }, { 0x1900, 0x27ff, 0x0000 }, { 0x9a00, 0x2810, 0x5000 }, { 0x9a00, 0x2808, 0x4000 }, { 0x9a00, 0x2804, 0x3000 }, { 0x9a00, 0x2802, 0x2000 }, { 0x1a00, 0x2801, 0x0000 }, { 0x1a00, 0x2803, 0x0000 }, { 0x9a00, 0x2806, 0x2000 }, { 0x1a00, 0x2805, 0x0000 }, { 0x1a00, 0x2807, 0x0000 }, { 0x9a00, 0x280c, 0x3000 }, { 0x9a00, 0x280a, 0x2000 }, { 0x1a00, 0x2809, 0x0000 }, { 0x1a00, 0x280b, 0x0000 }, { 0x9a00, 0x280e, 0x2000 }, { 0x1a00, 0x280d, 0x0000 }, { 0x1a00, 0x280f, 0x0000 }, { 0x9a00, 0x2818, 0x4000 }, { 0x9a00, 0x2814, 0x3000 }, { 0x9a00, 0x2812, 0x2000 }, { 0x1a00, 0x2811, 0x0000 }, { 0x1a00, 0x2813, 0x0000 }, { 0x9a00, 0x2816, 0x2000 }, { 0x1a00, 0x2815, 0x0000 }, { 0x1a00, 0x2817, 0x0000 }, { 0x9a00, 0x281c, 0x3000 }, { 0x9a00, 0x281a, 0x2000 }, { 0x1a00, 0x2819, 0x0000 }, { 0x1a00, 0x281b, 0x0000 }, { 0x9a00, 0x281e, 0x2000 }, { 0x1a00, 0x281d, 0x0000 }, { 0x1a00, 0x281f, 0x0000 }, { 0x9a00, 0x2860, 0x7000 }, { 0x9a00, 0x2840, 0x6000 }, { 0x9a00, 0x2830, 0x5000 }, { 0x9a00, 0x2828, 0x4000 }, { 0x9a00, 0x2824, 0x3000 }, { 0x9a00, 0x2822, 0x2000 }, { 0x1a00, 0x2821, 0x0000 }, { 0x1a00, 0x2823, 0x0000 }, { 0x9a00, 0x2826, 0x2000 }, { 0x1a00, 0x2825, 0x0000 }, { 0x1a00, 0x2827, 0x0000 }, { 0x9a00, 0x282c, 0x3000 }, { 0x9a00, 0x282a, 0x2000 }, { 0x1a00, 0x2829, 0x0000 }, { 0x1a00, 0x282b, 0x0000 }, { 0x9a00, 0x282e, 0x2000 }, { 0x1a00, 0x282d, 0x0000 }, { 0x1a00, 0x282f, 0x0000 }, { 0x9a00, 0x2838, 0x4000 }, { 0x9a00, 0x2834, 0x3000 }, { 0x9a00, 0x2832, 0x2000 }, { 0x1a00, 0x2831, 0x0000 }, { 0x1a00, 0x2833, 0x0000 }, { 0x9a00, 0x2836, 0x2000 }, { 0x1a00, 0x2835, 0x0000 }, { 0x1a00, 0x2837, 0x0000 }, { 0x9a00, 0x283c, 0x3000 }, { 0x9a00, 0x283a, 0x2000 }, { 0x1a00, 0x2839, 0x0000 }, { 0x1a00, 0x283b, 0x0000 }, { 0x9a00, 0x283e, 0x2000 }, { 0x1a00, 0x283d, 0x0000 }, { 0x1a00, 0x283f, 0x0000 }, { 0x9a00, 0x2850, 0x5000 }, { 0x9a00, 0x2848, 0x4000 }, { 0x9a00, 0x2844, 0x3000 }, { 0x9a00, 0x2842, 0x2000 }, { 0x1a00, 0x2841, 0x0000 }, { 0x1a00, 0x2843, 0x0000 }, { 0x9a00, 0x2846, 0x2000 }, { 0x1a00, 0x2845, 0x0000 }, { 0x1a00, 0x2847, 0x0000 }, { 0x9a00, 0x284c, 0x3000 }, { 0x9a00, 0x284a, 0x2000 }, { 0x1a00, 0x2849, 0x0000 }, { 0x1a00, 0x284b, 0x0000 }, { 0x9a00, 0x284e, 0x2000 }, { 0x1a00, 0x284d, 0x0000 }, { 0x1a00, 0x284f, 0x0000 }, { 0x9a00, 0x2858, 0x4000 }, { 0x9a00, 0x2854, 0x3000 }, { 0x9a00, 0x2852, 0x2000 }, { 0x1a00, 0x2851, 0x0000 }, { 0x1a00, 0x2853, 0x0000 }, { 0x9a00, 0x2856, 0x2000 }, { 0x1a00, 0x2855, 0x0000 }, { 0x1a00, 0x2857, 0x0000 }, { 0x9a00, 0x285c, 0x3000 }, { 0x9a00, 0x285a, 0x2000 }, { 0x1a00, 0x2859, 0x0000 }, { 0x1a00, 0x285b, 0x0000 }, { 0x9a00, 0x285e, 0x2000 }, { 0x1a00, 0x285d, 0x0000 }, { 0x1a00, 0x285f, 0x0000 }, { 0x9a00, 0x2880, 0x6000 }, { 0x9a00, 0x2870, 0x5000 }, { 0x9a00, 0x2868, 0x4000 }, { 0x9a00, 0x2864, 0x3000 }, { 0x9a00, 0x2862, 0x2000 }, { 0x1a00, 0x2861, 0x0000 }, { 0x1a00, 0x2863, 0x0000 }, { 0x9a00, 0x2866, 0x2000 }, { 0x1a00, 0x2865, 0x0000 }, { 0x1a00, 0x2867, 0x0000 }, { 0x9a00, 0x286c, 0x3000 }, { 0x9a00, 0x286a, 0x2000 }, { 0x1a00, 0x2869, 0x0000 }, { 0x1a00, 0x286b, 0x0000 }, { 0x9a00, 0x286e, 0x2000 }, { 0x1a00, 0x286d, 0x0000 }, { 0x1a00, 0x286f, 0x0000 }, { 0x9a00, 0x2878, 0x4000 }, { 0x9a00, 0x2874, 0x3000 }, { 0x9a00, 0x2872, 0x2000 }, { 0x1a00, 0x2871, 0x0000 }, { 0x1a00, 0x2873, 0x0000 }, { 0x9a00, 0x2876, 0x2000 }, { 0x1a00, 0x2875, 0x0000 }, { 0x1a00, 0x2877, 0x0000 }, { 0x9a00, 0x287c, 0x3000 }, { 0x9a00, 0x287a, 0x2000 }, { 0x1a00, 0x2879, 0x0000 }, { 0x1a00, 0x287b, 0x0000 }, { 0x9a00, 0x287e, 0x2000 }, { 0x1a00, 0x287d, 0x0000 }, { 0x1a00, 0x287f, 0x0000 }, { 0x9a00, 0x2890, 0x5000 }, { 0x9a00, 0x2888, 0x4000 }, { 0x9a00, 0x2884, 0x3000 }, { 0x9a00, 0x2882, 0x2000 }, { 0x1a00, 0x2881, 0x0000 }, { 0x1a00, 0x2883, 0x0000 }, { 0x9a00, 0x2886, 0x2000 }, { 0x1a00, 0x2885, 0x0000 }, { 0x1a00, 0x2887, 0x0000 }, { 0x9a00, 0x288c, 0x3000 }, { 0x9a00, 0x288a, 0x2000 }, { 0x1a00, 0x2889, 0x0000 }, { 0x1a00, 0x288b, 0x0000 }, { 0x9a00, 0x288e, 0x2000 }, { 0x1a00, 0x288d, 0x0000 }, { 0x1a00, 0x288f, 0x0000 }, { 0x9a00, 0x2898, 0x4000 }, { 0x9a00, 0x2894, 0x3000 }, { 0x9a00, 0x2892, 0x2000 }, { 0x1a00, 0x2891, 0x0000 }, { 0x1a00, 0x2893, 0x0000 }, { 0x9a00, 0x2896, 0x2000 }, { 0x1a00, 0x2895, 0x0000 }, { 0x1a00, 0x2897, 0x0000 }, { 0x9a00, 0x289c, 0x3000 }, { 0x9a00, 0x289a, 0x2000 }, { 0x1a00, 0x2899, 0x0000 }, { 0x1a00, 0x289b, 0x0000 }, { 0x9a00, 0x289e, 0x2000 }, { 0x1a00, 0x289d, 0x0000 }, { 0x1a00, 0x289f, 0x0000 }, { 0x9900, 0x2920, 0x8000 }, { 0x9a00, 0x28e0, 0x7000 }, { 0x9a00, 0x28c0, 0x6000 }, { 0x9a00, 0x28b0, 0x5000 }, { 0x9a00, 0x28a8, 0x4000 }, { 0x9a00, 0x28a4, 0x3000 }, { 0x9a00, 0x28a2, 0x2000 }, { 0x1a00, 0x28a1, 0x0000 }, { 0x1a00, 0x28a3, 0x0000 }, { 0x9a00, 0x28a6, 0x2000 }, { 0x1a00, 0x28a5, 0x0000 }, { 0x1a00, 0x28a7, 0x0000 }, { 0x9a00, 0x28ac, 0x3000 }, { 0x9a00, 0x28aa, 0x2000 }, { 0x1a00, 0x28a9, 0x0000 }, { 0x1a00, 0x28ab, 0x0000 }, { 0x9a00, 0x28ae, 0x2000 }, { 0x1a00, 0x28ad, 0x0000 }, { 0x1a00, 0x28af, 0x0000 }, { 0x9a00, 0x28b8, 0x4000 }, { 0x9a00, 0x28b4, 0x3000 }, { 0x9a00, 0x28b2, 0x2000 }, { 0x1a00, 0x28b1, 0x0000 }, { 0x1a00, 0x28b3, 0x0000 }, { 0x9a00, 0x28b6, 0x2000 }, { 0x1a00, 0x28b5, 0x0000 }, { 0x1a00, 0x28b7, 0x0000 }, { 0x9a00, 0x28bc, 0x3000 }, { 0x9a00, 0x28ba, 0x2000 }, { 0x1a00, 0x28b9, 0x0000 }, { 0x1a00, 0x28bb, 0x0000 }, { 0x9a00, 0x28be, 0x2000 }, { 0x1a00, 0x28bd, 0x0000 }, { 0x1a00, 0x28bf, 0x0000 }, { 0x9a00, 0x28d0, 0x5000 }, { 0x9a00, 0x28c8, 0x4000 }, { 0x9a00, 0x28c4, 0x3000 }, { 0x9a00, 0x28c2, 0x2000 }, { 0x1a00, 0x28c1, 0x0000 }, { 0x1a00, 0x28c3, 0x0000 }, { 0x9a00, 0x28c6, 0x2000 }, { 0x1a00, 0x28c5, 0x0000 }, { 0x1a00, 0x28c7, 0x0000 }, { 0x9a00, 0x28cc, 0x3000 }, { 0x9a00, 0x28ca, 0x2000 }, { 0x1a00, 0x28c9, 0x0000 }, { 0x1a00, 0x28cb, 0x0000 }, { 0x9a00, 0x28ce, 0x2000 }, { 0x1a00, 0x28cd, 0x0000 }, { 0x1a00, 0x28cf, 0x0000 }, { 0x9a00, 0x28d8, 0x4000 }, { 0x9a00, 0x28d4, 0x3000 }, { 0x9a00, 0x28d2, 0x2000 }, { 0x1a00, 0x28d1, 0x0000 }, { 0x1a00, 0x28d3, 0x0000 }, { 0x9a00, 0x28d6, 0x2000 }, { 0x1a00, 0x28d5, 0x0000 }, { 0x1a00, 0x28d7, 0x0000 }, { 0x9a00, 0x28dc, 0x3000 }, { 0x9a00, 0x28da, 0x2000 }, { 0x1a00, 0x28d9, 0x0000 }, { 0x1a00, 0x28db, 0x0000 }, { 0x9a00, 0x28de, 0x2000 }, { 0x1a00, 0x28dd, 0x0000 }, { 0x1a00, 0x28df, 0x0000 }, { 0x9900, 0x2900, 0x6000 }, { 0x9a00, 0x28f0, 0x5000 }, { 0x9a00, 0x28e8, 0x4000 }, { 0x9a00, 0x28e4, 0x3000 }, { 0x9a00, 0x28e2, 0x2000 }, { 0x1a00, 0x28e1, 0x0000 }, { 0x1a00, 0x28e3, 0x0000 }, { 0x9a00, 0x28e6, 0x2000 }, { 0x1a00, 0x28e5, 0x0000 }, { 0x1a00, 0x28e7, 0x0000 }, { 0x9a00, 0x28ec, 0x3000 }, { 0x9a00, 0x28ea, 0x2000 }, { 0x1a00, 0x28e9, 0x0000 }, { 0x1a00, 0x28eb, 0x0000 }, { 0x9a00, 0x28ee, 0x2000 }, { 0x1a00, 0x28ed, 0x0000 }, { 0x1a00, 0x28ef, 0x0000 }, { 0x9a00, 0x28f8, 0x4000 }, { 0x9a00, 0x28f4, 0x3000 }, { 0x9a00, 0x28f2, 0x2000 }, { 0x1a00, 0x28f1, 0x0000 }, { 0x1a00, 0x28f3, 0x0000 }, { 0x9a00, 0x28f6, 0x2000 }, { 0x1a00, 0x28f5, 0x0000 }, { 0x1a00, 0x28f7, 0x0000 }, { 0x9a00, 0x28fc, 0x3000 }, { 0x9a00, 0x28fa, 0x2000 }, { 0x1a00, 0x28f9, 0x0000 }, { 0x1a00, 0x28fb, 0x0000 }, { 0x9a00, 0x28fe, 0x2000 }, { 0x1a00, 0x28fd, 0x0000 }, { 0x1a00, 0x28ff, 0x0000 }, { 0x9900, 0x2910, 0x5000 }, { 0x9900, 0x2908, 0x4000 }, { 0x9900, 0x2904, 0x3000 }, { 0x9900, 0x2902, 0x2000 }, { 0x1900, 0x2901, 0x0000 }, { 0x1900, 0x2903, 0x0000 }, { 0x9900, 0x2906, 0x2000 }, { 0x1900, 0x2905, 0x0000 }, { 0x1900, 0x2907, 0x0000 }, { 0x9900, 0x290c, 0x3000 }, { 0x9900, 0x290a, 0x2000 }, { 0x1900, 0x2909, 0x0000 }, { 0x1900, 0x290b, 0x0000 }, { 0x9900, 0x290e, 0x2000 }, { 0x1900, 0x290d, 0x0000 }, { 0x1900, 0x290f, 0x0000 }, { 0x9900, 0x2918, 0x4000 }, { 0x9900, 0x2914, 0x3000 }, { 0x9900, 0x2912, 0x2000 }, { 0x1900, 0x2911, 0x0000 }, { 0x1900, 0x2913, 0x0000 }, { 0x9900, 0x2916, 0x2000 }, { 0x1900, 0x2915, 0x0000 }, { 0x1900, 0x2917, 0x0000 }, { 0x9900, 0x291c, 0x3000 }, { 0x9900, 0x291a, 0x2000 }, { 0x1900, 0x2919, 0x0000 }, { 0x1900, 0x291b, 0x0000 }, { 0x9900, 0x291e, 0x2000 }, { 0x1900, 0x291d, 0x0000 }, { 0x1900, 0x291f, 0x0000 }, { 0x9900, 0x2960, 0x7000 }, { 0x9900, 0x2940, 0x6000 }, { 0x9900, 0x2930, 0x5000 }, { 0x9900, 0x2928, 0x4000 }, { 0x9900, 0x2924, 0x3000 }, { 0x9900, 0x2922, 0x2000 }, { 0x1900, 0x2921, 0x0000 }, { 0x1900, 0x2923, 0x0000 }, { 0x9900, 0x2926, 0x2000 }, { 0x1900, 0x2925, 0x0000 }, { 0x1900, 0x2927, 0x0000 }, { 0x9900, 0x292c, 0x3000 }, { 0x9900, 0x292a, 0x2000 }, { 0x1900, 0x2929, 0x0000 }, { 0x1900, 0x292b, 0x0000 }, { 0x9900, 0x292e, 0x2000 }, { 0x1900, 0x292d, 0x0000 }, { 0x1900, 0x292f, 0x0000 }, { 0x9900, 0x2938, 0x4000 }, { 0x9900, 0x2934, 0x3000 }, { 0x9900, 0x2932, 0x2000 }, { 0x1900, 0x2931, 0x0000 }, { 0x1900, 0x2933, 0x0000 }, { 0x9900, 0x2936, 0x2000 }, { 0x1900, 0x2935, 0x0000 }, { 0x1900, 0x2937, 0x0000 }, { 0x9900, 0x293c, 0x3000 }, { 0x9900, 0x293a, 0x2000 }, { 0x1900, 0x2939, 0x0000 }, { 0x1900, 0x293b, 0x0000 }, { 0x9900, 0x293e, 0x2000 }, { 0x1900, 0x293d, 0x0000 }, { 0x1900, 0x293f, 0x0000 }, { 0x9900, 0x2950, 0x5000 }, { 0x9900, 0x2948, 0x4000 }, { 0x9900, 0x2944, 0x3000 }, { 0x9900, 0x2942, 0x2000 }, { 0x1900, 0x2941, 0x0000 }, { 0x1900, 0x2943, 0x0000 }, { 0x9900, 0x2946, 0x2000 }, { 0x1900, 0x2945, 0x0000 }, { 0x1900, 0x2947, 0x0000 }, { 0x9900, 0x294c, 0x3000 }, { 0x9900, 0x294a, 0x2000 }, { 0x1900, 0x2949, 0x0000 }, { 0x1900, 0x294b, 0x0000 }, { 0x9900, 0x294e, 0x2000 }, { 0x1900, 0x294d, 0x0000 }, { 0x1900, 0x294f, 0x0000 }, { 0x9900, 0x2958, 0x4000 }, { 0x9900, 0x2954, 0x3000 }, { 0x9900, 0x2952, 0x2000 }, { 0x1900, 0x2951, 0x0000 }, { 0x1900, 0x2953, 0x0000 }, { 0x9900, 0x2956, 0x2000 }, { 0x1900, 0x2955, 0x0000 }, { 0x1900, 0x2957, 0x0000 }, { 0x9900, 0x295c, 0x3000 }, { 0x9900, 0x295a, 0x2000 }, { 0x1900, 0x2959, 0x0000 }, { 0x1900, 0x295b, 0x0000 }, { 0x9900, 0x295e, 0x2000 }, { 0x1900, 0x295d, 0x0000 }, { 0x1900, 0x295f, 0x0000 }, { 0x9900, 0x2980, 0x6000 }, { 0x9900, 0x2970, 0x5000 }, { 0x9900, 0x2968, 0x4000 }, { 0x9900, 0x2964, 0x3000 }, { 0x9900, 0x2962, 0x2000 }, { 0x1900, 0x2961, 0x0000 }, { 0x1900, 0x2963, 0x0000 }, { 0x9900, 0x2966, 0x2000 }, { 0x1900, 0x2965, 0x0000 }, { 0x1900, 0x2967, 0x0000 }, { 0x9900, 0x296c, 0x3000 }, { 0x9900, 0x296a, 0x2000 }, { 0x1900, 0x2969, 0x0000 }, { 0x1900, 0x296b, 0x0000 }, { 0x9900, 0x296e, 0x2000 }, { 0x1900, 0x296d, 0x0000 }, { 0x1900, 0x296f, 0x0000 }, { 0x9900, 0x2978, 0x4000 }, { 0x9900, 0x2974, 0x3000 }, { 0x9900, 0x2972, 0x2000 }, { 0x1900, 0x2971, 0x0000 }, { 0x1900, 0x2973, 0x0000 }, { 0x9900, 0x2976, 0x2000 }, { 0x1900, 0x2975, 0x0000 }, { 0x1900, 0x2977, 0x0000 }, { 0x9900, 0x297c, 0x3000 }, { 0x9900, 0x297a, 0x2000 }, { 0x1900, 0x2979, 0x0000 }, { 0x1900, 0x297b, 0x0000 }, { 0x9900, 0x297e, 0x2000 }, { 0x1900, 0x297d, 0x0000 }, { 0x1900, 0x297f, 0x0000 }, { 0x9200, 0x2990, 0x5000 }, { 0x9200, 0x2988, 0x4000 }, { 0x9200, 0x2984, 0x3000 }, { 0x9900, 0x2982, 0x2000 }, { 0x1900, 0x2981, 0x0000 }, { 0x1600, 0x2983, 0x0000 }, { 0x9200, 0x2986, 0x2000 }, { 0x1600, 0x2985, 0x0000 }, { 0x1600, 0x2987, 0x0000 }, { 0x9200, 0x298c, 0x3000 }, { 0x9200, 0x298a, 0x2000 }, { 0x1600, 0x2989, 0x0000 }, { 0x1600, 0x298b, 0x0000 }, { 0x9200, 0x298e, 0x2000 }, { 0x1600, 0x298d, 0x0000 }, { 0x1600, 0x298f, 0x0000 }, { 0x9200, 0x2998, 0x4000 }, { 0x9200, 0x2994, 0x3000 }, { 0x9200, 0x2992, 0x2000 }, { 0x1600, 0x2991, 0x0000 }, { 0x1600, 0x2993, 0x0000 }, { 0x9200, 0x2996, 0x2000 }, { 0x1600, 0x2995, 0x0000 }, { 0x1600, 0x2997, 0x0000 }, { 0x9900, 0x299c, 0x3000 }, { 0x9900, 0x299a, 0x2000 }, { 0x1900, 0x2999, 0x0000 }, { 0x1900, 0x299b, 0x0000 }, { 0x9900, 0x299e, 0x2000 }, { 0x1900, 0x299d, 0x0000 }, { 0x1900, 0x299f, 0x0000 }, { 0x9900, 0x2aa0, 0x9000 }, { 0x9900, 0x2a20, 0x8000 }, { 0x9900, 0x29e0, 0x7000 }, { 0x9900, 0x29c0, 0x6000 }, { 0x9900, 0x29b0, 0x5000 }, { 0x9900, 0x29a8, 0x4000 }, { 0x9900, 0x29a4, 0x3000 }, { 0x9900, 0x29a2, 0x2000 }, { 0x1900, 0x29a1, 0x0000 }, { 0x1900, 0x29a3, 0x0000 }, { 0x9900, 0x29a6, 0x2000 }, { 0x1900, 0x29a5, 0x0000 }, { 0x1900, 0x29a7, 0x0000 }, { 0x9900, 0x29ac, 0x3000 }, { 0x9900, 0x29aa, 0x2000 }, { 0x1900, 0x29a9, 0x0000 }, { 0x1900, 0x29ab, 0x0000 }, { 0x9900, 0x29ae, 0x2000 }, { 0x1900, 0x29ad, 0x0000 }, { 0x1900, 0x29af, 0x0000 }, { 0x9900, 0x29b8, 0x4000 }, { 0x9900, 0x29b4, 0x3000 }, { 0x9900, 0x29b2, 0x2000 }, { 0x1900, 0x29b1, 0x0000 }, { 0x1900, 0x29b3, 0x0000 }, { 0x9900, 0x29b6, 0x2000 }, { 0x1900, 0x29b5, 0x0000 }, { 0x1900, 0x29b7, 0x0000 }, { 0x9900, 0x29bc, 0x3000 }, { 0x9900, 0x29ba, 0x2000 }, { 0x1900, 0x29b9, 0x0000 }, { 0x1900, 0x29bb, 0x0000 }, { 0x9900, 0x29be, 0x2000 }, { 0x1900, 0x29bd, 0x0000 }, { 0x1900, 0x29bf, 0x0000 }, { 0x9900, 0x29d0, 0x5000 }, { 0x9900, 0x29c8, 0x4000 }, { 0x9900, 0x29c4, 0x3000 }, { 0x9900, 0x29c2, 0x2000 }, { 0x1900, 0x29c1, 0x0000 }, { 0x1900, 0x29c3, 0x0000 }, { 0x9900, 0x29c6, 0x2000 }, { 0x1900, 0x29c5, 0x0000 }, { 0x1900, 0x29c7, 0x0000 }, { 0x9900, 0x29cc, 0x3000 }, { 0x9900, 0x29ca, 0x2000 }, { 0x1900, 0x29c9, 0x0000 }, { 0x1900, 0x29cb, 0x0000 }, { 0x9900, 0x29ce, 0x2000 }, { 0x1900, 0x29cd, 0x0000 }, { 0x1900, 0x29cf, 0x0000 }, { 0x9600, 0x29d8, 0x4000 }, { 0x9900, 0x29d4, 0x3000 }, { 0x9900, 0x29d2, 0x2000 }, { 0x1900, 0x29d1, 0x0000 }, { 0x1900, 0x29d3, 0x0000 }, { 0x9900, 0x29d6, 0x2000 }, { 0x1900, 0x29d5, 0x0000 }, { 0x1900, 0x29d7, 0x0000 }, { 0x9900, 0x29dc, 0x3000 }, { 0x9600, 0x29da, 0x2000 }, { 0x1200, 0x29d9, 0x0000 }, { 0x1200, 0x29db, 0x0000 }, { 0x9900, 0x29de, 0x2000 }, { 0x1900, 0x29dd, 0x0000 }, { 0x1900, 0x29df, 0x0000 }, { 0x9900, 0x2a00, 0x6000 }, { 0x9900, 0x29f0, 0x5000 }, { 0x9900, 0x29e8, 0x4000 }, { 0x9900, 0x29e4, 0x3000 }, { 0x9900, 0x29e2, 0x2000 }, { 0x1900, 0x29e1, 0x0000 }, { 0x1900, 0x29e3, 0x0000 }, { 0x9900, 0x29e6, 0x2000 }, { 0x1900, 0x29e5, 0x0000 }, { 0x1900, 0x29e7, 0x0000 }, { 0x9900, 0x29ec, 0x3000 }, { 0x9900, 0x29ea, 0x2000 }, { 0x1900, 0x29e9, 0x0000 }, { 0x1900, 0x29eb, 0x0000 }, { 0x9900, 0x29ee, 0x2000 }, { 0x1900, 0x29ed, 0x0000 }, { 0x1900, 0x29ef, 0x0000 }, { 0x9900, 0x29f8, 0x4000 }, { 0x9900, 0x29f4, 0x3000 }, { 0x9900, 0x29f2, 0x2000 }, { 0x1900, 0x29f1, 0x0000 }, { 0x1900, 0x29f3, 0x0000 }, { 0x9900, 0x29f6, 0x2000 }, { 0x1900, 0x29f5, 0x0000 }, { 0x1900, 0x29f7, 0x0000 }, { 0x9600, 0x29fc, 0x3000 }, { 0x9900, 0x29fa, 0x2000 }, { 0x1900, 0x29f9, 0x0000 }, { 0x1900, 0x29fb, 0x0000 }, { 0x9900, 0x29fe, 0x2000 }, { 0x1200, 0x29fd, 0x0000 }, { 0x1900, 0x29ff, 0x0000 }, { 0x9900, 0x2a10, 0x5000 }, { 0x9900, 0x2a08, 0x4000 }, { 0x9900, 0x2a04, 0x3000 }, { 0x9900, 0x2a02, 0x2000 }, { 0x1900, 0x2a01, 0x0000 }, { 0x1900, 0x2a03, 0x0000 }, { 0x9900, 0x2a06, 0x2000 }, { 0x1900, 0x2a05, 0x0000 }, { 0x1900, 0x2a07, 0x0000 }, { 0x9900, 0x2a0c, 0x3000 }, { 0x9900, 0x2a0a, 0x2000 }, { 0x1900, 0x2a09, 0x0000 }, { 0x1900, 0x2a0b, 0x0000 }, { 0x9900, 0x2a0e, 0x2000 }, { 0x1900, 0x2a0d, 0x0000 }, { 0x1900, 0x2a0f, 0x0000 }, { 0x9900, 0x2a18, 0x4000 }, { 0x9900, 0x2a14, 0x3000 }, { 0x9900, 0x2a12, 0x2000 }, { 0x1900, 0x2a11, 0x0000 }, { 0x1900, 0x2a13, 0x0000 }, { 0x9900, 0x2a16, 0x2000 }, { 0x1900, 0x2a15, 0x0000 }, { 0x1900, 0x2a17, 0x0000 }, { 0x9900, 0x2a1c, 0x3000 }, { 0x9900, 0x2a1a, 0x2000 }, { 0x1900, 0x2a19, 0x0000 }, { 0x1900, 0x2a1b, 0x0000 }, { 0x9900, 0x2a1e, 0x2000 }, { 0x1900, 0x2a1d, 0x0000 }, { 0x1900, 0x2a1f, 0x0000 }, { 0x9900, 0x2a60, 0x7000 }, { 0x9900, 0x2a40, 0x6000 }, { 0x9900, 0x2a30, 0x5000 }, { 0x9900, 0x2a28, 0x4000 }, { 0x9900, 0x2a24, 0x3000 }, { 0x9900, 0x2a22, 0x2000 }, { 0x1900, 0x2a21, 0x0000 }, { 0x1900, 0x2a23, 0x0000 }, { 0x9900, 0x2a26, 0x2000 }, { 0x1900, 0x2a25, 0x0000 }, { 0x1900, 0x2a27, 0x0000 }, { 0x9900, 0x2a2c, 0x3000 }, { 0x9900, 0x2a2a, 0x2000 }, { 0x1900, 0x2a29, 0x0000 }, { 0x1900, 0x2a2b, 0x0000 }, { 0x9900, 0x2a2e, 0x2000 }, { 0x1900, 0x2a2d, 0x0000 }, { 0x1900, 0x2a2f, 0x0000 }, { 0x9900, 0x2a38, 0x4000 }, { 0x9900, 0x2a34, 0x3000 }, { 0x9900, 0x2a32, 0x2000 }, { 0x1900, 0x2a31, 0x0000 }, { 0x1900, 0x2a33, 0x0000 }, { 0x9900, 0x2a36, 0x2000 }, { 0x1900, 0x2a35, 0x0000 }, { 0x1900, 0x2a37, 0x0000 }, { 0x9900, 0x2a3c, 0x3000 }, { 0x9900, 0x2a3a, 0x2000 }, { 0x1900, 0x2a39, 0x0000 }, { 0x1900, 0x2a3b, 0x0000 }, { 0x9900, 0x2a3e, 0x2000 }, { 0x1900, 0x2a3d, 0x0000 }, { 0x1900, 0x2a3f, 0x0000 }, { 0x9900, 0x2a50, 0x5000 }, { 0x9900, 0x2a48, 0x4000 }, { 0x9900, 0x2a44, 0x3000 }, { 0x9900, 0x2a42, 0x2000 }, { 0x1900, 0x2a41, 0x0000 }, { 0x1900, 0x2a43, 0x0000 }, { 0x9900, 0x2a46, 0x2000 }, { 0x1900, 0x2a45, 0x0000 }, { 0x1900, 0x2a47, 0x0000 }, { 0x9900, 0x2a4c, 0x3000 }, { 0x9900, 0x2a4a, 0x2000 }, { 0x1900, 0x2a49, 0x0000 }, { 0x1900, 0x2a4b, 0x0000 }, { 0x9900, 0x2a4e, 0x2000 }, { 0x1900, 0x2a4d, 0x0000 }, { 0x1900, 0x2a4f, 0x0000 }, { 0x9900, 0x2a58, 0x4000 }, { 0x9900, 0x2a54, 0x3000 }, { 0x9900, 0x2a52, 0x2000 }, { 0x1900, 0x2a51, 0x0000 }, { 0x1900, 0x2a53, 0x0000 }, { 0x9900, 0x2a56, 0x2000 }, { 0x1900, 0x2a55, 0x0000 }, { 0x1900, 0x2a57, 0x0000 }, { 0x9900, 0x2a5c, 0x3000 }, { 0x9900, 0x2a5a, 0x2000 }, { 0x1900, 0x2a59, 0x0000 }, { 0x1900, 0x2a5b, 0x0000 }, { 0x9900, 0x2a5e, 0x2000 }, { 0x1900, 0x2a5d, 0x0000 }, { 0x1900, 0x2a5f, 0x0000 }, { 0x9900, 0x2a80, 0x6000 }, { 0x9900, 0x2a70, 0x5000 }, { 0x9900, 0x2a68, 0x4000 }, { 0x9900, 0x2a64, 0x3000 }, { 0x9900, 0x2a62, 0x2000 }, { 0x1900, 0x2a61, 0x0000 }, { 0x1900, 0x2a63, 0x0000 }, { 0x9900, 0x2a66, 0x2000 }, { 0x1900, 0x2a65, 0x0000 }, { 0x1900, 0x2a67, 0x0000 }, { 0x9900, 0x2a6c, 0x3000 }, { 0x9900, 0x2a6a, 0x2000 }, { 0x1900, 0x2a69, 0x0000 }, { 0x1900, 0x2a6b, 0x0000 }, { 0x9900, 0x2a6e, 0x2000 }, { 0x1900, 0x2a6d, 0x0000 }, { 0x1900, 0x2a6f, 0x0000 }, { 0x9900, 0x2a78, 0x4000 }, { 0x9900, 0x2a74, 0x3000 }, { 0x9900, 0x2a72, 0x2000 }, { 0x1900, 0x2a71, 0x0000 }, { 0x1900, 0x2a73, 0x0000 }, { 0x9900, 0x2a76, 0x2000 }, { 0x1900, 0x2a75, 0x0000 }, { 0x1900, 0x2a77, 0x0000 }, { 0x9900, 0x2a7c, 0x3000 }, { 0x9900, 0x2a7a, 0x2000 }, { 0x1900, 0x2a79, 0x0000 }, { 0x1900, 0x2a7b, 0x0000 }, { 0x9900, 0x2a7e, 0x2000 }, { 0x1900, 0x2a7d, 0x0000 }, { 0x1900, 0x2a7f, 0x0000 }, { 0x9900, 0x2a90, 0x5000 }, { 0x9900, 0x2a88, 0x4000 }, { 0x9900, 0x2a84, 0x3000 }, { 0x9900, 0x2a82, 0x2000 }, { 0x1900, 0x2a81, 0x0000 }, { 0x1900, 0x2a83, 0x0000 }, { 0x9900, 0x2a86, 0x2000 }, { 0x1900, 0x2a85, 0x0000 }, { 0x1900, 0x2a87, 0x0000 }, { 0x9900, 0x2a8c, 0x3000 }, { 0x9900, 0x2a8a, 0x2000 }, { 0x1900, 0x2a89, 0x0000 }, { 0x1900, 0x2a8b, 0x0000 }, { 0x9900, 0x2a8e, 0x2000 }, { 0x1900, 0x2a8d, 0x0000 }, { 0x1900, 0x2a8f, 0x0000 }, { 0x9900, 0x2a98, 0x4000 }, { 0x9900, 0x2a94, 0x3000 }, { 0x9900, 0x2a92, 0x2000 }, { 0x1900, 0x2a91, 0x0000 }, { 0x1900, 0x2a93, 0x0000 }, { 0x9900, 0x2a96, 0x2000 }, { 0x1900, 0x2a95, 0x0000 }, { 0x1900, 0x2a97, 0x0000 }, { 0x9900, 0x2a9c, 0x3000 }, { 0x9900, 0x2a9a, 0x2000 }, { 0x1900, 0x2a99, 0x0000 }, { 0x1900, 0x2a9b, 0x0000 }, { 0x9900, 0x2a9e, 0x2000 }, { 0x1900, 0x2a9d, 0x0000 }, { 0x1900, 0x2a9f, 0x0000 }, { 0x9a00, 0x2e92, 0x8000 }, { 0x9900, 0x2ae0, 0x7000 }, { 0x9900, 0x2ac0, 0x6000 }, { 0x9900, 0x2ab0, 0x5000 }, { 0x9900, 0x2aa8, 0x4000 }, { 0x9900, 0x2aa4, 0x3000 }, { 0x9900, 0x2aa2, 0x2000 }, { 0x1900, 0x2aa1, 0x0000 }, { 0x1900, 0x2aa3, 0x0000 }, { 0x9900, 0x2aa6, 0x2000 }, { 0x1900, 0x2aa5, 0x0000 }, { 0x1900, 0x2aa7, 0x0000 }, { 0x9900, 0x2aac, 0x3000 }, { 0x9900, 0x2aaa, 0x2000 }, { 0x1900, 0x2aa9, 0x0000 }, { 0x1900, 0x2aab, 0x0000 }, { 0x9900, 0x2aae, 0x2000 }, { 0x1900, 0x2aad, 0x0000 }, { 0x1900, 0x2aaf, 0x0000 }, { 0x9900, 0x2ab8, 0x4000 }, { 0x9900, 0x2ab4, 0x3000 }, { 0x9900, 0x2ab2, 0x2000 }, { 0x1900, 0x2ab1, 0x0000 }, { 0x1900, 0x2ab3, 0x0000 }, { 0x9900, 0x2ab6, 0x2000 }, { 0x1900, 0x2ab5, 0x0000 }, { 0x1900, 0x2ab7, 0x0000 }, { 0x9900, 0x2abc, 0x3000 }, { 0x9900, 0x2aba, 0x2000 }, { 0x1900, 0x2ab9, 0x0000 }, { 0x1900, 0x2abb, 0x0000 }, { 0x9900, 0x2abe, 0x2000 }, { 0x1900, 0x2abd, 0x0000 }, { 0x1900, 0x2abf, 0x0000 }, { 0x9900, 0x2ad0, 0x5000 }, { 0x9900, 0x2ac8, 0x4000 }, { 0x9900, 0x2ac4, 0x3000 }, { 0x9900, 0x2ac2, 0x2000 }, { 0x1900, 0x2ac1, 0x0000 }, { 0x1900, 0x2ac3, 0x0000 }, { 0x9900, 0x2ac6, 0x2000 }, { 0x1900, 0x2ac5, 0x0000 }, { 0x1900, 0x2ac7, 0x0000 }, { 0x9900, 0x2acc, 0x3000 }, { 0x9900, 0x2aca, 0x2000 }, { 0x1900, 0x2ac9, 0x0000 }, { 0x1900, 0x2acb, 0x0000 }, { 0x9900, 0x2ace, 0x2000 }, { 0x1900, 0x2acd, 0x0000 }, { 0x1900, 0x2acf, 0x0000 }, { 0x9900, 0x2ad8, 0x4000 }, { 0x9900, 0x2ad4, 0x3000 }, { 0x9900, 0x2ad2, 0x2000 }, { 0x1900, 0x2ad1, 0x0000 }, { 0x1900, 0x2ad3, 0x0000 }, { 0x9900, 0x2ad6, 0x2000 }, { 0x1900, 0x2ad5, 0x0000 }, { 0x1900, 0x2ad7, 0x0000 }, { 0x9900, 0x2adc, 0x3000 }, { 0x9900, 0x2ada, 0x2000 }, { 0x1900, 0x2ad9, 0x0000 }, { 0x1900, 0x2adb, 0x0000 }, { 0x9900, 0x2ade, 0x2000 }, { 0x1900, 0x2add, 0x0000 }, { 0x1900, 0x2adf, 0x0000 }, { 0x9a00, 0x2b00, 0x6000 }, { 0x9900, 0x2af0, 0x5000 }, { 0x9900, 0x2ae8, 0x4000 }, { 0x9900, 0x2ae4, 0x3000 }, { 0x9900, 0x2ae2, 0x2000 }, { 0x1900, 0x2ae1, 0x0000 }, { 0x1900, 0x2ae3, 0x0000 }, { 0x9900, 0x2ae6, 0x2000 }, { 0x1900, 0x2ae5, 0x0000 }, { 0x1900, 0x2ae7, 0x0000 }, { 0x9900, 0x2aec, 0x3000 }, { 0x9900, 0x2aea, 0x2000 }, { 0x1900, 0x2ae9, 0x0000 }, { 0x1900, 0x2aeb, 0x0000 }, { 0x9900, 0x2aee, 0x2000 }, { 0x1900, 0x2aed, 0x0000 }, { 0x1900, 0x2aef, 0x0000 }, { 0x9900, 0x2af8, 0x4000 }, { 0x9900, 0x2af4, 0x3000 }, { 0x9900, 0x2af2, 0x2000 }, { 0x1900, 0x2af1, 0x0000 }, { 0x1900, 0x2af3, 0x0000 }, { 0x9900, 0x2af6, 0x2000 }, { 0x1900, 0x2af5, 0x0000 }, { 0x1900, 0x2af7, 0x0000 }, { 0x9900, 0x2afc, 0x3000 }, { 0x9900, 0x2afa, 0x2000 }, { 0x1900, 0x2af9, 0x0000 }, { 0x1900, 0x2afb, 0x0000 }, { 0x9900, 0x2afe, 0x2000 }, { 0x1900, 0x2afd, 0x0000 }, { 0x1900, 0x2aff, 0x0000 }, { 0x9a00, 0x2e82, 0x5000 }, { 0x9a00, 0x2b08, 0x4000 }, { 0x9a00, 0x2b04, 0x3000 }, { 0x9a00, 0x2b02, 0x2000 }, { 0x1a00, 0x2b01, 0x0000 }, { 0x1a00, 0x2b03, 0x0000 }, { 0x9a00, 0x2b06, 0x2000 }, { 0x1a00, 0x2b05, 0x0000 }, { 0x1a00, 0x2b07, 0x0000 }, { 0x9a00, 0x2b0c, 0x3000 }, { 0x9a00, 0x2b0a, 0x2000 }, { 0x1a00, 0x2b09, 0x0000 }, { 0x1a00, 0x2b0b, 0x0000 }, { 0x9a00, 0x2e80, 0x2000 }, { 0x1a00, 0x2b0d, 0x0000 }, { 0x1a00, 0x2e81, 0x0000 }, { 0x9a00, 0x2e8a, 0x4000 }, { 0x9a00, 0x2e86, 0x3000 }, { 0x9a00, 0x2e84, 0x2000 }, { 0x1a00, 0x2e83, 0x0000 }, { 0x1a00, 0x2e85, 0x0000 }, { 0x9a00, 0x2e88, 0x2000 }, { 0x1a00, 0x2e87, 0x0000 }, { 0x1a00, 0x2e89, 0x0000 }, { 0x9a00, 0x2e8e, 0x3000 }, { 0x9a00, 0x2e8c, 0x2000 }, { 0x1a00, 0x2e8b, 0x0000 }, { 0x1a00, 0x2e8d, 0x0000 }, { 0x9a00, 0x2e90, 0x2000 }, { 0x1a00, 0x2e8f, 0x0000 }, { 0x1a00, 0x2e91, 0x0000 }, { 0x9a00, 0x2ed3, 0x7000 }, { 0x9a00, 0x2eb3, 0x6000 }, { 0x9a00, 0x2ea3, 0x5000 }, { 0x9a00, 0x2e9b, 0x4000 }, { 0x9a00, 0x2e96, 0x3000 }, { 0x9a00, 0x2e94, 0x2000 }, { 0x1a00, 0x2e93, 0x0000 }, { 0x1a00, 0x2e95, 0x0000 }, { 0x9a00, 0x2e98, 0x2000 }, { 0x1a00, 0x2e97, 0x0000 }, { 0x1a00, 0x2e99, 0x0000 }, { 0x9a00, 0x2e9f, 0x3000 }, { 0x9a00, 0x2e9d, 0x2000 }, { 0x1a00, 0x2e9c, 0x0000 }, { 0x1a00, 0x2e9e, 0x0000 }, { 0x9a00, 0x2ea1, 0x2000 }, { 0x1a00, 0x2ea0, 0x0000 }, { 0x1a00, 0x2ea2, 0x0000 }, { 0x9a00, 0x2eab, 0x4000 }, { 0x9a00, 0x2ea7, 0x3000 }, { 0x9a00, 0x2ea5, 0x2000 }, { 0x1a00, 0x2ea4, 0x0000 }, { 0x1a00, 0x2ea6, 0x0000 }, { 0x9a00, 0x2ea9, 0x2000 }, { 0x1a00, 0x2ea8, 0x0000 }, { 0x1a00, 0x2eaa, 0x0000 }, { 0x9a00, 0x2eaf, 0x3000 }, { 0x9a00, 0x2ead, 0x2000 }, { 0x1a00, 0x2eac, 0x0000 }, { 0x1a00, 0x2eae, 0x0000 }, { 0x9a00, 0x2eb1, 0x2000 }, { 0x1a00, 0x2eb0, 0x0000 }, { 0x1a00, 0x2eb2, 0x0000 }, { 0x9a00, 0x2ec3, 0x5000 }, { 0x9a00, 0x2ebb, 0x4000 }, { 0x9a00, 0x2eb7, 0x3000 }, { 0x9a00, 0x2eb5, 0x2000 }, { 0x1a00, 0x2eb4, 0x0000 }, { 0x1a00, 0x2eb6, 0x0000 }, { 0x9a00, 0x2eb9, 0x2000 }, { 0x1a00, 0x2eb8, 0x0000 }, { 0x1a00, 0x2eba, 0x0000 }, { 0x9a00, 0x2ebf, 0x3000 }, { 0x9a00, 0x2ebd, 0x2000 }, { 0x1a00, 0x2ebc, 0x0000 }, { 0x1a00, 0x2ebe, 0x0000 }, { 0x9a00, 0x2ec1, 0x2000 }, { 0x1a00, 0x2ec0, 0x0000 }, { 0x1a00, 0x2ec2, 0x0000 }, { 0x9a00, 0x2ecb, 0x4000 }, { 0x9a00, 0x2ec7, 0x3000 }, { 0x9a00, 0x2ec5, 0x2000 }, { 0x1a00, 0x2ec4, 0x0000 }, { 0x1a00, 0x2ec6, 0x0000 }, { 0x9a00, 0x2ec9, 0x2000 }, { 0x1a00, 0x2ec8, 0x0000 }, { 0x1a00, 0x2eca, 0x0000 }, { 0x9a00, 0x2ecf, 0x3000 }, { 0x9a00, 0x2ecd, 0x2000 }, { 0x1a00, 0x2ecc, 0x0000 }, { 0x1a00, 0x2ece, 0x0000 }, { 0x9a00, 0x2ed1, 0x2000 }, { 0x1a00, 0x2ed0, 0x0000 }, { 0x1a00, 0x2ed2, 0x0000 }, { 0x9a00, 0x2ef3, 0x6000 }, { 0x9a00, 0x2ee3, 0x5000 }, { 0x9a00, 0x2edb, 0x4000 }, { 0x9a00, 0x2ed7, 0x3000 }, { 0x9a00, 0x2ed5, 0x2000 }, { 0x1a00, 0x2ed4, 0x0000 }, { 0x1a00, 0x2ed6, 0x0000 }, { 0x9a00, 0x2ed9, 0x2000 }, { 0x1a00, 0x2ed8, 0x0000 }, { 0x1a00, 0x2eda, 0x0000 }, { 0x9a00, 0x2edf, 0x3000 }, { 0x9a00, 0x2edd, 0x2000 }, { 0x1a00, 0x2edc, 0x0000 }, { 0x1a00, 0x2ede, 0x0000 }, { 0x9a00, 0x2ee1, 0x2000 }, { 0x1a00, 0x2ee0, 0x0000 }, { 0x1a00, 0x2ee2, 0x0000 }, { 0x9a00, 0x2eeb, 0x4000 }, { 0x9a00, 0x2ee7, 0x3000 }, { 0x9a00, 0x2ee5, 0x2000 }, { 0x1a00, 0x2ee4, 0x0000 }, { 0x1a00, 0x2ee6, 0x0000 }, { 0x9a00, 0x2ee9, 0x2000 }, { 0x1a00, 0x2ee8, 0x0000 }, { 0x1a00, 0x2eea, 0x0000 }, { 0x9a00, 0x2eef, 0x3000 }, { 0x9a00, 0x2eed, 0x2000 }, { 0x1a00, 0x2eec, 0x0000 }, { 0x1a00, 0x2eee, 0x0000 }, { 0x9a00, 0x2ef1, 0x2000 }, { 0x1a00, 0x2ef0, 0x0000 }, { 0x1a00, 0x2ef2, 0x0000 }, { 0x9a00, 0x2f0f, 0x5000 }, { 0x9a00, 0x2f07, 0x4000 }, { 0x9a00, 0x2f03, 0x3000 }, { 0x9a00, 0x2f01, 0x2000 }, { 0x1a00, 0x2f00, 0x0000 }, { 0x1a00, 0x2f02, 0x0000 }, { 0x9a00, 0x2f05, 0x2000 }, { 0x1a00, 0x2f04, 0x0000 }, { 0x1a00, 0x2f06, 0x0000 }, { 0x9a00, 0x2f0b, 0x3000 }, { 0x9a00, 0x2f09, 0x2000 }, { 0x1a00, 0x2f08, 0x0000 }, { 0x1a00, 0x2f0a, 0x0000 }, { 0x9a00, 0x2f0d, 0x2000 }, { 0x1a00, 0x2f0c, 0x0000 }, { 0x1a00, 0x2f0e, 0x0000 }, { 0x9a00, 0x2f17, 0x4000 }, { 0x9a00, 0x2f13, 0x3000 }, { 0x9a00, 0x2f11, 0x2000 }, { 0x1a00, 0x2f10, 0x0000 }, { 0x1a00, 0x2f12, 0x0000 }, { 0x9a00, 0x2f15, 0x2000 }, { 0x1a00, 0x2f14, 0x0000 }, { 0x1a00, 0x2f16, 0x0000 }, { 0x9a00, 0x2f1b, 0x3000 }, { 0x9a00, 0x2f19, 0x2000 }, { 0x1a00, 0x2f18, 0x0000 }, { 0x1a00, 0x2f1a, 0x0000 }, { 0x9a00, 0x2f1d, 0x2000 }, { 0x1a00, 0x2f1c, 0x0000 }, { 0x1a00, 0x2f1e, 0x0000 }, { 0x8701, 0x00f0, 0xd000 }, { 0x8700, 0xa34d, 0xc000 }, { 0x9a00, 0x3391, 0xb000 }, { 0x8700, 0x3149, 0xa000 }, { 0x9500, 0x303d, 0x9000 }, { 0x9a00, 0x2f9f, 0x8000 }, { 0x9a00, 0x2f5f, 0x7000 }, { 0x9a00, 0x2f3f, 0x6000 }, { 0x9a00, 0x2f2f, 0x5000 }, { 0x9a00, 0x2f27, 0x4000 }, { 0x9a00, 0x2f23, 0x3000 }, { 0x9a00, 0x2f21, 0x2000 }, { 0x1a00, 0x2f20, 0x0000 }, { 0x1a00, 0x2f22, 0x0000 }, { 0x9a00, 0x2f25, 0x2000 }, { 0x1a00, 0x2f24, 0x0000 }, { 0x1a00, 0x2f26, 0x0000 }, { 0x9a00, 0x2f2b, 0x3000 }, { 0x9a00, 0x2f29, 0x2000 }, { 0x1a00, 0x2f28, 0x0000 }, { 0x1a00, 0x2f2a, 0x0000 }, { 0x9a00, 0x2f2d, 0x2000 }, { 0x1a00, 0x2f2c, 0x0000 }, { 0x1a00, 0x2f2e, 0x0000 }, { 0x9a00, 0x2f37, 0x4000 }, { 0x9a00, 0x2f33, 0x3000 }, { 0x9a00, 0x2f31, 0x2000 }, { 0x1a00, 0x2f30, 0x0000 }, { 0x1a00, 0x2f32, 0x0000 }, { 0x9a00, 0x2f35, 0x2000 }, { 0x1a00, 0x2f34, 0x0000 }, { 0x1a00, 0x2f36, 0x0000 }, { 0x9a00, 0x2f3b, 0x3000 }, { 0x9a00, 0x2f39, 0x2000 }, { 0x1a00, 0x2f38, 0x0000 }, { 0x1a00, 0x2f3a, 0x0000 }, { 0x9a00, 0x2f3d, 0x2000 }, { 0x1a00, 0x2f3c, 0x0000 }, { 0x1a00, 0x2f3e, 0x0000 }, { 0x9a00, 0x2f4f, 0x5000 }, { 0x9a00, 0x2f47, 0x4000 }, { 0x9a00, 0x2f43, 0x3000 }, { 0x9a00, 0x2f41, 0x2000 }, { 0x1a00, 0x2f40, 0x0000 }, { 0x1a00, 0x2f42, 0x0000 }, { 0x9a00, 0x2f45, 0x2000 }, { 0x1a00, 0x2f44, 0x0000 }, { 0x1a00, 0x2f46, 0x0000 }, { 0x9a00, 0x2f4b, 0x3000 }, { 0x9a00, 0x2f49, 0x2000 }, { 0x1a00, 0x2f48, 0x0000 }, { 0x1a00, 0x2f4a, 0x0000 }, { 0x9a00, 0x2f4d, 0x2000 }, { 0x1a00, 0x2f4c, 0x0000 }, { 0x1a00, 0x2f4e, 0x0000 }, { 0x9a00, 0x2f57, 0x4000 }, { 0x9a00, 0x2f53, 0x3000 }, { 0x9a00, 0x2f51, 0x2000 }, { 0x1a00, 0x2f50, 0x0000 }, { 0x1a00, 0x2f52, 0x0000 }, { 0x9a00, 0x2f55, 0x2000 }, { 0x1a00, 0x2f54, 0x0000 }, { 0x1a00, 0x2f56, 0x0000 }, { 0x9a00, 0x2f5b, 0x3000 }, { 0x9a00, 0x2f59, 0x2000 }, { 0x1a00, 0x2f58, 0x0000 }, { 0x1a00, 0x2f5a, 0x0000 }, { 0x9a00, 0x2f5d, 0x2000 }, { 0x1a00, 0x2f5c, 0x0000 }, { 0x1a00, 0x2f5e, 0x0000 }, { 0x9a00, 0x2f7f, 0x6000 }, { 0x9a00, 0x2f6f, 0x5000 }, { 0x9a00, 0x2f67, 0x4000 }, { 0x9a00, 0x2f63, 0x3000 }, { 0x9a00, 0x2f61, 0x2000 }, { 0x1a00, 0x2f60, 0x0000 }, { 0x1a00, 0x2f62, 0x0000 }, { 0x9a00, 0x2f65, 0x2000 }, { 0x1a00, 0x2f64, 0x0000 }, { 0x1a00, 0x2f66, 0x0000 }, { 0x9a00, 0x2f6b, 0x3000 }, { 0x9a00, 0x2f69, 0x2000 }, { 0x1a00, 0x2f68, 0x0000 }, { 0x1a00, 0x2f6a, 0x0000 }, { 0x9a00, 0x2f6d, 0x2000 }, { 0x1a00, 0x2f6c, 0x0000 }, { 0x1a00, 0x2f6e, 0x0000 }, { 0x9a00, 0x2f77, 0x4000 }, { 0x9a00, 0x2f73, 0x3000 }, { 0x9a00, 0x2f71, 0x2000 }, { 0x1a00, 0x2f70, 0x0000 }, { 0x1a00, 0x2f72, 0x0000 }, { 0x9a00, 0x2f75, 0x2000 }, { 0x1a00, 0x2f74, 0x0000 }, { 0x1a00, 0x2f76, 0x0000 }, { 0x9a00, 0x2f7b, 0x3000 }, { 0x9a00, 0x2f79, 0x2000 }, { 0x1a00, 0x2f78, 0x0000 }, { 0x1a00, 0x2f7a, 0x0000 }, { 0x9a00, 0x2f7d, 0x2000 }, { 0x1a00, 0x2f7c, 0x0000 }, { 0x1a00, 0x2f7e, 0x0000 }, { 0x9a00, 0x2f8f, 0x5000 }, { 0x9a00, 0x2f87, 0x4000 }, { 0x9a00, 0x2f83, 0x3000 }, { 0x9a00, 0x2f81, 0x2000 }, { 0x1a00, 0x2f80, 0x0000 }, { 0x1a00, 0x2f82, 0x0000 }, { 0x9a00, 0x2f85, 0x2000 }, { 0x1a00, 0x2f84, 0x0000 }, { 0x1a00, 0x2f86, 0x0000 }, { 0x9a00, 0x2f8b, 0x3000 }, { 0x9a00, 0x2f89, 0x2000 }, { 0x1a00, 0x2f88, 0x0000 }, { 0x1a00, 0x2f8a, 0x0000 }, { 0x9a00, 0x2f8d, 0x2000 }, { 0x1a00, 0x2f8c, 0x0000 }, { 0x1a00, 0x2f8e, 0x0000 }, { 0x9a00, 0x2f97, 0x4000 }, { 0x9a00, 0x2f93, 0x3000 }, { 0x9a00, 0x2f91, 0x2000 }, { 0x1a00, 0x2f90, 0x0000 }, { 0x1a00, 0x2f92, 0x0000 }, { 0x9a00, 0x2f95, 0x2000 }, { 0x1a00, 0x2f94, 0x0000 }, { 0x1a00, 0x2f96, 0x0000 }, { 0x9a00, 0x2f9b, 0x3000 }, { 0x9a00, 0x2f99, 0x2000 }, { 0x1a00, 0x2f98, 0x0000 }, { 0x1a00, 0x2f9a, 0x0000 }, { 0x9a00, 0x2f9d, 0x2000 }, { 0x1a00, 0x2f9c, 0x0000 }, { 0x1a00, 0x2f9e, 0x0000 }, { 0x9a00, 0x2ff9, 0x7000 }, { 0x9a00, 0x2fbf, 0x6000 }, { 0x9a00, 0x2faf, 0x5000 }, { 0x9a00, 0x2fa7, 0x4000 }, { 0x9a00, 0x2fa3, 0x3000 }, { 0x9a00, 0x2fa1, 0x2000 }, { 0x1a00, 0x2fa0, 0x0000 }, { 0x1a00, 0x2fa2, 0x0000 }, { 0x9a00, 0x2fa5, 0x2000 }, { 0x1a00, 0x2fa4, 0x0000 }, { 0x1a00, 0x2fa6, 0x0000 }, { 0x9a00, 0x2fab, 0x3000 }, { 0x9a00, 0x2fa9, 0x2000 }, { 0x1a00, 0x2fa8, 0x0000 }, { 0x1a00, 0x2faa, 0x0000 }, { 0x9a00, 0x2fad, 0x2000 }, { 0x1a00, 0x2fac, 0x0000 }, { 0x1a00, 0x2fae, 0x0000 }, { 0x9a00, 0x2fb7, 0x4000 }, { 0x9a00, 0x2fb3, 0x3000 }, { 0x9a00, 0x2fb1, 0x2000 }, { 0x1a00, 0x2fb0, 0x0000 }, { 0x1a00, 0x2fb2, 0x0000 }, { 0x9a00, 0x2fb5, 0x2000 }, { 0x1a00, 0x2fb4, 0x0000 }, { 0x1a00, 0x2fb6, 0x0000 }, { 0x9a00, 0x2fbb, 0x3000 }, { 0x9a00, 0x2fb9, 0x2000 }, { 0x1a00, 0x2fb8, 0x0000 }, { 0x1a00, 0x2fba, 0x0000 }, { 0x9a00, 0x2fbd, 0x2000 }, { 0x1a00, 0x2fbc, 0x0000 }, { 0x1a00, 0x2fbe, 0x0000 }, { 0x9a00, 0x2fcf, 0x5000 }, { 0x9a00, 0x2fc7, 0x4000 }, { 0x9a00, 0x2fc3, 0x3000 }, { 0x9a00, 0x2fc1, 0x2000 }, { 0x1a00, 0x2fc0, 0x0000 }, { 0x1a00, 0x2fc2, 0x0000 }, { 0x9a00, 0x2fc5, 0x2000 }, { 0x1a00, 0x2fc4, 0x0000 }, { 0x1a00, 0x2fc6, 0x0000 }, { 0x9a00, 0x2fcb, 0x3000 }, { 0x9a00, 0x2fc9, 0x2000 }, { 0x1a00, 0x2fc8, 0x0000 }, { 0x1a00, 0x2fca, 0x0000 }, { 0x9a00, 0x2fcd, 0x2000 }, { 0x1a00, 0x2fcc, 0x0000 }, { 0x1a00, 0x2fce, 0x0000 }, { 0x9a00, 0x2ff1, 0x4000 }, { 0x9a00, 0x2fd3, 0x3000 }, { 0x9a00, 0x2fd1, 0x2000 }, { 0x1a00, 0x2fd0, 0x0000 }, { 0x1a00, 0x2fd2, 0x0000 }, { 0x9a00, 0x2fd5, 0x2000 }, { 0x1a00, 0x2fd4, 0x0000 }, { 0x1a00, 0x2ff0, 0x0000 }, { 0x9a00, 0x2ff5, 0x3000 }, { 0x9a00, 0x2ff3, 0x2000 }, { 0x1a00, 0x2ff2, 0x0000 }, { 0x1a00, 0x2ff4, 0x0000 }, { 0x9a00, 0x2ff7, 0x2000 }, { 0x1a00, 0x2ff6, 0x0000 }, { 0x1a00, 0x2ff8, 0x0000 }, { 0x9600, 0x301d, 0x6000 }, { 0x9200, 0x300d, 0x5000 }, { 0x8600, 0x3005, 0x4000 }, { 0x9500, 0x3001, 0x3000 }, { 0x9a00, 0x2ffb, 0x2000 }, { 0x1a00, 0x2ffa, 0x0000 }, { 0x1d00, 0x3000, 0x0000 }, { 0x9500, 0x3003, 0x2000 }, { 0x1500, 0x3002, 0x0000 }, { 0x1a00, 0x3004, 0x0000 }, { 0x9200, 0x3009, 0x3000 }, { 0x8e00, 0x3007, 0x2000 }, { 0x0700, 0x3006, 0x0000 }, { 0x1600, 0x3008, 0x0000 }, { 0x9200, 0x300b, 0x2000 }, { 0x1600, 0x300a, 0x0000 }, { 0x1600, 0x300c, 0x0000 }, { 0x9200, 0x3015, 0x4000 }, { 0x9200, 0x3011, 0x3000 }, { 0x9200, 0x300f, 0x2000 }, { 0x1600, 0x300e, 0x0000 }, { 0x1600, 0x3010, 0x0000 }, { 0x9a00, 0x3013, 0x2000 }, { 0x1a00, 0x3012, 0x0000 }, { 0x1600, 0x3014, 0x0000 }, { 0x9200, 0x3019, 0x3000 }, { 0x9200, 0x3017, 0x2000 }, { 0x1600, 0x3016, 0x0000 }, { 0x1600, 0x3018, 0x0000 }, { 0x9200, 0x301b, 0x2000 }, { 0x1600, 0x301a, 0x0000 }, { 0x1100, 0x301c, 0x0000 }, { 0x8c00, 0x302d, 0x5000 }, { 0x8e00, 0x3025, 0x4000 }, { 0x8e00, 0x3021, 0x3000 }, { 0x9200, 0x301f, 0x2000 }, { 0x1200, 0x301e, 0x0000 }, { 0x1a00, 0x3020, 0x0000 }, { 0x8e00, 0x3023, 0x2000 }, { 0x0e00, 0x3022, 0x0000 }, { 0x0e00, 0x3024, 0x0000 }, { 0x8e00, 0x3029, 0x3000 }, { 0x8e00, 0x3027, 0x2000 }, { 0x0e00, 0x3026, 0x0000 }, { 0x0e00, 0x3028, 0x0000 }, { 0x8c00, 0x302b, 0x2000 }, { 0x0c00, 0x302a, 0x0000 }, { 0x0c00, 0x302c, 0x0000 }, { 0x8600, 0x3035, 0x4000 }, { 0x8600, 0x3031, 0x3000 }, { 0x8c00, 0x302f, 0x2000 }, { 0x0c00, 0x302e, 0x0000 }, { 0x1100, 0x3030, 0x0000 }, { 0x8600, 0x3033, 0x2000 }, { 0x0600, 0x3032, 0x0000 }, { 0x0600, 0x3034, 0x0000 }, { 0x8e00, 0x3039, 0x3000 }, { 0x9a00, 0x3037, 0x2000 }, { 0x1a00, 0x3036, 0x0000 }, { 0x0e00, 0x3038, 0x0000 }, { 0x8600, 0x303b, 0x2000 }, { 0x0e00, 0x303a, 0x0000 }, { 0x0700, 0x303c, 0x0000 }, { 0x8700, 0x30c0, 0x8000 }, { 0x8700, 0x307e, 0x7000 }, { 0x8700, 0x305e, 0x6000 }, { 0x8700, 0x304e, 0x5000 }, { 0x8700, 0x3046, 0x4000 }, { 0x8700, 0x3042, 0x3000 }, { 0x9a00, 0x303f, 0x2000 }, { 0x1a00, 0x303e, 0x0000 }, { 0x0700, 0x3041, 0x0000 }, { 0x8700, 0x3044, 0x2000 }, { 0x0700, 0x3043, 0x0000 }, { 0x0700, 0x3045, 0x0000 }, { 0x8700, 0x304a, 0x3000 }, { 0x8700, 0x3048, 0x2000 }, { 0x0700, 0x3047, 0x0000 }, { 0x0700, 0x3049, 0x0000 }, { 0x8700, 0x304c, 0x2000 }, { 0x0700, 0x304b, 0x0000 }, { 0x0700, 0x304d, 0x0000 }, { 0x8700, 0x3056, 0x4000 }, { 0x8700, 0x3052, 0x3000 }, { 0x8700, 0x3050, 0x2000 }, { 0x0700, 0x304f, 0x0000 }, { 0x0700, 0x3051, 0x0000 }, { 0x8700, 0x3054, 0x2000 }, { 0x0700, 0x3053, 0x0000 }, { 0x0700, 0x3055, 0x0000 }, { 0x8700, 0x305a, 0x3000 }, { 0x8700, 0x3058, 0x2000 }, { 0x0700, 0x3057, 0x0000 }, { 0x0700, 0x3059, 0x0000 }, { 0x8700, 0x305c, 0x2000 }, { 0x0700, 0x305b, 0x0000 }, { 0x0700, 0x305d, 0x0000 }, { 0x8700, 0x306e, 0x5000 }, { 0x8700, 0x3066, 0x4000 }, { 0x8700, 0x3062, 0x3000 }, { 0x8700, 0x3060, 0x2000 }, { 0x0700, 0x305f, 0x0000 }, { 0x0700, 0x3061, 0x0000 }, { 0x8700, 0x3064, 0x2000 }, { 0x0700, 0x3063, 0x0000 }, { 0x0700, 0x3065, 0x0000 }, { 0x8700, 0x306a, 0x3000 }, { 0x8700, 0x3068, 0x2000 }, { 0x0700, 0x3067, 0x0000 }, { 0x0700, 0x3069, 0x0000 }, { 0x8700, 0x306c, 0x2000 }, { 0x0700, 0x306b, 0x0000 }, { 0x0700, 0x306d, 0x0000 }, { 0x8700, 0x3076, 0x4000 }, { 0x8700, 0x3072, 0x3000 }, { 0x8700, 0x3070, 0x2000 }, { 0x0700, 0x306f, 0x0000 }, { 0x0700, 0x3071, 0x0000 }, { 0x8700, 0x3074, 0x2000 }, { 0x0700, 0x3073, 0x0000 }, { 0x0700, 0x3075, 0x0000 }, { 0x8700, 0x307a, 0x3000 }, { 0x8700, 0x3078, 0x2000 }, { 0x0700, 0x3077, 0x0000 }, { 0x0700, 0x3079, 0x0000 }, { 0x8700, 0x307c, 0x2000 }, { 0x0700, 0x307b, 0x0000 }, { 0x0700, 0x307d, 0x0000 }, { 0x9100, 0x30a0, 0x6000 }, { 0x8700, 0x308e, 0x5000 }, { 0x8700, 0x3086, 0x4000 }, { 0x8700, 0x3082, 0x3000 }, { 0x8700, 0x3080, 0x2000 }, { 0x0700, 0x307f, 0x0000 }, { 0x0700, 0x3081, 0x0000 }, { 0x8700, 0x3084, 0x2000 }, { 0x0700, 0x3083, 0x0000 }, { 0x0700, 0x3085, 0x0000 }, { 0x8700, 0x308a, 0x3000 }, { 0x8700, 0x3088, 0x2000 }, { 0x0700, 0x3087, 0x0000 }, { 0x0700, 0x3089, 0x0000 }, { 0x8700, 0x308c, 0x2000 }, { 0x0700, 0x308b, 0x0000 }, { 0x0700, 0x308d, 0x0000 }, { 0x8700, 0x3096, 0x4000 }, { 0x8700, 0x3092, 0x3000 }, { 0x8700, 0x3090, 0x2000 }, { 0x0700, 0x308f, 0x0000 }, { 0x0700, 0x3091, 0x0000 }, { 0x8700, 0x3094, 0x2000 }, { 0x0700, 0x3093, 0x0000 }, { 0x0700, 0x3095, 0x0000 }, { 0x9800, 0x309c, 0x3000 }, { 0x8c00, 0x309a, 0x2000 }, { 0x0c00, 0x3099, 0x0000 }, { 0x1800, 0x309b, 0x0000 }, { 0x8600, 0x309e, 0x2000 }, { 0x0600, 0x309d, 0x0000 }, { 0x0700, 0x309f, 0x0000 }, { 0x8700, 0x30b0, 0x5000 }, { 0x8700, 0x30a8, 0x4000 }, { 0x8700, 0x30a4, 0x3000 }, { 0x8700, 0x30a2, 0x2000 }, { 0x0700, 0x30a1, 0x0000 }, { 0x0700, 0x30a3, 0x0000 }, { 0x8700, 0x30a6, 0x2000 }, { 0x0700, 0x30a5, 0x0000 }, { 0x0700, 0x30a7, 0x0000 }, { 0x8700, 0x30ac, 0x3000 }, { 0x8700, 0x30aa, 0x2000 }, { 0x0700, 0x30a9, 0x0000 }, { 0x0700, 0x30ab, 0x0000 }, { 0x8700, 0x30ae, 0x2000 }, { 0x0700, 0x30ad, 0x0000 }, { 0x0700, 0x30af, 0x0000 }, { 0x8700, 0x30b8, 0x4000 }, { 0x8700, 0x30b4, 0x3000 }, { 0x8700, 0x30b2, 0x2000 }, { 0x0700, 0x30b1, 0x0000 }, { 0x0700, 0x30b3, 0x0000 }, { 0x8700, 0x30b6, 0x2000 }, { 0x0700, 0x30b5, 0x0000 }, { 0x0700, 0x30b7, 0x0000 }, { 0x8700, 0x30bc, 0x3000 }, { 0x8700, 0x30ba, 0x2000 }, { 0x0700, 0x30b9, 0x0000 }, { 0x0700, 0x30bb, 0x0000 }, { 0x8700, 0x30be, 0x2000 }, { 0x0700, 0x30bd, 0x0000 }, { 0x0700, 0x30bf, 0x0000 }, { 0x8700, 0x3105, 0x7000 }, { 0x8700, 0x30e0, 0x6000 }, { 0x8700, 0x30d0, 0x5000 }, { 0x8700, 0x30c8, 0x4000 }, { 0x8700, 0x30c4, 0x3000 }, { 0x8700, 0x30c2, 0x2000 }, { 0x0700, 0x30c1, 0x0000 }, { 0x0700, 0x30c3, 0x0000 }, { 0x8700, 0x30c6, 0x2000 }, { 0x0700, 0x30c5, 0x0000 }, { 0x0700, 0x30c7, 0x0000 }, { 0x8700, 0x30cc, 0x3000 }, { 0x8700, 0x30ca, 0x2000 }, { 0x0700, 0x30c9, 0x0000 }, { 0x0700, 0x30cb, 0x0000 }, { 0x8700, 0x30ce, 0x2000 }, { 0x0700, 0x30cd, 0x0000 }, { 0x0700, 0x30cf, 0x0000 }, { 0x8700, 0x30d8, 0x4000 }, { 0x8700, 0x30d4, 0x3000 }, { 0x8700, 0x30d2, 0x2000 }, { 0x0700, 0x30d1, 0x0000 }, { 0x0700, 0x30d3, 0x0000 }, { 0x8700, 0x30d6, 0x2000 }, { 0x0700, 0x30d5, 0x0000 }, { 0x0700, 0x30d7, 0x0000 }, { 0x8700, 0x30dc, 0x3000 }, { 0x8700, 0x30da, 0x2000 }, { 0x0700, 0x30d9, 0x0000 }, { 0x0700, 0x30db, 0x0000 }, { 0x8700, 0x30de, 0x2000 }, { 0x0700, 0x30dd, 0x0000 }, { 0x0700, 0x30df, 0x0000 }, { 0x8700, 0x30f0, 0x5000 }, { 0x8700, 0x30e8, 0x4000 }, { 0x8700, 0x30e4, 0x3000 }, { 0x8700, 0x30e2, 0x2000 }, { 0x0700, 0x30e1, 0x0000 }, { 0x0700, 0x30e3, 0x0000 }, { 0x8700, 0x30e6, 0x2000 }, { 0x0700, 0x30e5, 0x0000 }, { 0x0700, 0x30e7, 0x0000 }, { 0x8700, 0x30ec, 0x3000 }, { 0x8700, 0x30ea, 0x2000 }, { 0x0700, 0x30e9, 0x0000 }, { 0x0700, 0x30eb, 0x0000 }, { 0x8700, 0x30ee, 0x2000 }, { 0x0700, 0x30ed, 0x0000 }, { 0x0700, 0x30ef, 0x0000 }, { 0x8700, 0x30f8, 0x4000 }, { 0x8700, 0x30f4, 0x3000 }, { 0x8700, 0x30f2, 0x2000 }, { 0x0700, 0x30f1, 0x0000 }, { 0x0700, 0x30f3, 0x0000 }, { 0x8700, 0x30f6, 0x2000 }, { 0x0700, 0x30f5, 0x0000 }, { 0x0700, 0x30f7, 0x0000 }, { 0x8600, 0x30fc, 0x3000 }, { 0x8700, 0x30fa, 0x2000 }, { 0x0700, 0x30f9, 0x0000 }, { 0x1000, 0x30fb, 0x0000 }, { 0x8600, 0x30fe, 0x2000 }, { 0x0600, 0x30fd, 0x0000 }, { 0x0700, 0x30ff, 0x0000 }, { 0x8700, 0x3125, 0x6000 }, { 0x8700, 0x3115, 0x5000 }, { 0x8700, 0x310d, 0x4000 }, { 0x8700, 0x3109, 0x3000 }, { 0x8700, 0x3107, 0x2000 }, { 0x0700, 0x3106, 0x0000 }, { 0x0700, 0x3108, 0x0000 }, { 0x8700, 0x310b, 0x2000 }, { 0x0700, 0x310a, 0x0000 }, { 0x0700, 0x310c, 0x0000 }, { 0x8700, 0x3111, 0x3000 }, { 0x8700, 0x310f, 0x2000 }, { 0x0700, 0x310e, 0x0000 }, { 0x0700, 0x3110, 0x0000 }, { 0x8700, 0x3113, 0x2000 }, { 0x0700, 0x3112, 0x0000 }, { 0x0700, 0x3114, 0x0000 }, { 0x8700, 0x311d, 0x4000 }, { 0x8700, 0x3119, 0x3000 }, { 0x8700, 0x3117, 0x2000 }, { 0x0700, 0x3116, 0x0000 }, { 0x0700, 0x3118, 0x0000 }, { 0x8700, 0x311b, 0x2000 }, { 0x0700, 0x311a, 0x0000 }, { 0x0700, 0x311c, 0x0000 }, { 0x8700, 0x3121, 0x3000 }, { 0x8700, 0x311f, 0x2000 }, { 0x0700, 0x311e, 0x0000 }, { 0x0700, 0x3120, 0x0000 }, { 0x8700, 0x3123, 0x2000 }, { 0x0700, 0x3122, 0x0000 }, { 0x0700, 0x3124, 0x0000 }, { 0x8700, 0x3139, 0x5000 }, { 0x8700, 0x3131, 0x4000 }, { 0x8700, 0x3129, 0x3000 }, { 0x8700, 0x3127, 0x2000 }, { 0x0700, 0x3126, 0x0000 }, { 0x0700, 0x3128, 0x0000 }, { 0x8700, 0x312b, 0x2000 }, { 0x0700, 0x312a, 0x0000 }, { 0x0700, 0x312c, 0x0000 }, { 0x8700, 0x3135, 0x3000 }, { 0x8700, 0x3133, 0x2000 }, { 0x0700, 0x3132, 0x0000 }, { 0x0700, 0x3134, 0x0000 }, { 0x8700, 0x3137, 0x2000 }, { 0x0700, 0x3136, 0x0000 }, { 0x0700, 0x3138, 0x0000 }, { 0x8700, 0x3141, 0x4000 }, { 0x8700, 0x313d, 0x3000 }, { 0x8700, 0x313b, 0x2000 }, { 0x0700, 0x313a, 0x0000 }, { 0x0700, 0x313c, 0x0000 }, { 0x8700, 0x313f, 0x2000 }, { 0x0700, 0x313e, 0x0000 }, { 0x0700, 0x3140, 0x0000 }, { 0x8700, 0x3145, 0x3000 }, { 0x8700, 0x3143, 0x2000 }, { 0x0700, 0x3142, 0x0000 }, { 0x0700, 0x3144, 0x0000 }, { 0x8700, 0x3147, 0x2000 }, { 0x0700, 0x3146, 0x0000 }, { 0x0700, 0x3148, 0x0000 }, { 0x9a00, 0x3290, 0x9000 }, { 0x9a00, 0x3202, 0x8000 }, { 0x8700, 0x3189, 0x7000 }, { 0x8700, 0x3169, 0x6000 }, { 0x8700, 0x3159, 0x5000 }, { 0x8700, 0x3151, 0x4000 }, { 0x8700, 0x314d, 0x3000 }, { 0x8700, 0x314b, 0x2000 }, { 0x0700, 0x314a, 0x0000 }, { 0x0700, 0x314c, 0x0000 }, { 0x8700, 0x314f, 0x2000 }, { 0x0700, 0x314e, 0x0000 }, { 0x0700, 0x3150, 0x0000 }, { 0x8700, 0x3155, 0x3000 }, { 0x8700, 0x3153, 0x2000 }, { 0x0700, 0x3152, 0x0000 }, { 0x0700, 0x3154, 0x0000 }, { 0x8700, 0x3157, 0x2000 }, { 0x0700, 0x3156, 0x0000 }, { 0x0700, 0x3158, 0x0000 }, { 0x8700, 0x3161, 0x4000 }, { 0x8700, 0x315d, 0x3000 }, { 0x8700, 0x315b, 0x2000 }, { 0x0700, 0x315a, 0x0000 }, { 0x0700, 0x315c, 0x0000 }, { 0x8700, 0x315f, 0x2000 }, { 0x0700, 0x315e, 0x0000 }, { 0x0700, 0x3160, 0x0000 }, { 0x8700, 0x3165, 0x3000 }, { 0x8700, 0x3163, 0x2000 }, { 0x0700, 0x3162, 0x0000 }, { 0x0700, 0x3164, 0x0000 }, { 0x8700, 0x3167, 0x2000 }, { 0x0700, 0x3166, 0x0000 }, { 0x0700, 0x3168, 0x0000 }, { 0x8700, 0x3179, 0x5000 }, { 0x8700, 0x3171, 0x4000 }, { 0x8700, 0x316d, 0x3000 }, { 0x8700, 0x316b, 0x2000 }, { 0x0700, 0x316a, 0x0000 }, { 0x0700, 0x316c, 0x0000 }, { 0x8700, 0x316f, 0x2000 }, { 0x0700, 0x316e, 0x0000 }, { 0x0700, 0x3170, 0x0000 }, { 0x8700, 0x3175, 0x3000 }, { 0x8700, 0x3173, 0x2000 }, { 0x0700, 0x3172, 0x0000 }, { 0x0700, 0x3174, 0x0000 }, { 0x8700, 0x3177, 0x2000 }, { 0x0700, 0x3176, 0x0000 }, { 0x0700, 0x3178, 0x0000 }, { 0x8700, 0x3181, 0x4000 }, { 0x8700, 0x317d, 0x3000 }, { 0x8700, 0x317b, 0x2000 }, { 0x0700, 0x317a, 0x0000 }, { 0x0700, 0x317c, 0x0000 }, { 0x8700, 0x317f, 0x2000 }, { 0x0700, 0x317e, 0x0000 }, { 0x0700, 0x3180, 0x0000 }, { 0x8700, 0x3185, 0x3000 }, { 0x8700, 0x3183, 0x2000 }, { 0x0700, 0x3182, 0x0000 }, { 0x0700, 0x3184, 0x0000 }, { 0x8700, 0x3187, 0x2000 }, { 0x0700, 0x3186, 0x0000 }, { 0x0700, 0x3188, 0x0000 }, { 0x8700, 0x31aa, 0x6000 }, { 0x9a00, 0x319a, 0x5000 }, { 0x8f00, 0x3192, 0x4000 }, { 0x8700, 0x318d, 0x3000 }, { 0x8700, 0x318b, 0x2000 }, { 0x0700, 0x318a, 0x0000 }, { 0x0700, 0x318c, 0x0000 }, { 0x9a00, 0x3190, 0x2000 }, { 0x0700, 0x318e, 0x0000 }, { 0x1a00, 0x3191, 0x0000 }, { 0x9a00, 0x3196, 0x3000 }, { 0x8f00, 0x3194, 0x2000 }, { 0x0f00, 0x3193, 0x0000 }, { 0x0f00, 0x3195, 0x0000 }, { 0x9a00, 0x3198, 0x2000 }, { 0x1a00, 0x3197, 0x0000 }, { 0x1a00, 0x3199, 0x0000 }, { 0x8700, 0x31a2, 0x4000 }, { 0x9a00, 0x319e, 0x3000 }, { 0x9a00, 0x319c, 0x2000 }, { 0x1a00, 0x319b, 0x0000 }, { 0x1a00, 0x319d, 0x0000 }, { 0x8700, 0x31a0, 0x2000 }, { 0x1a00, 0x319f, 0x0000 }, { 0x0700, 0x31a1, 0x0000 }, { 0x8700, 0x31a6, 0x3000 }, { 0x8700, 0x31a4, 0x2000 }, { 0x0700, 0x31a3, 0x0000 }, { 0x0700, 0x31a5, 0x0000 }, { 0x8700, 0x31a8, 0x2000 }, { 0x0700, 0x31a7, 0x0000 }, { 0x0700, 0x31a9, 0x0000 }, { 0x8700, 0x31f2, 0x5000 }, { 0x8700, 0x31b2, 0x4000 }, { 0x8700, 0x31ae, 0x3000 }, { 0x8700, 0x31ac, 0x2000 }, { 0x0700, 0x31ab, 0x0000 }, { 0x0700, 0x31ad, 0x0000 }, { 0x8700, 0x31b0, 0x2000 }, { 0x0700, 0x31af, 0x0000 }, { 0x0700, 0x31b1, 0x0000 }, { 0x8700, 0x31b6, 0x3000 }, { 0x8700, 0x31b4, 0x2000 }, { 0x0700, 0x31b3, 0x0000 }, { 0x0700, 0x31b5, 0x0000 }, { 0x8700, 0x31f0, 0x2000 }, { 0x0700, 0x31b7, 0x0000 }, { 0x0700, 0x31f1, 0x0000 }, { 0x8700, 0x31fa, 0x4000 }, { 0x8700, 0x31f6, 0x3000 }, { 0x8700, 0x31f4, 0x2000 }, { 0x0700, 0x31f3, 0x0000 }, { 0x0700, 0x31f5, 0x0000 }, { 0x8700, 0x31f8, 0x2000 }, { 0x0700, 0x31f7, 0x0000 }, { 0x0700, 0x31f9, 0x0000 }, { 0x8700, 0x31fe, 0x3000 }, { 0x8700, 0x31fc, 0x2000 }, { 0x0700, 0x31fb, 0x0000 }, { 0x0700, 0x31fd, 0x0000 }, { 0x9a00, 0x3200, 0x2000 }, { 0x0700, 0x31ff, 0x0000 }, { 0x1a00, 0x3201, 0x0000 }, { 0x9a00, 0x3243, 0x7000 }, { 0x8f00, 0x3223, 0x6000 }, { 0x9a00, 0x3212, 0x5000 }, { 0x9a00, 0x320a, 0x4000 }, { 0x9a00, 0x3206, 0x3000 }, { 0x9a00, 0x3204, 0x2000 }, { 0x1a00, 0x3203, 0x0000 }, { 0x1a00, 0x3205, 0x0000 }, { 0x9a00, 0x3208, 0x2000 }, { 0x1a00, 0x3207, 0x0000 }, { 0x1a00, 0x3209, 0x0000 }, { 0x9a00, 0x320e, 0x3000 }, { 0x9a00, 0x320c, 0x2000 }, { 0x1a00, 0x320b, 0x0000 }, { 0x1a00, 0x320d, 0x0000 }, { 0x9a00, 0x3210, 0x2000 }, { 0x1a00, 0x320f, 0x0000 }, { 0x1a00, 0x3211, 0x0000 }, { 0x9a00, 0x321a, 0x4000 }, { 0x9a00, 0x3216, 0x3000 }, { 0x9a00, 0x3214, 0x2000 }, { 0x1a00, 0x3213, 0x0000 }, { 0x1a00, 0x3215, 0x0000 }, { 0x9a00, 0x3218, 0x2000 }, { 0x1a00, 0x3217, 0x0000 }, { 0x1a00, 0x3219, 0x0000 }, { 0x9a00, 0x321e, 0x3000 }, { 0x9a00, 0x321c, 0x2000 }, { 0x1a00, 0x321b, 0x0000 }, { 0x1a00, 0x321d, 0x0000 }, { 0x8f00, 0x3221, 0x2000 }, { 0x0f00, 0x3220, 0x0000 }, { 0x0f00, 0x3222, 0x0000 }, { 0x9a00, 0x3233, 0x5000 }, { 0x9a00, 0x322b, 0x4000 }, { 0x8f00, 0x3227, 0x3000 }, { 0x8f00, 0x3225, 0x2000 }, { 0x0f00, 0x3224, 0x0000 }, { 0x0f00, 0x3226, 0x0000 }, { 0x8f00, 0x3229, 0x2000 }, { 0x0f00, 0x3228, 0x0000 }, { 0x1a00, 0x322a, 0x0000 }, { 0x9a00, 0x322f, 0x3000 }, { 0x9a00, 0x322d, 0x2000 }, { 0x1a00, 0x322c, 0x0000 }, { 0x1a00, 0x322e, 0x0000 }, { 0x9a00, 0x3231, 0x2000 }, { 0x1a00, 0x3230, 0x0000 }, { 0x1a00, 0x3232, 0x0000 }, { 0x9a00, 0x323b, 0x4000 }, { 0x9a00, 0x3237, 0x3000 }, { 0x9a00, 0x3235, 0x2000 }, { 0x1a00, 0x3234, 0x0000 }, { 0x1a00, 0x3236, 0x0000 }, { 0x9a00, 0x3239, 0x2000 }, { 0x1a00, 0x3238, 0x0000 }, { 0x1a00, 0x323a, 0x0000 }, { 0x9a00, 0x323f, 0x3000 }, { 0x9a00, 0x323d, 0x2000 }, { 0x1a00, 0x323c, 0x0000 }, { 0x1a00, 0x323e, 0x0000 }, { 0x9a00, 0x3241, 0x2000 }, { 0x1a00, 0x3240, 0x0000 }, { 0x1a00, 0x3242, 0x0000 }, { 0x9a00, 0x326f, 0x6000 }, { 0x8f00, 0x325f, 0x5000 }, { 0x8f00, 0x3257, 0x4000 }, { 0x8f00, 0x3253, 0x3000 }, { 0x8f00, 0x3251, 0x2000 }, { 0x1a00, 0x3250, 0x0000 }, { 0x0f00, 0x3252, 0x0000 }, { 0x8f00, 0x3255, 0x2000 }, { 0x0f00, 0x3254, 0x0000 }, { 0x0f00, 0x3256, 0x0000 }, { 0x8f00, 0x325b, 0x3000 }, { 0x8f00, 0x3259, 0x2000 }, { 0x0f00, 0x3258, 0x0000 }, { 0x0f00, 0x325a, 0x0000 }, { 0x8f00, 0x325d, 0x2000 }, { 0x0f00, 0x325c, 0x0000 }, { 0x0f00, 0x325e, 0x0000 }, { 0x9a00, 0x3267, 0x4000 }, { 0x9a00, 0x3263, 0x3000 }, { 0x9a00, 0x3261, 0x2000 }, { 0x1a00, 0x3260, 0x0000 }, { 0x1a00, 0x3262, 0x0000 }, { 0x9a00, 0x3265, 0x2000 }, { 0x1a00, 0x3264, 0x0000 }, { 0x1a00, 0x3266, 0x0000 }, { 0x9a00, 0x326b, 0x3000 }, { 0x9a00, 0x3269, 0x2000 }, { 0x1a00, 0x3268, 0x0000 }, { 0x1a00, 0x326a, 0x0000 }, { 0x9a00, 0x326d, 0x2000 }, { 0x1a00, 0x326c, 0x0000 }, { 0x1a00, 0x326e, 0x0000 }, { 0x8f00, 0x3280, 0x5000 }, { 0x9a00, 0x3277, 0x4000 }, { 0x9a00, 0x3273, 0x3000 }, { 0x9a00, 0x3271, 0x2000 }, { 0x1a00, 0x3270, 0x0000 }, { 0x1a00, 0x3272, 0x0000 }, { 0x9a00, 0x3275, 0x2000 }, { 0x1a00, 0x3274, 0x0000 }, { 0x1a00, 0x3276, 0x0000 }, { 0x9a00, 0x327b, 0x3000 }, { 0x9a00, 0x3279, 0x2000 }, { 0x1a00, 0x3278, 0x0000 }, { 0x1a00, 0x327a, 0x0000 }, { 0x9a00, 0x327d, 0x2000 }, { 0x1a00, 0x327c, 0x0000 }, { 0x1a00, 0x327f, 0x0000 }, { 0x8f00, 0x3288, 0x4000 }, { 0x8f00, 0x3284, 0x3000 }, { 0x8f00, 0x3282, 0x2000 }, { 0x0f00, 0x3281, 0x0000 }, { 0x0f00, 0x3283, 0x0000 }, { 0x8f00, 0x3286, 0x2000 }, { 0x0f00, 0x3285, 0x0000 }, { 0x0f00, 0x3287, 0x0000 }, { 0x9a00, 0x328c, 0x3000 }, { 0x9a00, 0x328a, 0x2000 }, { 0x0f00, 0x3289, 0x0000 }, { 0x1a00, 0x328b, 0x0000 }, { 0x9a00, 0x328e, 0x2000 }, { 0x1a00, 0x328d, 0x0000 }, { 0x1a00, 0x328f, 0x0000 }, { 0x9a00, 0x3311, 0x8000 }, { 0x9a00, 0x32d0, 0x7000 }, { 0x9a00, 0x32b0, 0x6000 }, { 0x9a00, 0x32a0, 0x5000 }, { 0x9a00, 0x3298, 0x4000 }, { 0x9a00, 0x3294, 0x3000 }, { 0x9a00, 0x3292, 0x2000 }, { 0x1a00, 0x3291, 0x0000 }, { 0x1a00, 0x3293, 0x0000 }, { 0x9a00, 0x3296, 0x2000 }, { 0x1a00, 0x3295, 0x0000 }, { 0x1a00, 0x3297, 0x0000 }, { 0x9a00, 0x329c, 0x3000 }, { 0x9a00, 0x329a, 0x2000 }, { 0x1a00, 0x3299, 0x0000 }, { 0x1a00, 0x329b, 0x0000 }, { 0x9a00, 0x329e, 0x2000 }, { 0x1a00, 0x329d, 0x0000 }, { 0x1a00, 0x329f, 0x0000 }, { 0x9a00, 0x32a8, 0x4000 }, { 0x9a00, 0x32a4, 0x3000 }, { 0x9a00, 0x32a2, 0x2000 }, { 0x1a00, 0x32a1, 0x0000 }, { 0x1a00, 0x32a3, 0x0000 }, { 0x9a00, 0x32a6, 0x2000 }, { 0x1a00, 0x32a5, 0x0000 }, { 0x1a00, 0x32a7, 0x0000 }, { 0x9a00, 0x32ac, 0x3000 }, { 0x9a00, 0x32aa, 0x2000 }, { 0x1a00, 0x32a9, 0x0000 }, { 0x1a00, 0x32ab, 0x0000 }, { 0x9a00, 0x32ae, 0x2000 }, { 0x1a00, 0x32ad, 0x0000 }, { 0x1a00, 0x32af, 0x0000 }, { 0x9a00, 0x32c0, 0x5000 }, { 0x8f00, 0x32b8, 0x4000 }, { 0x8f00, 0x32b4, 0x3000 }, { 0x8f00, 0x32b2, 0x2000 }, { 0x0f00, 0x32b1, 0x0000 }, { 0x0f00, 0x32b3, 0x0000 }, { 0x8f00, 0x32b6, 0x2000 }, { 0x0f00, 0x32b5, 0x0000 }, { 0x0f00, 0x32b7, 0x0000 }, { 0x8f00, 0x32bc, 0x3000 }, { 0x8f00, 0x32ba, 0x2000 }, { 0x0f00, 0x32b9, 0x0000 }, { 0x0f00, 0x32bb, 0x0000 }, { 0x8f00, 0x32be, 0x2000 }, { 0x0f00, 0x32bd, 0x0000 }, { 0x0f00, 0x32bf, 0x0000 }, { 0x9a00, 0x32c8, 0x4000 }, { 0x9a00, 0x32c4, 0x3000 }, { 0x9a00, 0x32c2, 0x2000 }, { 0x1a00, 0x32c1, 0x0000 }, { 0x1a00, 0x32c3, 0x0000 }, { 0x9a00, 0x32c6, 0x2000 }, { 0x1a00, 0x32c5, 0x0000 }, { 0x1a00, 0x32c7, 0x0000 }, { 0x9a00, 0x32cc, 0x3000 }, { 0x9a00, 0x32ca, 0x2000 }, { 0x1a00, 0x32c9, 0x0000 }, { 0x1a00, 0x32cb, 0x0000 }, { 0x9a00, 0x32ce, 0x2000 }, { 0x1a00, 0x32cd, 0x0000 }, { 0x1a00, 0x32cf, 0x0000 }, { 0x9a00, 0x32f0, 0x6000 }, { 0x9a00, 0x32e0, 0x5000 }, { 0x9a00, 0x32d8, 0x4000 }, { 0x9a00, 0x32d4, 0x3000 }, { 0x9a00, 0x32d2, 0x2000 }, { 0x1a00, 0x32d1, 0x0000 }, { 0x1a00, 0x32d3, 0x0000 }, { 0x9a00, 0x32d6, 0x2000 }, { 0x1a00, 0x32d5, 0x0000 }, { 0x1a00, 0x32d7, 0x0000 }, { 0x9a00, 0x32dc, 0x3000 }, { 0x9a00, 0x32da, 0x2000 }, { 0x1a00, 0x32d9, 0x0000 }, { 0x1a00, 0x32db, 0x0000 }, { 0x9a00, 0x32de, 0x2000 }, { 0x1a00, 0x32dd, 0x0000 }, { 0x1a00, 0x32df, 0x0000 }, { 0x9a00, 0x32e8, 0x4000 }, { 0x9a00, 0x32e4, 0x3000 }, { 0x9a00, 0x32e2, 0x2000 }, { 0x1a00, 0x32e1, 0x0000 }, { 0x1a00, 0x32e3, 0x0000 }, { 0x9a00, 0x32e6, 0x2000 }, { 0x1a00, 0x32e5, 0x0000 }, { 0x1a00, 0x32e7, 0x0000 }, { 0x9a00, 0x32ec, 0x3000 }, { 0x9a00, 0x32ea, 0x2000 }, { 0x1a00, 0x32e9, 0x0000 }, { 0x1a00, 0x32eb, 0x0000 }, { 0x9a00, 0x32ee, 0x2000 }, { 0x1a00, 0x32ed, 0x0000 }, { 0x1a00, 0x32ef, 0x0000 }, { 0x9a00, 0x3301, 0x5000 }, { 0x9a00, 0x32f8, 0x4000 }, { 0x9a00, 0x32f4, 0x3000 }, { 0x9a00, 0x32f2, 0x2000 }, { 0x1a00, 0x32f1, 0x0000 }, { 0x1a00, 0x32f3, 0x0000 }, { 0x9a00, 0x32f6, 0x2000 }, { 0x1a00, 0x32f5, 0x0000 }, { 0x1a00, 0x32f7, 0x0000 }, { 0x9a00, 0x32fc, 0x3000 }, { 0x9a00, 0x32fa, 0x2000 }, { 0x1a00, 0x32f9, 0x0000 }, { 0x1a00, 0x32fb, 0x0000 }, { 0x9a00, 0x32fe, 0x2000 }, { 0x1a00, 0x32fd, 0x0000 }, { 0x1a00, 0x3300, 0x0000 }, { 0x9a00, 0x3309, 0x4000 }, { 0x9a00, 0x3305, 0x3000 }, { 0x9a00, 0x3303, 0x2000 }, { 0x1a00, 0x3302, 0x0000 }, { 0x1a00, 0x3304, 0x0000 }, { 0x9a00, 0x3307, 0x2000 }, { 0x1a00, 0x3306, 0x0000 }, { 0x1a00, 0x3308, 0x0000 }, { 0x9a00, 0x330d, 0x3000 }, { 0x9a00, 0x330b, 0x2000 }, { 0x1a00, 0x330a, 0x0000 }, { 0x1a00, 0x330c, 0x0000 }, { 0x9a00, 0x330f, 0x2000 }, { 0x1a00, 0x330e, 0x0000 }, { 0x1a00, 0x3310, 0x0000 }, { 0x9a00, 0x3351, 0x7000 }, { 0x9a00, 0x3331, 0x6000 }, { 0x9a00, 0x3321, 0x5000 }, { 0x9a00, 0x3319, 0x4000 }, { 0x9a00, 0x3315, 0x3000 }, { 0x9a00, 0x3313, 0x2000 }, { 0x1a00, 0x3312, 0x0000 }, { 0x1a00, 0x3314, 0x0000 }, { 0x9a00, 0x3317, 0x2000 }, { 0x1a00, 0x3316, 0x0000 }, { 0x1a00, 0x3318, 0x0000 }, { 0x9a00, 0x331d, 0x3000 }, { 0x9a00, 0x331b, 0x2000 }, { 0x1a00, 0x331a, 0x0000 }, { 0x1a00, 0x331c, 0x0000 }, { 0x9a00, 0x331f, 0x2000 }, { 0x1a00, 0x331e, 0x0000 }, { 0x1a00, 0x3320, 0x0000 }, { 0x9a00, 0x3329, 0x4000 }, { 0x9a00, 0x3325, 0x3000 }, { 0x9a00, 0x3323, 0x2000 }, { 0x1a00, 0x3322, 0x0000 }, { 0x1a00, 0x3324, 0x0000 }, { 0x9a00, 0x3327, 0x2000 }, { 0x1a00, 0x3326, 0x0000 }, { 0x1a00, 0x3328, 0x0000 }, { 0x9a00, 0x332d, 0x3000 }, { 0x9a00, 0x332b, 0x2000 }, { 0x1a00, 0x332a, 0x0000 }, { 0x1a00, 0x332c, 0x0000 }, { 0x9a00, 0x332f, 0x2000 }, { 0x1a00, 0x332e, 0x0000 }, { 0x1a00, 0x3330, 0x0000 }, { 0x9a00, 0x3341, 0x5000 }, { 0x9a00, 0x3339, 0x4000 }, { 0x9a00, 0x3335, 0x3000 }, { 0x9a00, 0x3333, 0x2000 }, { 0x1a00, 0x3332, 0x0000 }, { 0x1a00, 0x3334, 0x0000 }, { 0x9a00, 0x3337, 0x2000 }, { 0x1a00, 0x3336, 0x0000 }, { 0x1a00, 0x3338, 0x0000 }, { 0x9a00, 0x333d, 0x3000 }, { 0x9a00, 0x333b, 0x2000 }, { 0x1a00, 0x333a, 0x0000 }, { 0x1a00, 0x333c, 0x0000 }, { 0x9a00, 0x333f, 0x2000 }, { 0x1a00, 0x333e, 0x0000 }, { 0x1a00, 0x3340, 0x0000 }, { 0x9a00, 0x3349, 0x4000 }, { 0x9a00, 0x3345, 0x3000 }, { 0x9a00, 0x3343, 0x2000 }, { 0x1a00, 0x3342, 0x0000 }, { 0x1a00, 0x3344, 0x0000 }, { 0x9a00, 0x3347, 0x2000 }, { 0x1a00, 0x3346, 0x0000 }, { 0x1a00, 0x3348, 0x0000 }, { 0x9a00, 0x334d, 0x3000 }, { 0x9a00, 0x334b, 0x2000 }, { 0x1a00, 0x334a, 0x0000 }, { 0x1a00, 0x334c, 0x0000 }, { 0x9a00, 0x334f, 0x2000 }, { 0x1a00, 0x334e, 0x0000 }, { 0x1a00, 0x3350, 0x0000 }, { 0x9a00, 0x3371, 0x6000 }, { 0x9a00, 0x3361, 0x5000 }, { 0x9a00, 0x3359, 0x4000 }, { 0x9a00, 0x3355, 0x3000 }, { 0x9a00, 0x3353, 0x2000 }, { 0x1a00, 0x3352, 0x0000 }, { 0x1a00, 0x3354, 0x0000 }, { 0x9a00, 0x3357, 0x2000 }, { 0x1a00, 0x3356, 0x0000 }, { 0x1a00, 0x3358, 0x0000 }, { 0x9a00, 0x335d, 0x3000 }, { 0x9a00, 0x335b, 0x2000 }, { 0x1a00, 0x335a, 0x0000 }, { 0x1a00, 0x335c, 0x0000 }, { 0x9a00, 0x335f, 0x2000 }, { 0x1a00, 0x335e, 0x0000 }, { 0x1a00, 0x3360, 0x0000 }, { 0x9a00, 0x3369, 0x4000 }, { 0x9a00, 0x3365, 0x3000 }, { 0x9a00, 0x3363, 0x2000 }, { 0x1a00, 0x3362, 0x0000 }, { 0x1a00, 0x3364, 0x0000 }, { 0x9a00, 0x3367, 0x2000 }, { 0x1a00, 0x3366, 0x0000 }, { 0x1a00, 0x3368, 0x0000 }, { 0x9a00, 0x336d, 0x3000 }, { 0x9a00, 0x336b, 0x2000 }, { 0x1a00, 0x336a, 0x0000 }, { 0x1a00, 0x336c, 0x0000 }, { 0x9a00, 0x336f, 0x2000 }, { 0x1a00, 0x336e, 0x0000 }, { 0x1a00, 0x3370, 0x0000 }, { 0x9a00, 0x3381, 0x5000 }, { 0x9a00, 0x3379, 0x4000 }, { 0x9a00, 0x3375, 0x3000 }, { 0x9a00, 0x3373, 0x2000 }, { 0x1a00, 0x3372, 0x0000 }, { 0x1a00, 0x3374, 0x0000 }, { 0x9a00, 0x3377, 0x2000 }, { 0x1a00, 0x3376, 0x0000 }, { 0x1a00, 0x3378, 0x0000 }, { 0x9a00, 0x337d, 0x3000 }, { 0x9a00, 0x337b, 0x2000 }, { 0x1a00, 0x337a, 0x0000 }, { 0x1a00, 0x337c, 0x0000 }, { 0x9a00, 0x337f, 0x2000 }, { 0x1a00, 0x337e, 0x0000 }, { 0x1a00, 0x3380, 0x0000 }, { 0x9a00, 0x3389, 0x4000 }, { 0x9a00, 0x3385, 0x3000 }, { 0x9a00, 0x3383, 0x2000 }, { 0x1a00, 0x3382, 0x0000 }, { 0x1a00, 0x3384, 0x0000 }, { 0x9a00, 0x3387, 0x2000 }, { 0x1a00, 0x3386, 0x0000 }, { 0x1a00, 0x3388, 0x0000 }, { 0x9a00, 0x338d, 0x3000 }, { 0x9a00, 0x338b, 0x2000 }, { 0x1a00, 0x338a, 0x0000 }, { 0x1a00, 0x338c, 0x0000 }, { 0x9a00, 0x338f, 0x2000 }, { 0x1a00, 0x338e, 0x0000 }, { 0x1a00, 0x3390, 0x0000 }, { 0x8700, 0xa14d, 0xa000 }, { 0x8700, 0xa04d, 0x9000 }, { 0x9a00, 0x4dcf, 0x8000 }, { 0x9a00, 0x33d1, 0x7000 }, { 0x9a00, 0x33b1, 0x6000 }, { 0x9a00, 0x33a1, 0x5000 }, { 0x9a00, 0x3399, 0x4000 }, { 0x9a00, 0x3395, 0x3000 }, { 0x9a00, 0x3393, 0x2000 }, { 0x1a00, 0x3392, 0x0000 }, { 0x1a00, 0x3394, 0x0000 }, { 0x9a00, 0x3397, 0x2000 }, { 0x1a00, 0x3396, 0x0000 }, { 0x1a00, 0x3398, 0x0000 }, { 0x9a00, 0x339d, 0x3000 }, { 0x9a00, 0x339b, 0x2000 }, { 0x1a00, 0x339a, 0x0000 }, { 0x1a00, 0x339c, 0x0000 }, { 0x9a00, 0x339f, 0x2000 }, { 0x1a00, 0x339e, 0x0000 }, { 0x1a00, 0x33a0, 0x0000 }, { 0x9a00, 0x33a9, 0x4000 }, { 0x9a00, 0x33a5, 0x3000 }, { 0x9a00, 0x33a3, 0x2000 }, { 0x1a00, 0x33a2, 0x0000 }, { 0x1a00, 0x33a4, 0x0000 }, { 0x9a00, 0x33a7, 0x2000 }, { 0x1a00, 0x33a6, 0x0000 }, { 0x1a00, 0x33a8, 0x0000 }, { 0x9a00, 0x33ad, 0x3000 }, { 0x9a00, 0x33ab, 0x2000 }, { 0x1a00, 0x33aa, 0x0000 }, { 0x1a00, 0x33ac, 0x0000 }, { 0x9a00, 0x33af, 0x2000 }, { 0x1a00, 0x33ae, 0x0000 }, { 0x1a00, 0x33b0, 0x0000 }, { 0x9a00, 0x33c1, 0x5000 }, { 0x9a00, 0x33b9, 0x4000 }, { 0x9a00, 0x33b5, 0x3000 }, { 0x9a00, 0x33b3, 0x2000 }, { 0x1a00, 0x33b2, 0x0000 }, { 0x1a00, 0x33b4, 0x0000 }, { 0x9a00, 0x33b7, 0x2000 }, { 0x1a00, 0x33b6, 0x0000 }, { 0x1a00, 0x33b8, 0x0000 }, { 0x9a00, 0x33bd, 0x3000 }, { 0x9a00, 0x33bb, 0x2000 }, { 0x1a00, 0x33ba, 0x0000 }, { 0x1a00, 0x33bc, 0x0000 }, { 0x9a00, 0x33bf, 0x2000 }, { 0x1a00, 0x33be, 0x0000 }, { 0x1a00, 0x33c0, 0x0000 }, { 0x9a00, 0x33c9, 0x4000 }, { 0x9a00, 0x33c5, 0x3000 }, { 0x9a00, 0x33c3, 0x2000 }, { 0x1a00, 0x33c2, 0x0000 }, { 0x1a00, 0x33c4, 0x0000 }, { 0x9a00, 0x33c7, 0x2000 }, { 0x1a00, 0x33c6, 0x0000 }, { 0x1a00, 0x33c8, 0x0000 }, { 0x9a00, 0x33cd, 0x3000 }, { 0x9a00, 0x33cb, 0x2000 }, { 0x1a00, 0x33ca, 0x0000 }, { 0x1a00, 0x33cc, 0x0000 }, { 0x9a00, 0x33cf, 0x2000 }, { 0x1a00, 0x33ce, 0x0000 }, { 0x1a00, 0x33d0, 0x0000 }, { 0x9a00, 0x33f1, 0x6000 }, { 0x9a00, 0x33e1, 0x5000 }, { 0x9a00, 0x33d9, 0x4000 }, { 0x9a00, 0x33d5, 0x3000 }, { 0x9a00, 0x33d3, 0x2000 }, { 0x1a00, 0x33d2, 0x0000 }, { 0x1a00, 0x33d4, 0x0000 }, { 0x9a00, 0x33d7, 0x2000 }, { 0x1a00, 0x33d6, 0x0000 }, { 0x1a00, 0x33d8, 0x0000 }, { 0x9a00, 0x33dd, 0x3000 }, { 0x9a00, 0x33db, 0x2000 }, { 0x1a00, 0x33da, 0x0000 }, { 0x1a00, 0x33dc, 0x0000 }, { 0x9a00, 0x33df, 0x2000 }, { 0x1a00, 0x33de, 0x0000 }, { 0x1a00, 0x33e0, 0x0000 }, { 0x9a00, 0x33e9, 0x4000 }, { 0x9a00, 0x33e5, 0x3000 }, { 0x9a00, 0x33e3, 0x2000 }, { 0x1a00, 0x33e2, 0x0000 }, { 0x1a00, 0x33e4, 0x0000 }, { 0x9a00, 0x33e7, 0x2000 }, { 0x1a00, 0x33e6, 0x0000 }, { 0x1a00, 0x33e8, 0x0000 }, { 0x9a00, 0x33ed, 0x3000 }, { 0x9a00, 0x33eb, 0x2000 }, { 0x1a00, 0x33ea, 0x0000 }, { 0x1a00, 0x33ec, 0x0000 }, { 0x9a00, 0x33ef, 0x2000 }, { 0x1a00, 0x33ee, 0x0000 }, { 0x1a00, 0x33f0, 0x0000 }, { 0x8700, 0x4db5, 0x5000 }, { 0x9a00, 0x33f9, 0x4000 }, { 0x9a00, 0x33f5, 0x3000 }, { 0x9a00, 0x33f3, 0x2000 }, { 0x1a00, 0x33f2, 0x0000 }, { 0x1a00, 0x33f4, 0x0000 }, { 0x9a00, 0x33f7, 0x2000 }, { 0x1a00, 0x33f6, 0x0000 }, { 0x1a00, 0x33f8, 0x0000 }, { 0x9a00, 0x33fd, 0x3000 }, { 0x9a00, 0x33fb, 0x2000 }, { 0x1a00, 0x33fa, 0x0000 }, { 0x1a00, 0x33fc, 0x0000 }, { 0x9a00, 0x33ff, 0x2000 }, { 0x1a00, 0x33fe, 0x0000 }, { 0x0700, 0x3400, 0x0000 }, { 0x9a00, 0x4dc7, 0x4000 }, { 0x9a00, 0x4dc3, 0x3000 }, { 0x9a00, 0x4dc1, 0x2000 }, { 0x1a00, 0x4dc0, 0x0000 }, { 0x1a00, 0x4dc2, 0x0000 }, { 0x9a00, 0x4dc5, 0x2000 }, { 0x1a00, 0x4dc4, 0x0000 }, { 0x1a00, 0x4dc6, 0x0000 }, { 0x9a00, 0x4dcb, 0x3000 }, { 0x9a00, 0x4dc9, 0x2000 }, { 0x1a00, 0x4dc8, 0x0000 }, { 0x1a00, 0x4dca, 0x0000 }, { 0x9a00, 0x4dcd, 0x2000 }, { 0x1a00, 0x4dcc, 0x0000 }, { 0x1a00, 0x4dce, 0x0000 }, { 0x8700, 0xa00d, 0x7000 }, { 0x9a00, 0x4def, 0x6000 }, { 0x9a00, 0x4ddf, 0x5000 }, { 0x9a00, 0x4dd7, 0x4000 }, { 0x9a00, 0x4dd3, 0x3000 }, { 0x9a00, 0x4dd1, 0x2000 }, { 0x1a00, 0x4dd0, 0x0000 }, { 0x1a00, 0x4dd2, 0x0000 }, { 0x9a00, 0x4dd5, 0x2000 }, { 0x1a00, 0x4dd4, 0x0000 }, { 0x1a00, 0x4dd6, 0x0000 }, { 0x9a00, 0x4ddb, 0x3000 }, { 0x9a00, 0x4dd9, 0x2000 }, { 0x1a00, 0x4dd8, 0x0000 }, { 0x1a00, 0x4dda, 0x0000 }, { 0x9a00, 0x4ddd, 0x2000 }, { 0x1a00, 0x4ddc, 0x0000 }, { 0x1a00, 0x4dde, 0x0000 }, { 0x9a00, 0x4de7, 0x4000 }, { 0x9a00, 0x4de3, 0x3000 }, { 0x9a00, 0x4de1, 0x2000 }, { 0x1a00, 0x4de0, 0x0000 }, { 0x1a00, 0x4de2, 0x0000 }, { 0x9a00, 0x4de5, 0x2000 }, { 0x1a00, 0x4de4, 0x0000 }, { 0x1a00, 0x4de6, 0x0000 }, { 0x9a00, 0x4deb, 0x3000 }, { 0x9a00, 0x4de9, 0x2000 }, { 0x1a00, 0x4de8, 0x0000 }, { 0x1a00, 0x4dea, 0x0000 }, { 0x9a00, 0x4ded, 0x2000 }, { 0x1a00, 0x4dec, 0x0000 }, { 0x1a00, 0x4dee, 0x0000 }, { 0x9a00, 0x4dff, 0x5000 }, { 0x9a00, 0x4df7, 0x4000 }, { 0x9a00, 0x4df3, 0x3000 }, { 0x9a00, 0x4df1, 0x2000 }, { 0x1a00, 0x4df0, 0x0000 }, { 0x1a00, 0x4df2, 0x0000 }, { 0x9a00, 0x4df5, 0x2000 }, { 0x1a00, 0x4df4, 0x0000 }, { 0x1a00, 0x4df6, 0x0000 }, { 0x9a00, 0x4dfb, 0x3000 }, { 0x9a00, 0x4df9, 0x2000 }, { 0x1a00, 0x4df8, 0x0000 }, { 0x1a00, 0x4dfa, 0x0000 }, { 0x9a00, 0x4dfd, 0x2000 }, { 0x1a00, 0x4dfc, 0x0000 }, { 0x1a00, 0x4dfe, 0x0000 }, { 0x8700, 0xa005, 0x4000 }, { 0x8700, 0xa001, 0x3000 }, { 0x8700, 0x9fa5, 0x2000 }, { 0x0700, 0x4e00, 0x0000 }, { 0x0700, 0xa000, 0x0000 }, { 0x8700, 0xa003, 0x2000 }, { 0x0700, 0xa002, 0x0000 }, { 0x0700, 0xa004, 0x0000 }, { 0x8700, 0xa009, 0x3000 }, { 0x8700, 0xa007, 0x2000 }, { 0x0700, 0xa006, 0x0000 }, { 0x0700, 0xa008, 0x0000 }, { 0x8700, 0xa00b, 0x2000 }, { 0x0700, 0xa00a, 0x0000 }, { 0x0700, 0xa00c, 0x0000 }, { 0x8700, 0xa02d, 0x6000 }, { 0x8700, 0xa01d, 0x5000 }, { 0x8700, 0xa015, 0x4000 }, { 0x8700, 0xa011, 0x3000 }, { 0x8700, 0xa00f, 0x2000 }, { 0x0700, 0xa00e, 0x0000 }, { 0x0700, 0xa010, 0x0000 }, { 0x8700, 0xa013, 0x2000 }, { 0x0700, 0xa012, 0x0000 }, { 0x0700, 0xa014, 0x0000 }, { 0x8700, 0xa019, 0x3000 }, { 0x8700, 0xa017, 0x2000 }, { 0x0700, 0xa016, 0x0000 }, { 0x0700, 0xa018, 0x0000 }, { 0x8700, 0xa01b, 0x2000 }, { 0x0700, 0xa01a, 0x0000 }, { 0x0700, 0xa01c, 0x0000 }, { 0x8700, 0xa025, 0x4000 }, { 0x8700, 0xa021, 0x3000 }, { 0x8700, 0xa01f, 0x2000 }, { 0x0700, 0xa01e, 0x0000 }, { 0x0700, 0xa020, 0x0000 }, { 0x8700, 0xa023, 0x2000 }, { 0x0700, 0xa022, 0x0000 }, { 0x0700, 0xa024, 0x0000 }, { 0x8700, 0xa029, 0x3000 }, { 0x8700, 0xa027, 0x2000 }, { 0x0700, 0xa026, 0x0000 }, { 0x0700, 0xa028, 0x0000 }, { 0x8700, 0xa02b, 0x2000 }, { 0x0700, 0xa02a, 0x0000 }, { 0x0700, 0xa02c, 0x0000 }, { 0x8700, 0xa03d, 0x5000 }, { 0x8700, 0xa035, 0x4000 }, { 0x8700, 0xa031, 0x3000 }, { 0x8700, 0xa02f, 0x2000 }, { 0x0700, 0xa02e, 0x0000 }, { 0x0700, 0xa030, 0x0000 }, { 0x8700, 0xa033, 0x2000 }, { 0x0700, 0xa032, 0x0000 }, { 0x0700, 0xa034, 0x0000 }, { 0x8700, 0xa039, 0x3000 }, { 0x8700, 0xa037, 0x2000 }, { 0x0700, 0xa036, 0x0000 }, { 0x0700, 0xa038, 0x0000 }, { 0x8700, 0xa03b, 0x2000 }, { 0x0700, 0xa03a, 0x0000 }, { 0x0700, 0xa03c, 0x0000 }, { 0x8700, 0xa045, 0x4000 }, { 0x8700, 0xa041, 0x3000 }, { 0x8700, 0xa03f, 0x2000 }, { 0x0700, 0xa03e, 0x0000 }, { 0x0700, 0xa040, 0x0000 }, { 0x8700, 0xa043, 0x2000 }, { 0x0700, 0xa042, 0x0000 }, { 0x0700, 0xa044, 0x0000 }, { 0x8700, 0xa049, 0x3000 }, { 0x8700, 0xa047, 0x2000 }, { 0x0700, 0xa046, 0x0000 }, { 0x0700, 0xa048, 0x0000 }, { 0x8700, 0xa04b, 0x2000 }, { 0x0700, 0xa04a, 0x0000 }, { 0x0700, 0xa04c, 0x0000 }, { 0x8700, 0xa0cd, 0x8000 }, { 0x8700, 0xa08d, 0x7000 }, { 0x8700, 0xa06d, 0x6000 }, { 0x8700, 0xa05d, 0x5000 }, { 0x8700, 0xa055, 0x4000 }, { 0x8700, 0xa051, 0x3000 }, { 0x8700, 0xa04f, 0x2000 }, { 0x0700, 0xa04e, 0x0000 }, { 0x0700, 0xa050, 0x0000 }, { 0x8700, 0xa053, 0x2000 }, { 0x0700, 0xa052, 0x0000 }, { 0x0700, 0xa054, 0x0000 }, { 0x8700, 0xa059, 0x3000 }, { 0x8700, 0xa057, 0x2000 }, { 0x0700, 0xa056, 0x0000 }, { 0x0700, 0xa058, 0x0000 }, { 0x8700, 0xa05b, 0x2000 }, { 0x0700, 0xa05a, 0x0000 }, { 0x0700, 0xa05c, 0x0000 }, { 0x8700, 0xa065, 0x4000 }, { 0x8700, 0xa061, 0x3000 }, { 0x8700, 0xa05f, 0x2000 }, { 0x0700, 0xa05e, 0x0000 }, { 0x0700, 0xa060, 0x0000 }, { 0x8700, 0xa063, 0x2000 }, { 0x0700, 0xa062, 0x0000 }, { 0x0700, 0xa064, 0x0000 }, { 0x8700, 0xa069, 0x3000 }, { 0x8700, 0xa067, 0x2000 }, { 0x0700, 0xa066, 0x0000 }, { 0x0700, 0xa068, 0x0000 }, { 0x8700, 0xa06b, 0x2000 }, { 0x0700, 0xa06a, 0x0000 }, { 0x0700, 0xa06c, 0x0000 }, { 0x8700, 0xa07d, 0x5000 }, { 0x8700, 0xa075, 0x4000 }, { 0x8700, 0xa071, 0x3000 }, { 0x8700, 0xa06f, 0x2000 }, { 0x0700, 0xa06e, 0x0000 }, { 0x0700, 0xa070, 0x0000 }, { 0x8700, 0xa073, 0x2000 }, { 0x0700, 0xa072, 0x0000 }, { 0x0700, 0xa074, 0x0000 }, { 0x8700, 0xa079, 0x3000 }, { 0x8700, 0xa077, 0x2000 }, { 0x0700, 0xa076, 0x0000 }, { 0x0700, 0xa078, 0x0000 }, { 0x8700, 0xa07b, 0x2000 }, { 0x0700, 0xa07a, 0x0000 }, { 0x0700, 0xa07c, 0x0000 }, { 0x8700, 0xa085, 0x4000 }, { 0x8700, 0xa081, 0x3000 }, { 0x8700, 0xa07f, 0x2000 }, { 0x0700, 0xa07e, 0x0000 }, { 0x0700, 0xa080, 0x0000 }, { 0x8700, 0xa083, 0x2000 }, { 0x0700, 0xa082, 0x0000 }, { 0x0700, 0xa084, 0x0000 }, { 0x8700, 0xa089, 0x3000 }, { 0x8700, 0xa087, 0x2000 }, { 0x0700, 0xa086, 0x0000 }, { 0x0700, 0xa088, 0x0000 }, { 0x8700, 0xa08b, 0x2000 }, { 0x0700, 0xa08a, 0x0000 }, { 0x0700, 0xa08c, 0x0000 }, { 0x8700, 0xa0ad, 0x6000 }, { 0x8700, 0xa09d, 0x5000 }, { 0x8700, 0xa095, 0x4000 }, { 0x8700, 0xa091, 0x3000 }, { 0x8700, 0xa08f, 0x2000 }, { 0x0700, 0xa08e, 0x0000 }, { 0x0700, 0xa090, 0x0000 }, { 0x8700, 0xa093, 0x2000 }, { 0x0700, 0xa092, 0x0000 }, { 0x0700, 0xa094, 0x0000 }, { 0x8700, 0xa099, 0x3000 }, { 0x8700, 0xa097, 0x2000 }, { 0x0700, 0xa096, 0x0000 }, { 0x0700, 0xa098, 0x0000 }, { 0x8700, 0xa09b, 0x2000 }, { 0x0700, 0xa09a, 0x0000 }, { 0x0700, 0xa09c, 0x0000 }, { 0x8700, 0xa0a5, 0x4000 }, { 0x8700, 0xa0a1, 0x3000 }, { 0x8700, 0xa09f, 0x2000 }, { 0x0700, 0xa09e, 0x0000 }, { 0x0700, 0xa0a0, 0x0000 }, { 0x8700, 0xa0a3, 0x2000 }, { 0x0700, 0xa0a2, 0x0000 }, { 0x0700, 0xa0a4, 0x0000 }, { 0x8700, 0xa0a9, 0x3000 }, { 0x8700, 0xa0a7, 0x2000 }, { 0x0700, 0xa0a6, 0x0000 }, { 0x0700, 0xa0a8, 0x0000 }, { 0x8700, 0xa0ab, 0x2000 }, { 0x0700, 0xa0aa, 0x0000 }, { 0x0700, 0xa0ac, 0x0000 }, { 0x8700, 0xa0bd, 0x5000 }, { 0x8700, 0xa0b5, 0x4000 }, { 0x8700, 0xa0b1, 0x3000 }, { 0x8700, 0xa0af, 0x2000 }, { 0x0700, 0xa0ae, 0x0000 }, { 0x0700, 0xa0b0, 0x0000 }, { 0x8700, 0xa0b3, 0x2000 }, { 0x0700, 0xa0b2, 0x0000 }, { 0x0700, 0xa0b4, 0x0000 }, { 0x8700, 0xa0b9, 0x3000 }, { 0x8700, 0xa0b7, 0x2000 }, { 0x0700, 0xa0b6, 0x0000 }, { 0x0700, 0xa0b8, 0x0000 }, { 0x8700, 0xa0bb, 0x2000 }, { 0x0700, 0xa0ba, 0x0000 }, { 0x0700, 0xa0bc, 0x0000 }, { 0x8700, 0xa0c5, 0x4000 }, { 0x8700, 0xa0c1, 0x3000 }, { 0x8700, 0xa0bf, 0x2000 }, { 0x0700, 0xa0be, 0x0000 }, { 0x0700, 0xa0c0, 0x0000 }, { 0x8700, 0xa0c3, 0x2000 }, { 0x0700, 0xa0c2, 0x0000 }, { 0x0700, 0xa0c4, 0x0000 }, { 0x8700, 0xa0c9, 0x3000 }, { 0x8700, 0xa0c7, 0x2000 }, { 0x0700, 0xa0c6, 0x0000 }, { 0x0700, 0xa0c8, 0x0000 }, { 0x8700, 0xa0cb, 0x2000 }, { 0x0700, 0xa0ca, 0x0000 }, { 0x0700, 0xa0cc, 0x0000 }, { 0x8700, 0xa10d, 0x7000 }, { 0x8700, 0xa0ed, 0x6000 }, { 0x8700, 0xa0dd, 0x5000 }, { 0x8700, 0xa0d5, 0x4000 }, { 0x8700, 0xa0d1, 0x3000 }, { 0x8700, 0xa0cf, 0x2000 }, { 0x0700, 0xa0ce, 0x0000 }, { 0x0700, 0xa0d0, 0x0000 }, { 0x8700, 0xa0d3, 0x2000 }, { 0x0700, 0xa0d2, 0x0000 }, { 0x0700, 0xa0d4, 0x0000 }, { 0x8700, 0xa0d9, 0x3000 }, { 0x8700, 0xa0d7, 0x2000 }, { 0x0700, 0xa0d6, 0x0000 }, { 0x0700, 0xa0d8, 0x0000 }, { 0x8700, 0xa0db, 0x2000 }, { 0x0700, 0xa0da, 0x0000 }, { 0x0700, 0xa0dc, 0x0000 }, { 0x8700, 0xa0e5, 0x4000 }, { 0x8700, 0xa0e1, 0x3000 }, { 0x8700, 0xa0df, 0x2000 }, { 0x0700, 0xa0de, 0x0000 }, { 0x0700, 0xa0e0, 0x0000 }, { 0x8700, 0xa0e3, 0x2000 }, { 0x0700, 0xa0e2, 0x0000 }, { 0x0700, 0xa0e4, 0x0000 }, { 0x8700, 0xa0e9, 0x3000 }, { 0x8700, 0xa0e7, 0x2000 }, { 0x0700, 0xa0e6, 0x0000 }, { 0x0700, 0xa0e8, 0x0000 }, { 0x8700, 0xa0eb, 0x2000 }, { 0x0700, 0xa0ea, 0x0000 }, { 0x0700, 0xa0ec, 0x0000 }, { 0x8700, 0xa0fd, 0x5000 }, { 0x8700, 0xa0f5, 0x4000 }, { 0x8700, 0xa0f1, 0x3000 }, { 0x8700, 0xa0ef, 0x2000 }, { 0x0700, 0xa0ee, 0x0000 }, { 0x0700, 0xa0f0, 0x0000 }, { 0x8700, 0xa0f3, 0x2000 }, { 0x0700, 0xa0f2, 0x0000 }, { 0x0700, 0xa0f4, 0x0000 }, { 0x8700, 0xa0f9, 0x3000 }, { 0x8700, 0xa0f7, 0x2000 }, { 0x0700, 0xa0f6, 0x0000 }, { 0x0700, 0xa0f8, 0x0000 }, { 0x8700, 0xa0fb, 0x2000 }, { 0x0700, 0xa0fa, 0x0000 }, { 0x0700, 0xa0fc, 0x0000 }, { 0x8700, 0xa105, 0x4000 }, { 0x8700, 0xa101, 0x3000 }, { 0x8700, 0xa0ff, 0x2000 }, { 0x0700, 0xa0fe, 0x0000 }, { 0x0700, 0xa100, 0x0000 }, { 0x8700, 0xa103, 0x2000 }, { 0x0700, 0xa102, 0x0000 }, { 0x0700, 0xa104, 0x0000 }, { 0x8700, 0xa109, 0x3000 }, { 0x8700, 0xa107, 0x2000 }, { 0x0700, 0xa106, 0x0000 }, { 0x0700, 0xa108, 0x0000 }, { 0x8700, 0xa10b, 0x2000 }, { 0x0700, 0xa10a, 0x0000 }, { 0x0700, 0xa10c, 0x0000 }, { 0x8700, 0xa12d, 0x6000 }, { 0x8700, 0xa11d, 0x5000 }, { 0x8700, 0xa115, 0x4000 }, { 0x8700, 0xa111, 0x3000 }, { 0x8700, 0xa10f, 0x2000 }, { 0x0700, 0xa10e, 0x0000 }, { 0x0700, 0xa110, 0x0000 }, { 0x8700, 0xa113, 0x2000 }, { 0x0700, 0xa112, 0x0000 }, { 0x0700, 0xa114, 0x0000 }, { 0x8700, 0xa119, 0x3000 }, { 0x8700, 0xa117, 0x2000 }, { 0x0700, 0xa116, 0x0000 }, { 0x0700, 0xa118, 0x0000 }, { 0x8700, 0xa11b, 0x2000 }, { 0x0700, 0xa11a, 0x0000 }, { 0x0700, 0xa11c, 0x0000 }, { 0x8700, 0xa125, 0x4000 }, { 0x8700, 0xa121, 0x3000 }, { 0x8700, 0xa11f, 0x2000 }, { 0x0700, 0xa11e, 0x0000 }, { 0x0700, 0xa120, 0x0000 }, { 0x8700, 0xa123, 0x2000 }, { 0x0700, 0xa122, 0x0000 }, { 0x0700, 0xa124, 0x0000 }, { 0x8700, 0xa129, 0x3000 }, { 0x8700, 0xa127, 0x2000 }, { 0x0700, 0xa126, 0x0000 }, { 0x0700, 0xa128, 0x0000 }, { 0x8700, 0xa12b, 0x2000 }, { 0x0700, 0xa12a, 0x0000 }, { 0x0700, 0xa12c, 0x0000 }, { 0x8700, 0xa13d, 0x5000 }, { 0x8700, 0xa135, 0x4000 }, { 0x8700, 0xa131, 0x3000 }, { 0x8700, 0xa12f, 0x2000 }, { 0x0700, 0xa12e, 0x0000 }, { 0x0700, 0xa130, 0x0000 }, { 0x8700, 0xa133, 0x2000 }, { 0x0700, 0xa132, 0x0000 }, { 0x0700, 0xa134, 0x0000 }, { 0x8700, 0xa139, 0x3000 }, { 0x8700, 0xa137, 0x2000 }, { 0x0700, 0xa136, 0x0000 }, { 0x0700, 0xa138, 0x0000 }, { 0x8700, 0xa13b, 0x2000 }, { 0x0700, 0xa13a, 0x0000 }, { 0x0700, 0xa13c, 0x0000 }, { 0x8700, 0xa145, 0x4000 }, { 0x8700, 0xa141, 0x3000 }, { 0x8700, 0xa13f, 0x2000 }, { 0x0700, 0xa13e, 0x0000 }, { 0x0700, 0xa140, 0x0000 }, { 0x8700, 0xa143, 0x2000 }, { 0x0700, 0xa142, 0x0000 }, { 0x0700, 0xa144, 0x0000 }, { 0x8700, 0xa149, 0x3000 }, { 0x8700, 0xa147, 0x2000 }, { 0x0700, 0xa146, 0x0000 }, { 0x0700, 0xa148, 0x0000 }, { 0x8700, 0xa14b, 0x2000 }, { 0x0700, 0xa14a, 0x0000 }, { 0x0700, 0xa14c, 0x0000 }, { 0x8700, 0xa24d, 0x9000 }, { 0x8700, 0xa1cd, 0x8000 }, { 0x8700, 0xa18d, 0x7000 }, { 0x8700, 0xa16d, 0x6000 }, { 0x8700, 0xa15d, 0x5000 }, { 0x8700, 0xa155, 0x4000 }, { 0x8700, 0xa151, 0x3000 }, { 0x8700, 0xa14f, 0x2000 }, { 0x0700, 0xa14e, 0x0000 }, { 0x0700, 0xa150, 0x0000 }, { 0x8700, 0xa153, 0x2000 }, { 0x0700, 0xa152, 0x0000 }, { 0x0700, 0xa154, 0x0000 }, { 0x8700, 0xa159, 0x3000 }, { 0x8700, 0xa157, 0x2000 }, { 0x0700, 0xa156, 0x0000 }, { 0x0700, 0xa158, 0x0000 }, { 0x8700, 0xa15b, 0x2000 }, { 0x0700, 0xa15a, 0x0000 }, { 0x0700, 0xa15c, 0x0000 }, { 0x8700, 0xa165, 0x4000 }, { 0x8700, 0xa161, 0x3000 }, { 0x8700, 0xa15f, 0x2000 }, { 0x0700, 0xa15e, 0x0000 }, { 0x0700, 0xa160, 0x0000 }, { 0x8700, 0xa163, 0x2000 }, { 0x0700, 0xa162, 0x0000 }, { 0x0700, 0xa164, 0x0000 }, { 0x8700, 0xa169, 0x3000 }, { 0x8700, 0xa167, 0x2000 }, { 0x0700, 0xa166, 0x0000 }, { 0x0700, 0xa168, 0x0000 }, { 0x8700, 0xa16b, 0x2000 }, { 0x0700, 0xa16a, 0x0000 }, { 0x0700, 0xa16c, 0x0000 }, { 0x8700, 0xa17d, 0x5000 }, { 0x8700, 0xa175, 0x4000 }, { 0x8700, 0xa171, 0x3000 }, { 0x8700, 0xa16f, 0x2000 }, { 0x0700, 0xa16e, 0x0000 }, { 0x0700, 0xa170, 0x0000 }, { 0x8700, 0xa173, 0x2000 }, { 0x0700, 0xa172, 0x0000 }, { 0x0700, 0xa174, 0x0000 }, { 0x8700, 0xa179, 0x3000 }, { 0x8700, 0xa177, 0x2000 }, { 0x0700, 0xa176, 0x0000 }, { 0x0700, 0xa178, 0x0000 }, { 0x8700, 0xa17b, 0x2000 }, { 0x0700, 0xa17a, 0x0000 }, { 0x0700, 0xa17c, 0x0000 }, { 0x8700, 0xa185, 0x4000 }, { 0x8700, 0xa181, 0x3000 }, { 0x8700, 0xa17f, 0x2000 }, { 0x0700, 0xa17e, 0x0000 }, { 0x0700, 0xa180, 0x0000 }, { 0x8700, 0xa183, 0x2000 }, { 0x0700, 0xa182, 0x0000 }, { 0x0700, 0xa184, 0x0000 }, { 0x8700, 0xa189, 0x3000 }, { 0x8700, 0xa187, 0x2000 }, { 0x0700, 0xa186, 0x0000 }, { 0x0700, 0xa188, 0x0000 }, { 0x8700, 0xa18b, 0x2000 }, { 0x0700, 0xa18a, 0x0000 }, { 0x0700, 0xa18c, 0x0000 }, { 0x8700, 0xa1ad, 0x6000 }, { 0x8700, 0xa19d, 0x5000 }, { 0x8700, 0xa195, 0x4000 }, { 0x8700, 0xa191, 0x3000 }, { 0x8700, 0xa18f, 0x2000 }, { 0x0700, 0xa18e, 0x0000 }, { 0x0700, 0xa190, 0x0000 }, { 0x8700, 0xa193, 0x2000 }, { 0x0700, 0xa192, 0x0000 }, { 0x0700, 0xa194, 0x0000 }, { 0x8700, 0xa199, 0x3000 }, { 0x8700, 0xa197, 0x2000 }, { 0x0700, 0xa196, 0x0000 }, { 0x0700, 0xa198, 0x0000 }, { 0x8700, 0xa19b, 0x2000 }, { 0x0700, 0xa19a, 0x0000 }, { 0x0700, 0xa19c, 0x0000 }, { 0x8700, 0xa1a5, 0x4000 }, { 0x8700, 0xa1a1, 0x3000 }, { 0x8700, 0xa19f, 0x2000 }, { 0x0700, 0xa19e, 0x0000 }, { 0x0700, 0xa1a0, 0x0000 }, { 0x8700, 0xa1a3, 0x2000 }, { 0x0700, 0xa1a2, 0x0000 }, { 0x0700, 0xa1a4, 0x0000 }, { 0x8700, 0xa1a9, 0x3000 }, { 0x8700, 0xa1a7, 0x2000 }, { 0x0700, 0xa1a6, 0x0000 }, { 0x0700, 0xa1a8, 0x0000 }, { 0x8700, 0xa1ab, 0x2000 }, { 0x0700, 0xa1aa, 0x0000 }, { 0x0700, 0xa1ac, 0x0000 }, { 0x8700, 0xa1bd, 0x5000 }, { 0x8700, 0xa1b5, 0x4000 }, { 0x8700, 0xa1b1, 0x3000 }, { 0x8700, 0xa1af, 0x2000 }, { 0x0700, 0xa1ae, 0x0000 }, { 0x0700, 0xa1b0, 0x0000 }, { 0x8700, 0xa1b3, 0x2000 }, { 0x0700, 0xa1b2, 0x0000 }, { 0x0700, 0xa1b4, 0x0000 }, { 0x8700, 0xa1b9, 0x3000 }, { 0x8700, 0xa1b7, 0x2000 }, { 0x0700, 0xa1b6, 0x0000 }, { 0x0700, 0xa1b8, 0x0000 }, { 0x8700, 0xa1bb, 0x2000 }, { 0x0700, 0xa1ba, 0x0000 }, { 0x0700, 0xa1bc, 0x0000 }, { 0x8700, 0xa1c5, 0x4000 }, { 0x8700, 0xa1c1, 0x3000 }, { 0x8700, 0xa1bf, 0x2000 }, { 0x0700, 0xa1be, 0x0000 }, { 0x0700, 0xa1c0, 0x0000 }, { 0x8700, 0xa1c3, 0x2000 }, { 0x0700, 0xa1c2, 0x0000 }, { 0x0700, 0xa1c4, 0x0000 }, { 0x8700, 0xa1c9, 0x3000 }, { 0x8700, 0xa1c7, 0x2000 }, { 0x0700, 0xa1c6, 0x0000 }, { 0x0700, 0xa1c8, 0x0000 }, { 0x8700, 0xa1cb, 0x2000 }, { 0x0700, 0xa1ca, 0x0000 }, { 0x0700, 0xa1cc, 0x0000 }, { 0x8700, 0xa20d, 0x7000 }, { 0x8700, 0xa1ed, 0x6000 }, { 0x8700, 0xa1dd, 0x5000 }, { 0x8700, 0xa1d5, 0x4000 }, { 0x8700, 0xa1d1, 0x3000 }, { 0x8700, 0xa1cf, 0x2000 }, { 0x0700, 0xa1ce, 0x0000 }, { 0x0700, 0xa1d0, 0x0000 }, { 0x8700, 0xa1d3, 0x2000 }, { 0x0700, 0xa1d2, 0x0000 }, { 0x0700, 0xa1d4, 0x0000 }, { 0x8700, 0xa1d9, 0x3000 }, { 0x8700, 0xa1d7, 0x2000 }, { 0x0700, 0xa1d6, 0x0000 }, { 0x0700, 0xa1d8, 0x0000 }, { 0x8700, 0xa1db, 0x2000 }, { 0x0700, 0xa1da, 0x0000 }, { 0x0700, 0xa1dc, 0x0000 }, { 0x8700, 0xa1e5, 0x4000 }, { 0x8700, 0xa1e1, 0x3000 }, { 0x8700, 0xa1df, 0x2000 }, { 0x0700, 0xa1de, 0x0000 }, { 0x0700, 0xa1e0, 0x0000 }, { 0x8700, 0xa1e3, 0x2000 }, { 0x0700, 0xa1e2, 0x0000 }, { 0x0700, 0xa1e4, 0x0000 }, { 0x8700, 0xa1e9, 0x3000 }, { 0x8700, 0xa1e7, 0x2000 }, { 0x0700, 0xa1e6, 0x0000 }, { 0x0700, 0xa1e8, 0x0000 }, { 0x8700, 0xa1eb, 0x2000 }, { 0x0700, 0xa1ea, 0x0000 }, { 0x0700, 0xa1ec, 0x0000 }, { 0x8700, 0xa1fd, 0x5000 }, { 0x8700, 0xa1f5, 0x4000 }, { 0x8700, 0xa1f1, 0x3000 }, { 0x8700, 0xa1ef, 0x2000 }, { 0x0700, 0xa1ee, 0x0000 }, { 0x0700, 0xa1f0, 0x0000 }, { 0x8700, 0xa1f3, 0x2000 }, { 0x0700, 0xa1f2, 0x0000 }, { 0x0700, 0xa1f4, 0x0000 }, { 0x8700, 0xa1f9, 0x3000 }, { 0x8700, 0xa1f7, 0x2000 }, { 0x0700, 0xa1f6, 0x0000 }, { 0x0700, 0xa1f8, 0x0000 }, { 0x8700, 0xa1fb, 0x2000 }, { 0x0700, 0xa1fa, 0x0000 }, { 0x0700, 0xa1fc, 0x0000 }, { 0x8700, 0xa205, 0x4000 }, { 0x8700, 0xa201, 0x3000 }, { 0x8700, 0xa1ff, 0x2000 }, { 0x0700, 0xa1fe, 0x0000 }, { 0x0700, 0xa200, 0x0000 }, { 0x8700, 0xa203, 0x2000 }, { 0x0700, 0xa202, 0x0000 }, { 0x0700, 0xa204, 0x0000 }, { 0x8700, 0xa209, 0x3000 }, { 0x8700, 0xa207, 0x2000 }, { 0x0700, 0xa206, 0x0000 }, { 0x0700, 0xa208, 0x0000 }, { 0x8700, 0xa20b, 0x2000 }, { 0x0700, 0xa20a, 0x0000 }, { 0x0700, 0xa20c, 0x0000 }, { 0x8700, 0xa22d, 0x6000 }, { 0x8700, 0xa21d, 0x5000 }, { 0x8700, 0xa215, 0x4000 }, { 0x8700, 0xa211, 0x3000 }, { 0x8700, 0xa20f, 0x2000 }, { 0x0700, 0xa20e, 0x0000 }, { 0x0700, 0xa210, 0x0000 }, { 0x8700, 0xa213, 0x2000 }, { 0x0700, 0xa212, 0x0000 }, { 0x0700, 0xa214, 0x0000 }, { 0x8700, 0xa219, 0x3000 }, { 0x8700, 0xa217, 0x2000 }, { 0x0700, 0xa216, 0x0000 }, { 0x0700, 0xa218, 0x0000 }, { 0x8700, 0xa21b, 0x2000 }, { 0x0700, 0xa21a, 0x0000 }, { 0x0700, 0xa21c, 0x0000 }, { 0x8700, 0xa225, 0x4000 }, { 0x8700, 0xa221, 0x3000 }, { 0x8700, 0xa21f, 0x2000 }, { 0x0700, 0xa21e, 0x0000 }, { 0x0700, 0xa220, 0x0000 }, { 0x8700, 0xa223, 0x2000 }, { 0x0700, 0xa222, 0x0000 }, { 0x0700, 0xa224, 0x0000 }, { 0x8700, 0xa229, 0x3000 }, { 0x8700, 0xa227, 0x2000 }, { 0x0700, 0xa226, 0x0000 }, { 0x0700, 0xa228, 0x0000 }, { 0x8700, 0xa22b, 0x2000 }, { 0x0700, 0xa22a, 0x0000 }, { 0x0700, 0xa22c, 0x0000 }, { 0x8700, 0xa23d, 0x5000 }, { 0x8700, 0xa235, 0x4000 }, { 0x8700, 0xa231, 0x3000 }, { 0x8700, 0xa22f, 0x2000 }, { 0x0700, 0xa22e, 0x0000 }, { 0x0700, 0xa230, 0x0000 }, { 0x8700, 0xa233, 0x2000 }, { 0x0700, 0xa232, 0x0000 }, { 0x0700, 0xa234, 0x0000 }, { 0x8700, 0xa239, 0x3000 }, { 0x8700, 0xa237, 0x2000 }, { 0x0700, 0xa236, 0x0000 }, { 0x0700, 0xa238, 0x0000 }, { 0x8700, 0xa23b, 0x2000 }, { 0x0700, 0xa23a, 0x0000 }, { 0x0700, 0xa23c, 0x0000 }, { 0x8700, 0xa245, 0x4000 }, { 0x8700, 0xa241, 0x3000 }, { 0x8700, 0xa23f, 0x2000 }, { 0x0700, 0xa23e, 0x0000 }, { 0x0700, 0xa240, 0x0000 }, { 0x8700, 0xa243, 0x2000 }, { 0x0700, 0xa242, 0x0000 }, { 0x0700, 0xa244, 0x0000 }, { 0x8700, 0xa249, 0x3000 }, { 0x8700, 0xa247, 0x2000 }, { 0x0700, 0xa246, 0x0000 }, { 0x0700, 0xa248, 0x0000 }, { 0x8700, 0xa24b, 0x2000 }, { 0x0700, 0xa24a, 0x0000 }, { 0x0700, 0xa24c, 0x0000 }, { 0x8700, 0xa2cd, 0x8000 }, { 0x8700, 0xa28d, 0x7000 }, { 0x8700, 0xa26d, 0x6000 }, { 0x8700, 0xa25d, 0x5000 }, { 0x8700, 0xa255, 0x4000 }, { 0x8700, 0xa251, 0x3000 }, { 0x8700, 0xa24f, 0x2000 }, { 0x0700, 0xa24e, 0x0000 }, { 0x0700, 0xa250, 0x0000 }, { 0x8700, 0xa253, 0x2000 }, { 0x0700, 0xa252, 0x0000 }, { 0x0700, 0xa254, 0x0000 }, { 0x8700, 0xa259, 0x3000 }, { 0x8700, 0xa257, 0x2000 }, { 0x0700, 0xa256, 0x0000 }, { 0x0700, 0xa258, 0x0000 }, { 0x8700, 0xa25b, 0x2000 }, { 0x0700, 0xa25a, 0x0000 }, { 0x0700, 0xa25c, 0x0000 }, { 0x8700, 0xa265, 0x4000 }, { 0x8700, 0xa261, 0x3000 }, { 0x8700, 0xa25f, 0x2000 }, { 0x0700, 0xa25e, 0x0000 }, { 0x0700, 0xa260, 0x0000 }, { 0x8700, 0xa263, 0x2000 }, { 0x0700, 0xa262, 0x0000 }, { 0x0700, 0xa264, 0x0000 }, { 0x8700, 0xa269, 0x3000 }, { 0x8700, 0xa267, 0x2000 }, { 0x0700, 0xa266, 0x0000 }, { 0x0700, 0xa268, 0x0000 }, { 0x8700, 0xa26b, 0x2000 }, { 0x0700, 0xa26a, 0x0000 }, { 0x0700, 0xa26c, 0x0000 }, { 0x8700, 0xa27d, 0x5000 }, { 0x8700, 0xa275, 0x4000 }, { 0x8700, 0xa271, 0x3000 }, { 0x8700, 0xa26f, 0x2000 }, { 0x0700, 0xa26e, 0x0000 }, { 0x0700, 0xa270, 0x0000 }, { 0x8700, 0xa273, 0x2000 }, { 0x0700, 0xa272, 0x0000 }, { 0x0700, 0xa274, 0x0000 }, { 0x8700, 0xa279, 0x3000 }, { 0x8700, 0xa277, 0x2000 }, { 0x0700, 0xa276, 0x0000 }, { 0x0700, 0xa278, 0x0000 }, { 0x8700, 0xa27b, 0x2000 }, { 0x0700, 0xa27a, 0x0000 }, { 0x0700, 0xa27c, 0x0000 }, { 0x8700, 0xa285, 0x4000 }, { 0x8700, 0xa281, 0x3000 }, { 0x8700, 0xa27f, 0x2000 }, { 0x0700, 0xa27e, 0x0000 }, { 0x0700, 0xa280, 0x0000 }, { 0x8700, 0xa283, 0x2000 }, { 0x0700, 0xa282, 0x0000 }, { 0x0700, 0xa284, 0x0000 }, { 0x8700, 0xa289, 0x3000 }, { 0x8700, 0xa287, 0x2000 }, { 0x0700, 0xa286, 0x0000 }, { 0x0700, 0xa288, 0x0000 }, { 0x8700, 0xa28b, 0x2000 }, { 0x0700, 0xa28a, 0x0000 }, { 0x0700, 0xa28c, 0x0000 }, { 0x8700, 0xa2ad, 0x6000 }, { 0x8700, 0xa29d, 0x5000 }, { 0x8700, 0xa295, 0x4000 }, { 0x8700, 0xa291, 0x3000 }, { 0x8700, 0xa28f, 0x2000 }, { 0x0700, 0xa28e, 0x0000 }, { 0x0700, 0xa290, 0x0000 }, { 0x8700, 0xa293, 0x2000 }, { 0x0700, 0xa292, 0x0000 }, { 0x0700, 0xa294, 0x0000 }, { 0x8700, 0xa299, 0x3000 }, { 0x8700, 0xa297, 0x2000 }, { 0x0700, 0xa296, 0x0000 }, { 0x0700, 0xa298, 0x0000 }, { 0x8700, 0xa29b, 0x2000 }, { 0x0700, 0xa29a, 0x0000 }, { 0x0700, 0xa29c, 0x0000 }, { 0x8700, 0xa2a5, 0x4000 }, { 0x8700, 0xa2a1, 0x3000 }, { 0x8700, 0xa29f, 0x2000 }, { 0x0700, 0xa29e, 0x0000 }, { 0x0700, 0xa2a0, 0x0000 }, { 0x8700, 0xa2a3, 0x2000 }, { 0x0700, 0xa2a2, 0x0000 }, { 0x0700, 0xa2a4, 0x0000 }, { 0x8700, 0xa2a9, 0x3000 }, { 0x8700, 0xa2a7, 0x2000 }, { 0x0700, 0xa2a6, 0x0000 }, { 0x0700, 0xa2a8, 0x0000 }, { 0x8700, 0xa2ab, 0x2000 }, { 0x0700, 0xa2aa, 0x0000 }, { 0x0700, 0xa2ac, 0x0000 }, { 0x8700, 0xa2bd, 0x5000 }, { 0x8700, 0xa2b5, 0x4000 }, { 0x8700, 0xa2b1, 0x3000 }, { 0x8700, 0xa2af, 0x2000 }, { 0x0700, 0xa2ae, 0x0000 }, { 0x0700, 0xa2b0, 0x0000 }, { 0x8700, 0xa2b3, 0x2000 }, { 0x0700, 0xa2b2, 0x0000 }, { 0x0700, 0xa2b4, 0x0000 }, { 0x8700, 0xa2b9, 0x3000 }, { 0x8700, 0xa2b7, 0x2000 }, { 0x0700, 0xa2b6, 0x0000 }, { 0x0700, 0xa2b8, 0x0000 }, { 0x8700, 0xa2bb, 0x2000 }, { 0x0700, 0xa2ba, 0x0000 }, { 0x0700, 0xa2bc, 0x0000 }, { 0x8700, 0xa2c5, 0x4000 }, { 0x8700, 0xa2c1, 0x3000 }, { 0x8700, 0xa2bf, 0x2000 }, { 0x0700, 0xa2be, 0x0000 }, { 0x0700, 0xa2c0, 0x0000 }, { 0x8700, 0xa2c3, 0x2000 }, { 0x0700, 0xa2c2, 0x0000 }, { 0x0700, 0xa2c4, 0x0000 }, { 0x8700, 0xa2c9, 0x3000 }, { 0x8700, 0xa2c7, 0x2000 }, { 0x0700, 0xa2c6, 0x0000 }, { 0x0700, 0xa2c8, 0x0000 }, { 0x8700, 0xa2cb, 0x2000 }, { 0x0700, 0xa2ca, 0x0000 }, { 0x0700, 0xa2cc, 0x0000 }, { 0x8700, 0xa30d, 0x7000 }, { 0x8700, 0xa2ed, 0x6000 }, { 0x8700, 0xa2dd, 0x5000 }, { 0x8700, 0xa2d5, 0x4000 }, { 0x8700, 0xa2d1, 0x3000 }, { 0x8700, 0xa2cf, 0x2000 }, { 0x0700, 0xa2ce, 0x0000 }, { 0x0700, 0xa2d0, 0x0000 }, { 0x8700, 0xa2d3, 0x2000 }, { 0x0700, 0xa2d2, 0x0000 }, { 0x0700, 0xa2d4, 0x0000 }, { 0x8700, 0xa2d9, 0x3000 }, { 0x8700, 0xa2d7, 0x2000 }, { 0x0700, 0xa2d6, 0x0000 }, { 0x0700, 0xa2d8, 0x0000 }, { 0x8700, 0xa2db, 0x2000 }, { 0x0700, 0xa2da, 0x0000 }, { 0x0700, 0xa2dc, 0x0000 }, { 0x8700, 0xa2e5, 0x4000 }, { 0x8700, 0xa2e1, 0x3000 }, { 0x8700, 0xa2df, 0x2000 }, { 0x0700, 0xa2de, 0x0000 }, { 0x0700, 0xa2e0, 0x0000 }, { 0x8700, 0xa2e3, 0x2000 }, { 0x0700, 0xa2e2, 0x0000 }, { 0x0700, 0xa2e4, 0x0000 }, { 0x8700, 0xa2e9, 0x3000 }, { 0x8700, 0xa2e7, 0x2000 }, { 0x0700, 0xa2e6, 0x0000 }, { 0x0700, 0xa2e8, 0x0000 }, { 0x8700, 0xa2eb, 0x2000 }, { 0x0700, 0xa2ea, 0x0000 }, { 0x0700, 0xa2ec, 0x0000 }, { 0x8700, 0xa2fd, 0x5000 }, { 0x8700, 0xa2f5, 0x4000 }, { 0x8700, 0xa2f1, 0x3000 }, { 0x8700, 0xa2ef, 0x2000 }, { 0x0700, 0xa2ee, 0x0000 }, { 0x0700, 0xa2f0, 0x0000 }, { 0x8700, 0xa2f3, 0x2000 }, { 0x0700, 0xa2f2, 0x0000 }, { 0x0700, 0xa2f4, 0x0000 }, { 0x8700, 0xa2f9, 0x3000 }, { 0x8700, 0xa2f7, 0x2000 }, { 0x0700, 0xa2f6, 0x0000 }, { 0x0700, 0xa2f8, 0x0000 }, { 0x8700, 0xa2fb, 0x2000 }, { 0x0700, 0xa2fa, 0x0000 }, { 0x0700, 0xa2fc, 0x0000 }, { 0x8700, 0xa305, 0x4000 }, { 0x8700, 0xa301, 0x3000 }, { 0x8700, 0xa2ff, 0x2000 }, { 0x0700, 0xa2fe, 0x0000 }, { 0x0700, 0xa300, 0x0000 }, { 0x8700, 0xa303, 0x2000 }, { 0x0700, 0xa302, 0x0000 }, { 0x0700, 0xa304, 0x0000 }, { 0x8700, 0xa309, 0x3000 }, { 0x8700, 0xa307, 0x2000 }, { 0x0700, 0xa306, 0x0000 }, { 0x0700, 0xa308, 0x0000 }, { 0x8700, 0xa30b, 0x2000 }, { 0x0700, 0xa30a, 0x0000 }, { 0x0700, 0xa30c, 0x0000 }, { 0x8700, 0xa32d, 0x6000 }, { 0x8700, 0xa31d, 0x5000 }, { 0x8700, 0xa315, 0x4000 }, { 0x8700, 0xa311, 0x3000 }, { 0x8700, 0xa30f, 0x2000 }, { 0x0700, 0xa30e, 0x0000 }, { 0x0700, 0xa310, 0x0000 }, { 0x8700, 0xa313, 0x2000 }, { 0x0700, 0xa312, 0x0000 }, { 0x0700, 0xa314, 0x0000 }, { 0x8700, 0xa319, 0x3000 }, { 0x8700, 0xa317, 0x2000 }, { 0x0700, 0xa316, 0x0000 }, { 0x0700, 0xa318, 0x0000 }, { 0x8700, 0xa31b, 0x2000 }, { 0x0700, 0xa31a, 0x0000 }, { 0x0700, 0xa31c, 0x0000 }, { 0x8700, 0xa325, 0x4000 }, { 0x8700, 0xa321, 0x3000 }, { 0x8700, 0xa31f, 0x2000 }, { 0x0700, 0xa31e, 0x0000 }, { 0x0700, 0xa320, 0x0000 }, { 0x8700, 0xa323, 0x2000 }, { 0x0700, 0xa322, 0x0000 }, { 0x0700, 0xa324, 0x0000 }, { 0x8700, 0xa329, 0x3000 }, { 0x8700, 0xa327, 0x2000 }, { 0x0700, 0xa326, 0x0000 }, { 0x0700, 0xa328, 0x0000 }, { 0x8700, 0xa32b, 0x2000 }, { 0x0700, 0xa32a, 0x0000 }, { 0x0700, 0xa32c, 0x0000 }, { 0x8700, 0xa33d, 0x5000 }, { 0x8700, 0xa335, 0x4000 }, { 0x8700, 0xa331, 0x3000 }, { 0x8700, 0xa32f, 0x2000 }, { 0x0700, 0xa32e, 0x0000 }, { 0x0700, 0xa330, 0x0000 }, { 0x8700, 0xa333, 0x2000 }, { 0x0700, 0xa332, 0x0000 }, { 0x0700, 0xa334, 0x0000 }, { 0x8700, 0xa339, 0x3000 }, { 0x8700, 0xa337, 0x2000 }, { 0x0700, 0xa336, 0x0000 }, { 0x0700, 0xa338, 0x0000 }, { 0x8700, 0xa33b, 0x2000 }, { 0x0700, 0xa33a, 0x0000 }, { 0x0700, 0xa33c, 0x0000 }, { 0x8700, 0xa345, 0x4000 }, { 0x8700, 0xa341, 0x3000 }, { 0x8700, 0xa33f, 0x2000 }, { 0x0700, 0xa33e, 0x0000 }, { 0x0700, 0xa340, 0x0000 }, { 0x8700, 0xa343, 0x2000 }, { 0x0700, 0xa342, 0x0000 }, { 0x0700, 0xa344, 0x0000 }, { 0x8700, 0xa349, 0x3000 }, { 0x8700, 0xa347, 0x2000 }, { 0x0700, 0xa346, 0x0000 }, { 0x0700, 0xa348, 0x0000 }, { 0x8700, 0xa34b, 0x2000 }, { 0x0700, 0xa34a, 0x0000 }, { 0x0700, 0xa34c, 0x0000 }, { 0x8700, 0xfc4d, 0xb000 }, { 0x8700, 0xf97f, 0xa000 }, { 0x8700, 0xa44d, 0x9000 }, { 0x8700, 0xa3cd, 0x8000 }, { 0x8700, 0xa38d, 0x7000 }, { 0x8700, 0xa36d, 0x6000 }, { 0x8700, 0xa35d, 0x5000 }, { 0x8700, 0xa355, 0x4000 }, { 0x8700, 0xa351, 0x3000 }, { 0x8700, 0xa34f, 0x2000 }, { 0x0700, 0xa34e, 0x0000 }, { 0x0700, 0xa350, 0x0000 }, { 0x8700, 0xa353, 0x2000 }, { 0x0700, 0xa352, 0x0000 }, { 0x0700, 0xa354, 0x0000 }, { 0x8700, 0xa359, 0x3000 }, { 0x8700, 0xa357, 0x2000 }, { 0x0700, 0xa356, 0x0000 }, { 0x0700, 0xa358, 0x0000 }, { 0x8700, 0xa35b, 0x2000 }, { 0x0700, 0xa35a, 0x0000 }, { 0x0700, 0xa35c, 0x0000 }, { 0x8700, 0xa365, 0x4000 }, { 0x8700, 0xa361, 0x3000 }, { 0x8700, 0xa35f, 0x2000 }, { 0x0700, 0xa35e, 0x0000 }, { 0x0700, 0xa360, 0x0000 }, { 0x8700, 0xa363, 0x2000 }, { 0x0700, 0xa362, 0x0000 }, { 0x0700, 0xa364, 0x0000 }, { 0x8700, 0xa369, 0x3000 }, { 0x8700, 0xa367, 0x2000 }, { 0x0700, 0xa366, 0x0000 }, { 0x0700, 0xa368, 0x0000 }, { 0x8700, 0xa36b, 0x2000 }, { 0x0700, 0xa36a, 0x0000 }, { 0x0700, 0xa36c, 0x0000 }, { 0x8700, 0xa37d, 0x5000 }, { 0x8700, 0xa375, 0x4000 }, { 0x8700, 0xa371, 0x3000 }, { 0x8700, 0xa36f, 0x2000 }, { 0x0700, 0xa36e, 0x0000 }, { 0x0700, 0xa370, 0x0000 }, { 0x8700, 0xa373, 0x2000 }, { 0x0700, 0xa372, 0x0000 }, { 0x0700, 0xa374, 0x0000 }, { 0x8700, 0xa379, 0x3000 }, { 0x8700, 0xa377, 0x2000 }, { 0x0700, 0xa376, 0x0000 }, { 0x0700, 0xa378, 0x0000 }, { 0x8700, 0xa37b, 0x2000 }, { 0x0700, 0xa37a, 0x0000 }, { 0x0700, 0xa37c, 0x0000 }, { 0x8700, 0xa385, 0x4000 }, { 0x8700, 0xa381, 0x3000 }, { 0x8700, 0xa37f, 0x2000 }, { 0x0700, 0xa37e, 0x0000 }, { 0x0700, 0xa380, 0x0000 }, { 0x8700, 0xa383, 0x2000 }, { 0x0700, 0xa382, 0x0000 }, { 0x0700, 0xa384, 0x0000 }, { 0x8700, 0xa389, 0x3000 }, { 0x8700, 0xa387, 0x2000 }, { 0x0700, 0xa386, 0x0000 }, { 0x0700, 0xa388, 0x0000 }, { 0x8700, 0xa38b, 0x2000 }, { 0x0700, 0xa38a, 0x0000 }, { 0x0700, 0xa38c, 0x0000 }, { 0x8700, 0xa3ad, 0x6000 }, { 0x8700, 0xa39d, 0x5000 }, { 0x8700, 0xa395, 0x4000 }, { 0x8700, 0xa391, 0x3000 }, { 0x8700, 0xa38f, 0x2000 }, { 0x0700, 0xa38e, 0x0000 }, { 0x0700, 0xa390, 0x0000 }, { 0x8700, 0xa393, 0x2000 }, { 0x0700, 0xa392, 0x0000 }, { 0x0700, 0xa394, 0x0000 }, { 0x8700, 0xa399, 0x3000 }, { 0x8700, 0xa397, 0x2000 }, { 0x0700, 0xa396, 0x0000 }, { 0x0700, 0xa398, 0x0000 }, { 0x8700, 0xa39b, 0x2000 }, { 0x0700, 0xa39a, 0x0000 }, { 0x0700, 0xa39c, 0x0000 }, { 0x8700, 0xa3a5, 0x4000 }, { 0x8700, 0xa3a1, 0x3000 }, { 0x8700, 0xa39f, 0x2000 }, { 0x0700, 0xa39e, 0x0000 }, { 0x0700, 0xa3a0, 0x0000 }, { 0x8700, 0xa3a3, 0x2000 }, { 0x0700, 0xa3a2, 0x0000 }, { 0x0700, 0xa3a4, 0x0000 }, { 0x8700, 0xa3a9, 0x3000 }, { 0x8700, 0xa3a7, 0x2000 }, { 0x0700, 0xa3a6, 0x0000 }, { 0x0700, 0xa3a8, 0x0000 }, { 0x8700, 0xa3ab, 0x2000 }, { 0x0700, 0xa3aa, 0x0000 }, { 0x0700, 0xa3ac, 0x0000 }, { 0x8700, 0xa3bd, 0x5000 }, { 0x8700, 0xa3b5, 0x4000 }, { 0x8700, 0xa3b1, 0x3000 }, { 0x8700, 0xa3af, 0x2000 }, { 0x0700, 0xa3ae, 0x0000 }, { 0x0700, 0xa3b0, 0x0000 }, { 0x8700, 0xa3b3, 0x2000 }, { 0x0700, 0xa3b2, 0x0000 }, { 0x0700, 0xa3b4, 0x0000 }, { 0x8700, 0xa3b9, 0x3000 }, { 0x8700, 0xa3b7, 0x2000 }, { 0x0700, 0xa3b6, 0x0000 }, { 0x0700, 0xa3b8, 0x0000 }, { 0x8700, 0xa3bb, 0x2000 }, { 0x0700, 0xa3ba, 0x0000 }, { 0x0700, 0xa3bc, 0x0000 }, { 0x8700, 0xa3c5, 0x4000 }, { 0x8700, 0xa3c1, 0x3000 }, { 0x8700, 0xa3bf, 0x2000 }, { 0x0700, 0xa3be, 0x0000 }, { 0x0700, 0xa3c0, 0x0000 }, { 0x8700, 0xa3c3, 0x2000 }, { 0x0700, 0xa3c2, 0x0000 }, { 0x0700, 0xa3c4, 0x0000 }, { 0x8700, 0xa3c9, 0x3000 }, { 0x8700, 0xa3c7, 0x2000 }, { 0x0700, 0xa3c6, 0x0000 }, { 0x0700, 0xa3c8, 0x0000 }, { 0x8700, 0xa3cb, 0x2000 }, { 0x0700, 0xa3ca, 0x0000 }, { 0x0700, 0xa3cc, 0x0000 }, { 0x8700, 0xa40d, 0x7000 }, { 0x8700, 0xa3ed, 0x6000 }, { 0x8700, 0xa3dd, 0x5000 }, { 0x8700, 0xa3d5, 0x4000 }, { 0x8700, 0xa3d1, 0x3000 }, { 0x8700, 0xa3cf, 0x2000 }, { 0x0700, 0xa3ce, 0x0000 }, { 0x0700, 0xa3d0, 0x0000 }, { 0x8700, 0xa3d3, 0x2000 }, { 0x0700, 0xa3d2, 0x0000 }, { 0x0700, 0xa3d4, 0x0000 }, { 0x8700, 0xa3d9, 0x3000 }, { 0x8700, 0xa3d7, 0x2000 }, { 0x0700, 0xa3d6, 0x0000 }, { 0x0700, 0xa3d8, 0x0000 }, { 0x8700, 0xa3db, 0x2000 }, { 0x0700, 0xa3da, 0x0000 }, { 0x0700, 0xa3dc, 0x0000 }, { 0x8700, 0xa3e5, 0x4000 }, { 0x8700, 0xa3e1, 0x3000 }, { 0x8700, 0xa3df, 0x2000 }, { 0x0700, 0xa3de, 0x0000 }, { 0x0700, 0xa3e0, 0x0000 }, { 0x8700, 0xa3e3, 0x2000 }, { 0x0700, 0xa3e2, 0x0000 }, { 0x0700, 0xa3e4, 0x0000 }, { 0x8700, 0xa3e9, 0x3000 }, { 0x8700, 0xa3e7, 0x2000 }, { 0x0700, 0xa3e6, 0x0000 }, { 0x0700, 0xa3e8, 0x0000 }, { 0x8700, 0xa3eb, 0x2000 }, { 0x0700, 0xa3ea, 0x0000 }, { 0x0700, 0xa3ec, 0x0000 }, { 0x8700, 0xa3fd, 0x5000 }, { 0x8700, 0xa3f5, 0x4000 }, { 0x8700, 0xa3f1, 0x3000 }, { 0x8700, 0xa3ef, 0x2000 }, { 0x0700, 0xa3ee, 0x0000 }, { 0x0700, 0xa3f0, 0x0000 }, { 0x8700, 0xa3f3, 0x2000 }, { 0x0700, 0xa3f2, 0x0000 }, { 0x0700, 0xa3f4, 0x0000 }, { 0x8700, 0xa3f9, 0x3000 }, { 0x8700, 0xa3f7, 0x2000 }, { 0x0700, 0xa3f6, 0x0000 }, { 0x0700, 0xa3f8, 0x0000 }, { 0x8700, 0xa3fb, 0x2000 }, { 0x0700, 0xa3fa, 0x0000 }, { 0x0700, 0xa3fc, 0x0000 }, { 0x8700, 0xa405, 0x4000 }, { 0x8700, 0xa401, 0x3000 }, { 0x8700, 0xa3ff, 0x2000 }, { 0x0700, 0xa3fe, 0x0000 }, { 0x0700, 0xa400, 0x0000 }, { 0x8700, 0xa403, 0x2000 }, { 0x0700, 0xa402, 0x0000 }, { 0x0700, 0xa404, 0x0000 }, { 0x8700, 0xa409, 0x3000 }, { 0x8700, 0xa407, 0x2000 }, { 0x0700, 0xa406, 0x0000 }, { 0x0700, 0xa408, 0x0000 }, { 0x8700, 0xa40b, 0x2000 }, { 0x0700, 0xa40a, 0x0000 }, { 0x0700, 0xa40c, 0x0000 }, { 0x8700, 0xa42d, 0x6000 }, { 0x8700, 0xa41d, 0x5000 }, { 0x8700, 0xa415, 0x4000 }, { 0x8700, 0xa411, 0x3000 }, { 0x8700, 0xa40f, 0x2000 }, { 0x0700, 0xa40e, 0x0000 }, { 0x0700, 0xa410, 0x0000 }, { 0x8700, 0xa413, 0x2000 }, { 0x0700, 0xa412, 0x0000 }, { 0x0700, 0xa414, 0x0000 }, { 0x8700, 0xa419, 0x3000 }, { 0x8700, 0xa417, 0x2000 }, { 0x0700, 0xa416, 0x0000 }, { 0x0700, 0xa418, 0x0000 }, { 0x8700, 0xa41b, 0x2000 }, { 0x0700, 0xa41a, 0x0000 }, { 0x0700, 0xa41c, 0x0000 }, { 0x8700, 0xa425, 0x4000 }, { 0x8700, 0xa421, 0x3000 }, { 0x8700, 0xa41f, 0x2000 }, { 0x0700, 0xa41e, 0x0000 }, { 0x0700, 0xa420, 0x0000 }, { 0x8700, 0xa423, 0x2000 }, { 0x0700, 0xa422, 0x0000 }, { 0x0700, 0xa424, 0x0000 }, { 0x8700, 0xa429, 0x3000 }, { 0x8700, 0xa427, 0x2000 }, { 0x0700, 0xa426, 0x0000 }, { 0x0700, 0xa428, 0x0000 }, { 0x8700, 0xa42b, 0x2000 }, { 0x0700, 0xa42a, 0x0000 }, { 0x0700, 0xa42c, 0x0000 }, { 0x8700, 0xa43d, 0x5000 }, { 0x8700, 0xa435, 0x4000 }, { 0x8700, 0xa431, 0x3000 }, { 0x8700, 0xa42f, 0x2000 }, { 0x0700, 0xa42e, 0x0000 }, { 0x0700, 0xa430, 0x0000 }, { 0x8700, 0xa433, 0x2000 }, { 0x0700, 0xa432, 0x0000 }, { 0x0700, 0xa434, 0x0000 }, { 0x8700, 0xa439, 0x3000 }, { 0x8700, 0xa437, 0x2000 }, { 0x0700, 0xa436, 0x0000 }, { 0x0700, 0xa438, 0x0000 }, { 0x8700, 0xa43b, 0x2000 }, { 0x0700, 0xa43a, 0x0000 }, { 0x0700, 0xa43c, 0x0000 }, { 0x8700, 0xa445, 0x4000 }, { 0x8700, 0xa441, 0x3000 }, { 0x8700, 0xa43f, 0x2000 }, { 0x0700, 0xa43e, 0x0000 }, { 0x0700, 0xa440, 0x0000 }, { 0x8700, 0xa443, 0x2000 }, { 0x0700, 0xa442, 0x0000 }, { 0x0700, 0xa444, 0x0000 }, { 0x8700, 0xa449, 0x3000 }, { 0x8700, 0xa447, 0x2000 }, { 0x0700, 0xa446, 0x0000 }, { 0x0700, 0xa448, 0x0000 }, { 0x8700, 0xa44b, 0x2000 }, { 0x0700, 0xa44a, 0x0000 }, { 0x0700, 0xa44c, 0x0000 }, { 0x8300, 0xf8ff, 0x8000 }, { 0x9a00, 0xa490, 0x7000 }, { 0x8700, 0xa46d, 0x6000 }, { 0x8700, 0xa45d, 0x5000 }, { 0x8700, 0xa455, 0x4000 }, { 0x8700, 0xa451, 0x3000 }, { 0x8700, 0xa44f, 0x2000 }, { 0x0700, 0xa44e, 0x0000 }, { 0x0700, 0xa450, 0x0000 }, { 0x8700, 0xa453, 0x2000 }, { 0x0700, 0xa452, 0x0000 }, { 0x0700, 0xa454, 0x0000 }, { 0x8700, 0xa459, 0x3000 }, { 0x8700, 0xa457, 0x2000 }, { 0x0700, 0xa456, 0x0000 }, { 0x0700, 0xa458, 0x0000 }, { 0x8700, 0xa45b, 0x2000 }, { 0x0700, 0xa45a, 0x0000 }, { 0x0700, 0xa45c, 0x0000 }, { 0x8700, 0xa465, 0x4000 }, { 0x8700, 0xa461, 0x3000 }, { 0x8700, 0xa45f, 0x2000 }, { 0x0700, 0xa45e, 0x0000 }, { 0x0700, 0xa460, 0x0000 }, { 0x8700, 0xa463, 0x2000 }, { 0x0700, 0xa462, 0x0000 }, { 0x0700, 0xa464, 0x0000 }, { 0x8700, 0xa469, 0x3000 }, { 0x8700, 0xa467, 0x2000 }, { 0x0700, 0xa466, 0x0000 }, { 0x0700, 0xa468, 0x0000 }, { 0x8700, 0xa46b, 0x2000 }, { 0x0700, 0xa46a, 0x0000 }, { 0x0700, 0xa46c, 0x0000 }, { 0x8700, 0xa47d, 0x5000 }, { 0x8700, 0xa475, 0x4000 }, { 0x8700, 0xa471, 0x3000 }, { 0x8700, 0xa46f, 0x2000 }, { 0x0700, 0xa46e, 0x0000 }, { 0x0700, 0xa470, 0x0000 }, { 0x8700, 0xa473, 0x2000 }, { 0x0700, 0xa472, 0x0000 }, { 0x0700, 0xa474, 0x0000 }, { 0x8700, 0xa479, 0x3000 }, { 0x8700, 0xa477, 0x2000 }, { 0x0700, 0xa476, 0x0000 }, { 0x0700, 0xa478, 0x0000 }, { 0x8700, 0xa47b, 0x2000 }, { 0x0700, 0xa47a, 0x0000 }, { 0x0700, 0xa47c, 0x0000 }, { 0x8700, 0xa485, 0x4000 }, { 0x8700, 0xa481, 0x3000 }, { 0x8700, 0xa47f, 0x2000 }, { 0x0700, 0xa47e, 0x0000 }, { 0x0700, 0xa480, 0x0000 }, { 0x8700, 0xa483, 0x2000 }, { 0x0700, 0xa482, 0x0000 }, { 0x0700, 0xa484, 0x0000 }, { 0x8700, 0xa489, 0x3000 }, { 0x8700, 0xa487, 0x2000 }, { 0x0700, 0xa486, 0x0000 }, { 0x0700, 0xa488, 0x0000 }, { 0x8700, 0xa48b, 0x2000 }, { 0x0700, 0xa48a, 0x0000 }, { 0x0700, 0xa48c, 0x0000 }, { 0x9a00, 0xa4b0, 0x6000 }, { 0x9a00, 0xa4a0, 0x5000 }, { 0x9a00, 0xa498, 0x4000 }, { 0x9a00, 0xa494, 0x3000 }, { 0x9a00, 0xa492, 0x2000 }, { 0x1a00, 0xa491, 0x0000 }, { 0x1a00, 0xa493, 0x0000 }, { 0x9a00, 0xa496, 0x2000 }, { 0x1a00, 0xa495, 0x0000 }, { 0x1a00, 0xa497, 0x0000 }, { 0x9a00, 0xa49c, 0x3000 }, { 0x9a00, 0xa49a, 0x2000 }, { 0x1a00, 0xa499, 0x0000 }, { 0x1a00, 0xa49b, 0x0000 }, { 0x9a00, 0xa49e, 0x2000 }, { 0x1a00, 0xa49d, 0x0000 }, { 0x1a00, 0xa49f, 0x0000 }, { 0x9a00, 0xa4a8, 0x4000 }, { 0x9a00, 0xa4a4, 0x3000 }, { 0x9a00, 0xa4a2, 0x2000 }, { 0x1a00, 0xa4a1, 0x0000 }, { 0x1a00, 0xa4a3, 0x0000 }, { 0x9a00, 0xa4a6, 0x2000 }, { 0x1a00, 0xa4a5, 0x0000 }, { 0x1a00, 0xa4a7, 0x0000 }, { 0x9a00, 0xa4ac, 0x3000 }, { 0x9a00, 0xa4aa, 0x2000 }, { 0x1a00, 0xa4a9, 0x0000 }, { 0x1a00, 0xa4ab, 0x0000 }, { 0x9a00, 0xa4ae, 0x2000 }, { 0x1a00, 0xa4ad, 0x0000 }, { 0x1a00, 0xa4af, 0x0000 }, { 0x9a00, 0xa4c0, 0x5000 }, { 0x9a00, 0xa4b8, 0x4000 }, { 0x9a00, 0xa4b4, 0x3000 }, { 0x9a00, 0xa4b2, 0x2000 }, { 0x1a00, 0xa4b1, 0x0000 }, { 0x1a00, 0xa4b3, 0x0000 }, { 0x9a00, 0xa4b6, 0x2000 }, { 0x1a00, 0xa4b5, 0x0000 }, { 0x1a00, 0xa4b7, 0x0000 }, { 0x9a00, 0xa4bc, 0x3000 }, { 0x9a00, 0xa4ba, 0x2000 }, { 0x1a00, 0xa4b9, 0x0000 }, { 0x1a00, 0xa4bb, 0x0000 }, { 0x9a00, 0xa4be, 0x2000 }, { 0x1a00, 0xa4bd, 0x0000 }, { 0x1a00, 0xa4bf, 0x0000 }, { 0x8700, 0xd7a3, 0x4000 }, { 0x9a00, 0xa4c4, 0x3000 }, { 0x9a00, 0xa4c2, 0x2000 }, { 0x1a00, 0xa4c1, 0x0000 }, { 0x1a00, 0xa4c3, 0x0000 }, { 0x9a00, 0xa4c6, 0x2000 }, { 0x1a00, 0xa4c5, 0x0000 }, { 0x0700, 0xac00, 0x0000 }, { 0x8400, 0xdbff, 0x3000 }, { 0x8400, 0xdb7f, 0x2000 }, { 0x0400, 0xd800, 0x0000 }, { 0x0400, 0xdb80, 0x0000 }, { 0x8400, 0xdfff, 0x2000 }, { 0x0400, 0xdc00, 0x0000 }, { 0x0300, 0xe000, 0x0000 }, { 0x8700, 0xf93f, 0x7000 }, { 0x8700, 0xf91f, 0x6000 }, { 0x8700, 0xf90f, 0x5000 }, { 0x8700, 0xf907, 0x4000 }, { 0x8700, 0xf903, 0x3000 }, { 0x8700, 0xf901, 0x2000 }, { 0x0700, 0xf900, 0x0000 }, { 0x0700, 0xf902, 0x0000 }, { 0x8700, 0xf905, 0x2000 }, { 0x0700, 0xf904, 0x0000 }, { 0x0700, 0xf906, 0x0000 }, { 0x8700, 0xf90b, 0x3000 }, { 0x8700, 0xf909, 0x2000 }, { 0x0700, 0xf908, 0x0000 }, { 0x0700, 0xf90a, 0x0000 }, { 0x8700, 0xf90d, 0x2000 }, { 0x0700, 0xf90c, 0x0000 }, { 0x0700, 0xf90e, 0x0000 }, { 0x8700, 0xf917, 0x4000 }, { 0x8700, 0xf913, 0x3000 }, { 0x8700, 0xf911, 0x2000 }, { 0x0700, 0xf910, 0x0000 }, { 0x0700, 0xf912, 0x0000 }, { 0x8700, 0xf915, 0x2000 }, { 0x0700, 0xf914, 0x0000 }, { 0x0700, 0xf916, 0x0000 }, { 0x8700, 0xf91b, 0x3000 }, { 0x8700, 0xf919, 0x2000 }, { 0x0700, 0xf918, 0x0000 }, { 0x0700, 0xf91a, 0x0000 }, { 0x8700, 0xf91d, 0x2000 }, { 0x0700, 0xf91c, 0x0000 }, { 0x0700, 0xf91e, 0x0000 }, { 0x8700, 0xf92f, 0x5000 }, { 0x8700, 0xf927, 0x4000 }, { 0x8700, 0xf923, 0x3000 }, { 0x8700, 0xf921, 0x2000 }, { 0x0700, 0xf920, 0x0000 }, { 0x0700, 0xf922, 0x0000 }, { 0x8700, 0xf925, 0x2000 }, { 0x0700, 0xf924, 0x0000 }, { 0x0700, 0xf926, 0x0000 }, { 0x8700, 0xf92b, 0x3000 }, { 0x8700, 0xf929, 0x2000 }, { 0x0700, 0xf928, 0x0000 }, { 0x0700, 0xf92a, 0x0000 }, { 0x8700, 0xf92d, 0x2000 }, { 0x0700, 0xf92c, 0x0000 }, { 0x0700, 0xf92e, 0x0000 }, { 0x8700, 0xf937, 0x4000 }, { 0x8700, 0xf933, 0x3000 }, { 0x8700, 0xf931, 0x2000 }, { 0x0700, 0xf930, 0x0000 }, { 0x0700, 0xf932, 0x0000 }, { 0x8700, 0xf935, 0x2000 }, { 0x0700, 0xf934, 0x0000 }, { 0x0700, 0xf936, 0x0000 }, { 0x8700, 0xf93b, 0x3000 }, { 0x8700, 0xf939, 0x2000 }, { 0x0700, 0xf938, 0x0000 }, { 0x0700, 0xf93a, 0x0000 }, { 0x8700, 0xf93d, 0x2000 }, { 0x0700, 0xf93c, 0x0000 }, { 0x0700, 0xf93e, 0x0000 }, { 0x8700, 0xf95f, 0x6000 }, { 0x8700, 0xf94f, 0x5000 }, { 0x8700, 0xf947, 0x4000 }, { 0x8700, 0xf943, 0x3000 }, { 0x8700, 0xf941, 0x2000 }, { 0x0700, 0xf940, 0x0000 }, { 0x0700, 0xf942, 0x0000 }, { 0x8700, 0xf945, 0x2000 }, { 0x0700, 0xf944, 0x0000 }, { 0x0700, 0xf946, 0x0000 }, { 0x8700, 0xf94b, 0x3000 }, { 0x8700, 0xf949, 0x2000 }, { 0x0700, 0xf948, 0x0000 }, { 0x0700, 0xf94a, 0x0000 }, { 0x8700, 0xf94d, 0x2000 }, { 0x0700, 0xf94c, 0x0000 }, { 0x0700, 0xf94e, 0x0000 }, { 0x8700, 0xf957, 0x4000 }, { 0x8700, 0xf953, 0x3000 }, { 0x8700, 0xf951, 0x2000 }, { 0x0700, 0xf950, 0x0000 }, { 0x0700, 0xf952, 0x0000 }, { 0x8700, 0xf955, 0x2000 }, { 0x0700, 0xf954, 0x0000 }, { 0x0700, 0xf956, 0x0000 }, { 0x8700, 0xf95b, 0x3000 }, { 0x8700, 0xf959, 0x2000 }, { 0x0700, 0xf958, 0x0000 }, { 0x0700, 0xf95a, 0x0000 }, { 0x8700, 0xf95d, 0x2000 }, { 0x0700, 0xf95c, 0x0000 }, { 0x0700, 0xf95e, 0x0000 }, { 0x8700, 0xf96f, 0x5000 }, { 0x8700, 0xf967, 0x4000 }, { 0x8700, 0xf963, 0x3000 }, { 0x8700, 0xf961, 0x2000 }, { 0x0700, 0xf960, 0x0000 }, { 0x0700, 0xf962, 0x0000 }, { 0x8700, 0xf965, 0x2000 }, { 0x0700, 0xf964, 0x0000 }, { 0x0700, 0xf966, 0x0000 }, { 0x8700, 0xf96b, 0x3000 }, { 0x8700, 0xf969, 0x2000 }, { 0x0700, 0xf968, 0x0000 }, { 0x0700, 0xf96a, 0x0000 }, { 0x8700, 0xf96d, 0x2000 }, { 0x0700, 0xf96c, 0x0000 }, { 0x0700, 0xf96e, 0x0000 }, { 0x8700, 0xf977, 0x4000 }, { 0x8700, 0xf973, 0x3000 }, { 0x8700, 0xf971, 0x2000 }, { 0x0700, 0xf970, 0x0000 }, { 0x0700, 0xf972, 0x0000 }, { 0x8700, 0xf975, 0x2000 }, { 0x0700, 0xf974, 0x0000 }, { 0x0700, 0xf976, 0x0000 }, { 0x8700, 0xf97b, 0x3000 }, { 0x8700, 0xf979, 0x2000 }, { 0x0700, 0xf978, 0x0000 }, { 0x0700, 0xf97a, 0x0000 }, { 0x8700, 0xf97d, 0x2000 }, { 0x0700, 0xf97c, 0x0000 }, { 0x0700, 0xf97e, 0x0000 }, { 0x8700, 0xfb27, 0x9000 }, { 0x8700, 0xf9ff, 0x8000 }, { 0x8700, 0xf9bf, 0x7000 }, { 0x8700, 0xf99f, 0x6000 }, { 0x8700, 0xf98f, 0x5000 }, { 0x8700, 0xf987, 0x4000 }, { 0x8700, 0xf983, 0x3000 }, { 0x8700, 0xf981, 0x2000 }, { 0x0700, 0xf980, 0x0000 }, { 0x0700, 0xf982, 0x0000 }, { 0x8700, 0xf985, 0x2000 }, { 0x0700, 0xf984, 0x0000 }, { 0x0700, 0xf986, 0x0000 }, { 0x8700, 0xf98b, 0x3000 }, { 0x8700, 0xf989, 0x2000 }, { 0x0700, 0xf988, 0x0000 }, { 0x0700, 0xf98a, 0x0000 }, { 0x8700, 0xf98d, 0x2000 }, { 0x0700, 0xf98c, 0x0000 }, { 0x0700, 0xf98e, 0x0000 }, { 0x8700, 0xf997, 0x4000 }, { 0x8700, 0xf993, 0x3000 }, { 0x8700, 0xf991, 0x2000 }, { 0x0700, 0xf990, 0x0000 }, { 0x0700, 0xf992, 0x0000 }, { 0x8700, 0xf995, 0x2000 }, { 0x0700, 0xf994, 0x0000 }, { 0x0700, 0xf996, 0x0000 }, { 0x8700, 0xf99b, 0x3000 }, { 0x8700, 0xf999, 0x2000 }, { 0x0700, 0xf998, 0x0000 }, { 0x0700, 0xf99a, 0x0000 }, { 0x8700, 0xf99d, 0x2000 }, { 0x0700, 0xf99c, 0x0000 }, { 0x0700, 0xf99e, 0x0000 }, { 0x8700, 0xf9af, 0x5000 }, { 0x8700, 0xf9a7, 0x4000 }, { 0x8700, 0xf9a3, 0x3000 }, { 0x8700, 0xf9a1, 0x2000 }, { 0x0700, 0xf9a0, 0x0000 }, { 0x0700, 0xf9a2, 0x0000 }, { 0x8700, 0xf9a5, 0x2000 }, { 0x0700, 0xf9a4, 0x0000 }, { 0x0700, 0xf9a6, 0x0000 }, { 0x8700, 0xf9ab, 0x3000 }, { 0x8700, 0xf9a9, 0x2000 }, { 0x0700, 0xf9a8, 0x0000 }, { 0x0700, 0xf9aa, 0x0000 }, { 0x8700, 0xf9ad, 0x2000 }, { 0x0700, 0xf9ac, 0x0000 }, { 0x0700, 0xf9ae, 0x0000 }, { 0x8700, 0xf9b7, 0x4000 }, { 0x8700, 0xf9b3, 0x3000 }, { 0x8700, 0xf9b1, 0x2000 }, { 0x0700, 0xf9b0, 0x0000 }, { 0x0700, 0xf9b2, 0x0000 }, { 0x8700, 0xf9b5, 0x2000 }, { 0x0700, 0xf9b4, 0x0000 }, { 0x0700, 0xf9b6, 0x0000 }, { 0x8700, 0xf9bb, 0x3000 }, { 0x8700, 0xf9b9, 0x2000 }, { 0x0700, 0xf9b8, 0x0000 }, { 0x0700, 0xf9ba, 0x0000 }, { 0x8700, 0xf9bd, 0x2000 }, { 0x0700, 0xf9bc, 0x0000 }, { 0x0700, 0xf9be, 0x0000 }, { 0x8700, 0xf9df, 0x6000 }, { 0x8700, 0xf9cf, 0x5000 }, { 0x8700, 0xf9c7, 0x4000 }, { 0x8700, 0xf9c3, 0x3000 }, { 0x8700, 0xf9c1, 0x2000 }, { 0x0700, 0xf9c0, 0x0000 }, { 0x0700, 0xf9c2, 0x0000 }, { 0x8700, 0xf9c5, 0x2000 }, { 0x0700, 0xf9c4, 0x0000 }, { 0x0700, 0xf9c6, 0x0000 }, { 0x8700, 0xf9cb, 0x3000 }, { 0x8700, 0xf9c9, 0x2000 }, { 0x0700, 0xf9c8, 0x0000 }, { 0x0700, 0xf9ca, 0x0000 }, { 0x8700, 0xf9cd, 0x2000 }, { 0x0700, 0xf9cc, 0x0000 }, { 0x0700, 0xf9ce, 0x0000 }, { 0x8700, 0xf9d7, 0x4000 }, { 0x8700, 0xf9d3, 0x3000 }, { 0x8700, 0xf9d1, 0x2000 }, { 0x0700, 0xf9d0, 0x0000 }, { 0x0700, 0xf9d2, 0x0000 }, { 0x8700, 0xf9d5, 0x2000 }, { 0x0700, 0xf9d4, 0x0000 }, { 0x0700, 0xf9d6, 0x0000 }, { 0x8700, 0xf9db, 0x3000 }, { 0x8700, 0xf9d9, 0x2000 }, { 0x0700, 0xf9d8, 0x0000 }, { 0x0700, 0xf9da, 0x0000 }, { 0x8700, 0xf9dd, 0x2000 }, { 0x0700, 0xf9dc, 0x0000 }, { 0x0700, 0xf9de, 0x0000 }, { 0x8700, 0xf9ef, 0x5000 }, { 0x8700, 0xf9e7, 0x4000 }, { 0x8700, 0xf9e3, 0x3000 }, { 0x8700, 0xf9e1, 0x2000 }, { 0x0700, 0xf9e0, 0x0000 }, { 0x0700, 0xf9e2, 0x0000 }, { 0x8700, 0xf9e5, 0x2000 }, { 0x0700, 0xf9e4, 0x0000 }, { 0x0700, 0xf9e6, 0x0000 }, { 0x8700, 0xf9eb, 0x3000 }, { 0x8700, 0xf9e9, 0x2000 }, { 0x0700, 0xf9e8, 0x0000 }, { 0x0700, 0xf9ea, 0x0000 }, { 0x8700, 0xf9ed, 0x2000 }, { 0x0700, 0xf9ec, 0x0000 }, { 0x0700, 0xf9ee, 0x0000 }, { 0x8700, 0xf9f7, 0x4000 }, { 0x8700, 0xf9f3, 0x3000 }, { 0x8700, 0xf9f1, 0x2000 }, { 0x0700, 0xf9f0, 0x0000 }, { 0x0700, 0xf9f2, 0x0000 }, { 0x8700, 0xf9f5, 0x2000 }, { 0x0700, 0xf9f4, 0x0000 }, { 0x0700, 0xf9f6, 0x0000 }, { 0x8700, 0xf9fb, 0x3000 }, { 0x8700, 0xf9f9, 0x2000 }, { 0x0700, 0xf9f8, 0x0000 }, { 0x0700, 0xf9fa, 0x0000 }, { 0x8700, 0xf9fd, 0x2000 }, { 0x0700, 0xf9fc, 0x0000 }, { 0x0700, 0xf9fe, 0x0000 }, { 0x8700, 0xfa41, 0x7000 }, { 0x8700, 0xfa1f, 0x6000 }, { 0x8700, 0xfa0f, 0x5000 }, { 0x8700, 0xfa07, 0x4000 }, { 0x8700, 0xfa03, 0x3000 }, { 0x8700, 0xfa01, 0x2000 }, { 0x0700, 0xfa00, 0x0000 }, { 0x0700, 0xfa02, 0x0000 }, { 0x8700, 0xfa05, 0x2000 }, { 0x0700, 0xfa04, 0x0000 }, { 0x0700, 0xfa06, 0x0000 }, { 0x8700, 0xfa0b, 0x3000 }, { 0x8700, 0xfa09, 0x2000 }, { 0x0700, 0xfa08, 0x0000 }, { 0x0700, 0xfa0a, 0x0000 }, { 0x8700, 0xfa0d, 0x2000 }, { 0x0700, 0xfa0c, 0x0000 }, { 0x0700, 0xfa0e, 0x0000 }, { 0x8700, 0xfa17, 0x4000 }, { 0x8700, 0xfa13, 0x3000 }, { 0x8700, 0xfa11, 0x2000 }, { 0x0700, 0xfa10, 0x0000 }, { 0x0700, 0xfa12, 0x0000 }, { 0x8700, 0xfa15, 0x2000 }, { 0x0700, 0xfa14, 0x0000 }, { 0x0700, 0xfa16, 0x0000 }, { 0x8700, 0xfa1b, 0x3000 }, { 0x8700, 0xfa19, 0x2000 }, { 0x0700, 0xfa18, 0x0000 }, { 0x0700, 0xfa1a, 0x0000 }, { 0x8700, 0xfa1d, 0x2000 }, { 0x0700, 0xfa1c, 0x0000 }, { 0x0700, 0xfa1e, 0x0000 }, { 0x8700, 0xfa31, 0x5000 }, { 0x8700, 0xfa27, 0x4000 }, { 0x8700, 0xfa23, 0x3000 }, { 0x8700, 0xfa21, 0x2000 }, { 0x0700, 0xfa20, 0x0000 }, { 0x0700, 0xfa22, 0x0000 }, { 0x8700, 0xfa25, 0x2000 }, { 0x0700, 0xfa24, 0x0000 }, { 0x0700, 0xfa26, 0x0000 }, { 0x8700, 0xfa2b, 0x3000 }, { 0x8700, 0xfa29, 0x2000 }, { 0x0700, 0xfa28, 0x0000 }, { 0x0700, 0xfa2a, 0x0000 }, { 0x8700, 0xfa2d, 0x2000 }, { 0x0700, 0xfa2c, 0x0000 }, { 0x0700, 0xfa30, 0x0000 }, { 0x8700, 0xfa39, 0x4000 }, { 0x8700, 0xfa35, 0x3000 }, { 0x8700, 0xfa33, 0x2000 }, { 0x0700, 0xfa32, 0x0000 }, { 0x0700, 0xfa34, 0x0000 }, { 0x8700, 0xfa37, 0x2000 }, { 0x0700, 0xfa36, 0x0000 }, { 0x0700, 0xfa38, 0x0000 }, { 0x8700, 0xfa3d, 0x3000 }, { 0x8700, 0xfa3b, 0x2000 }, { 0x0700, 0xfa3a, 0x0000 }, { 0x0700, 0xfa3c, 0x0000 }, { 0x8700, 0xfa3f, 0x2000 }, { 0x0700, 0xfa3e, 0x0000 }, { 0x0700, 0xfa40, 0x0000 }, { 0x8700, 0xfa61, 0x6000 }, { 0x8700, 0xfa51, 0x5000 }, { 0x8700, 0xfa49, 0x4000 }, { 0x8700, 0xfa45, 0x3000 }, { 0x8700, 0xfa43, 0x2000 }, { 0x0700, 0xfa42, 0x0000 }, { 0x0700, 0xfa44, 0x0000 }, { 0x8700, 0xfa47, 0x2000 }, { 0x0700, 0xfa46, 0x0000 }, { 0x0700, 0xfa48, 0x0000 }, { 0x8700, 0xfa4d, 0x3000 }, { 0x8700, 0xfa4b, 0x2000 }, { 0x0700, 0xfa4a, 0x0000 }, { 0x0700, 0xfa4c, 0x0000 }, { 0x8700, 0xfa4f, 0x2000 }, { 0x0700, 0xfa4e, 0x0000 }, { 0x0700, 0xfa50, 0x0000 }, { 0x8700, 0xfa59, 0x4000 }, { 0x8700, 0xfa55, 0x3000 }, { 0x8700, 0xfa53, 0x2000 }, { 0x0700, 0xfa52, 0x0000 }, { 0x0700, 0xfa54, 0x0000 }, { 0x8700, 0xfa57, 0x2000 }, { 0x0700, 0xfa56, 0x0000 }, { 0x0700, 0xfa58, 0x0000 }, { 0x8700, 0xfa5d, 0x3000 }, { 0x8700, 0xfa5b, 0x2000 }, { 0x0700, 0xfa5a, 0x0000 }, { 0x0700, 0xfa5c, 0x0000 }, { 0x8700, 0xfa5f, 0x2000 }, { 0x0700, 0xfa5e, 0x0000 }, { 0x0700, 0xfa60, 0x0000 }, { 0x8500, 0xfb06, 0x5000 }, { 0x8700, 0xfa69, 0x4000 }, { 0x8700, 0xfa65, 0x3000 }, { 0x8700, 0xfa63, 0x2000 }, { 0x0700, 0xfa62, 0x0000 }, { 0x0700, 0xfa64, 0x0000 }, { 0x8700, 0xfa67, 0x2000 }, { 0x0700, 0xfa66, 0x0000 }, { 0x0700, 0xfa68, 0x0000 }, { 0x8500, 0xfb02, 0x3000 }, { 0x8500, 0xfb00, 0x2000 }, { 0x0700, 0xfa6a, 0x0000 }, { 0x0500, 0xfb01, 0x0000 }, { 0x8500, 0xfb04, 0x2000 }, { 0x0500, 0xfb03, 0x0000 }, { 0x0500, 0xfb05, 0x0000 }, { 0x8700, 0xfb1f, 0x4000 }, { 0x8500, 0xfb16, 0x3000 }, { 0x8500, 0xfb14, 0x2000 }, { 0x0500, 0xfb13, 0x0000 }, { 0x0500, 0xfb15, 0x0000 }, { 0x8700, 0xfb1d, 0x2000 }, { 0x0500, 0xfb17, 0x0000 }, { 0x0c00, 0xfb1e, 0x0000 }, { 0x8700, 0xfb23, 0x3000 }, { 0x8700, 0xfb21, 0x2000 }, { 0x0700, 0xfb20, 0x0000 }, { 0x0700, 0xfb22, 0x0000 }, { 0x8700, 0xfb25, 0x2000 }, { 0x0700, 0xfb24, 0x0000 }, { 0x0700, 0xfb26, 0x0000 }, { 0x8700, 0xfbac, 0x8000 }, { 0x8700, 0xfb6c, 0x7000 }, { 0x8700, 0xfb4c, 0x6000 }, { 0x8700, 0xfb38, 0x5000 }, { 0x8700, 0xfb2f, 0x4000 }, { 0x8700, 0xfb2b, 0x3000 }, { 0x9900, 0xfb29, 0x2000 }, { 0x0700, 0xfb28, 0x0000 }, { 0x0700, 0xfb2a, 0x0000 }, { 0x8700, 0xfb2d, 0x2000 }, { 0x0700, 0xfb2c, 0x0000 }, { 0x0700, 0xfb2e, 0x0000 }, { 0x8700, 0xfb33, 0x3000 }, { 0x8700, 0xfb31, 0x2000 }, { 0x0700, 0xfb30, 0x0000 }, { 0x0700, 0xfb32, 0x0000 }, { 0x8700, 0xfb35, 0x2000 }, { 0x0700, 0xfb34, 0x0000 }, { 0x0700, 0xfb36, 0x0000 }, { 0x8700, 0xfb43, 0x4000 }, { 0x8700, 0xfb3c, 0x3000 }, { 0x8700, 0xfb3a, 0x2000 }, { 0x0700, 0xfb39, 0x0000 }, { 0x0700, 0xfb3b, 0x0000 }, { 0x8700, 0xfb40, 0x2000 }, { 0x0700, 0xfb3e, 0x0000 }, { 0x0700, 0xfb41, 0x0000 }, { 0x8700, 0xfb48, 0x3000 }, { 0x8700, 0xfb46, 0x2000 }, { 0x0700, 0xfb44, 0x0000 }, { 0x0700, 0xfb47, 0x0000 }, { 0x8700, 0xfb4a, 0x2000 }, { 0x0700, 0xfb49, 0x0000 }, { 0x0700, 0xfb4b, 0x0000 }, { 0x8700, 0xfb5c, 0x5000 }, { 0x8700, 0xfb54, 0x4000 }, { 0x8700, 0xfb50, 0x3000 }, { 0x8700, 0xfb4e, 0x2000 }, { 0x0700, 0xfb4d, 0x0000 }, { 0x0700, 0xfb4f, 0x0000 }, { 0x8700, 0xfb52, 0x2000 }, { 0x0700, 0xfb51, 0x0000 }, { 0x0700, 0xfb53, 0x0000 }, { 0x8700, 0xfb58, 0x3000 }, { 0x8700, 0xfb56, 0x2000 }, { 0x0700, 0xfb55, 0x0000 }, { 0x0700, 0xfb57, 0x0000 }, { 0x8700, 0xfb5a, 0x2000 }, { 0x0700, 0xfb59, 0x0000 }, { 0x0700, 0xfb5b, 0x0000 }, { 0x8700, 0xfb64, 0x4000 }, { 0x8700, 0xfb60, 0x3000 }, { 0x8700, 0xfb5e, 0x2000 }, { 0x0700, 0xfb5d, 0x0000 }, { 0x0700, 0xfb5f, 0x0000 }, { 0x8700, 0xfb62, 0x2000 }, { 0x0700, 0xfb61, 0x0000 }, { 0x0700, 0xfb63, 0x0000 }, { 0x8700, 0xfb68, 0x3000 }, { 0x8700, 0xfb66, 0x2000 }, { 0x0700, 0xfb65, 0x0000 }, { 0x0700, 0xfb67, 0x0000 }, { 0x8700, 0xfb6a, 0x2000 }, { 0x0700, 0xfb69, 0x0000 }, { 0x0700, 0xfb6b, 0x0000 }, { 0x8700, 0xfb8c, 0x6000 }, { 0x8700, 0xfb7c, 0x5000 }, { 0x8700, 0xfb74, 0x4000 }, { 0x8700, 0xfb70, 0x3000 }, { 0x8700, 0xfb6e, 0x2000 }, { 0x0700, 0xfb6d, 0x0000 }, { 0x0700, 0xfb6f, 0x0000 }, { 0x8700, 0xfb72, 0x2000 }, { 0x0700, 0xfb71, 0x0000 }, { 0x0700, 0xfb73, 0x0000 }, { 0x8700, 0xfb78, 0x3000 }, { 0x8700, 0xfb76, 0x2000 }, { 0x0700, 0xfb75, 0x0000 }, { 0x0700, 0xfb77, 0x0000 }, { 0x8700, 0xfb7a, 0x2000 }, { 0x0700, 0xfb79, 0x0000 }, { 0x0700, 0xfb7b, 0x0000 }, { 0x8700, 0xfb84, 0x4000 }, { 0x8700, 0xfb80, 0x3000 }, { 0x8700, 0xfb7e, 0x2000 }, { 0x0700, 0xfb7d, 0x0000 }, { 0x0700, 0xfb7f, 0x0000 }, { 0x8700, 0xfb82, 0x2000 }, { 0x0700, 0xfb81, 0x0000 }, { 0x0700, 0xfb83, 0x0000 }, { 0x8700, 0xfb88, 0x3000 }, { 0x8700, 0xfb86, 0x2000 }, { 0x0700, 0xfb85, 0x0000 }, { 0x0700, 0xfb87, 0x0000 }, { 0x8700, 0xfb8a, 0x2000 }, { 0x0700, 0xfb89, 0x0000 }, { 0x0700, 0xfb8b, 0x0000 }, { 0x8700, 0xfb9c, 0x5000 }, { 0x8700, 0xfb94, 0x4000 }, { 0x8700, 0xfb90, 0x3000 }, { 0x8700, 0xfb8e, 0x2000 }, { 0x0700, 0xfb8d, 0x0000 }, { 0x0700, 0xfb8f, 0x0000 }, { 0x8700, 0xfb92, 0x2000 }, { 0x0700, 0xfb91, 0x0000 }, { 0x0700, 0xfb93, 0x0000 }, { 0x8700, 0xfb98, 0x3000 }, { 0x8700, 0xfb96, 0x2000 }, { 0x0700, 0xfb95, 0x0000 }, { 0x0700, 0xfb97, 0x0000 }, { 0x8700, 0xfb9a, 0x2000 }, { 0x0700, 0xfb99, 0x0000 }, { 0x0700, 0xfb9b, 0x0000 }, { 0x8700, 0xfba4, 0x4000 }, { 0x8700, 0xfba0, 0x3000 }, { 0x8700, 0xfb9e, 0x2000 }, { 0x0700, 0xfb9d, 0x0000 }, { 0x0700, 0xfb9f, 0x0000 }, { 0x8700, 0xfba2, 0x2000 }, { 0x0700, 0xfba1, 0x0000 }, { 0x0700, 0xfba3, 0x0000 }, { 0x8700, 0xfba8, 0x3000 }, { 0x8700, 0xfba6, 0x2000 }, { 0x0700, 0xfba5, 0x0000 }, { 0x0700, 0xfba7, 0x0000 }, { 0x8700, 0xfbaa, 0x2000 }, { 0x0700, 0xfba9, 0x0000 }, { 0x0700, 0xfbab, 0x0000 }, { 0x8700, 0xfc0d, 0x7000 }, { 0x8700, 0xfbed, 0x6000 }, { 0x8700, 0xfbdd, 0x5000 }, { 0x8700, 0xfbd5, 0x4000 }, { 0x8700, 0xfbb0, 0x3000 }, { 0x8700, 0xfbae, 0x2000 }, { 0x0700, 0xfbad, 0x0000 }, { 0x0700, 0xfbaf, 0x0000 }, { 0x8700, 0xfbd3, 0x2000 }, { 0x0700, 0xfbb1, 0x0000 }, { 0x0700, 0xfbd4, 0x0000 }, { 0x8700, 0xfbd9, 0x3000 }, { 0x8700, 0xfbd7, 0x2000 }, { 0x0700, 0xfbd6, 0x0000 }, { 0x0700, 0xfbd8, 0x0000 }, { 0x8700, 0xfbdb, 0x2000 }, { 0x0700, 0xfbda, 0x0000 }, { 0x0700, 0xfbdc, 0x0000 }, { 0x8700, 0xfbe5, 0x4000 }, { 0x8700, 0xfbe1, 0x3000 }, { 0x8700, 0xfbdf, 0x2000 }, { 0x0700, 0xfbde, 0x0000 }, { 0x0700, 0xfbe0, 0x0000 }, { 0x8700, 0xfbe3, 0x2000 }, { 0x0700, 0xfbe2, 0x0000 }, { 0x0700, 0xfbe4, 0x0000 }, { 0x8700, 0xfbe9, 0x3000 }, { 0x8700, 0xfbe7, 0x2000 }, { 0x0700, 0xfbe6, 0x0000 }, { 0x0700, 0xfbe8, 0x0000 }, { 0x8700, 0xfbeb, 0x2000 }, { 0x0700, 0xfbea, 0x0000 }, { 0x0700, 0xfbec, 0x0000 }, { 0x8700, 0xfbfd, 0x5000 }, { 0x8700, 0xfbf5, 0x4000 }, { 0x8700, 0xfbf1, 0x3000 }, { 0x8700, 0xfbef, 0x2000 }, { 0x0700, 0xfbee, 0x0000 }, { 0x0700, 0xfbf0, 0x0000 }, { 0x8700, 0xfbf3, 0x2000 }, { 0x0700, 0xfbf2, 0x0000 }, { 0x0700, 0xfbf4, 0x0000 }, { 0x8700, 0xfbf9, 0x3000 }, { 0x8700, 0xfbf7, 0x2000 }, { 0x0700, 0xfbf6, 0x0000 }, { 0x0700, 0xfbf8, 0x0000 }, { 0x8700, 0xfbfb, 0x2000 }, { 0x0700, 0xfbfa, 0x0000 }, { 0x0700, 0xfbfc, 0x0000 }, { 0x8700, 0xfc05, 0x4000 }, { 0x8700, 0xfc01, 0x3000 }, { 0x8700, 0xfbff, 0x2000 }, { 0x0700, 0xfbfe, 0x0000 }, { 0x0700, 0xfc00, 0x0000 }, { 0x8700, 0xfc03, 0x2000 }, { 0x0700, 0xfc02, 0x0000 }, { 0x0700, 0xfc04, 0x0000 }, { 0x8700, 0xfc09, 0x3000 }, { 0x8700, 0xfc07, 0x2000 }, { 0x0700, 0xfc06, 0x0000 }, { 0x0700, 0xfc08, 0x0000 }, { 0x8700, 0xfc0b, 0x2000 }, { 0x0700, 0xfc0a, 0x0000 }, { 0x0700, 0xfc0c, 0x0000 }, { 0x8700, 0xfc2d, 0x6000 }, { 0x8700, 0xfc1d, 0x5000 }, { 0x8700, 0xfc15, 0x4000 }, { 0x8700, 0xfc11, 0x3000 }, { 0x8700, 0xfc0f, 0x2000 }, { 0x0700, 0xfc0e, 0x0000 }, { 0x0700, 0xfc10, 0x0000 }, { 0x8700, 0xfc13, 0x2000 }, { 0x0700, 0xfc12, 0x0000 }, { 0x0700, 0xfc14, 0x0000 }, { 0x8700, 0xfc19, 0x3000 }, { 0x8700, 0xfc17, 0x2000 }, { 0x0700, 0xfc16, 0x0000 }, { 0x0700, 0xfc18, 0x0000 }, { 0x8700, 0xfc1b, 0x2000 }, { 0x0700, 0xfc1a, 0x0000 }, { 0x0700, 0xfc1c, 0x0000 }, { 0x8700, 0xfc25, 0x4000 }, { 0x8700, 0xfc21, 0x3000 }, { 0x8700, 0xfc1f, 0x2000 }, { 0x0700, 0xfc1e, 0x0000 }, { 0x0700, 0xfc20, 0x0000 }, { 0x8700, 0xfc23, 0x2000 }, { 0x0700, 0xfc22, 0x0000 }, { 0x0700, 0xfc24, 0x0000 }, { 0x8700, 0xfc29, 0x3000 }, { 0x8700, 0xfc27, 0x2000 }, { 0x0700, 0xfc26, 0x0000 }, { 0x0700, 0xfc28, 0x0000 }, { 0x8700, 0xfc2b, 0x2000 }, { 0x0700, 0xfc2a, 0x0000 }, { 0x0700, 0xfc2c, 0x0000 }, { 0x8700, 0xfc3d, 0x5000 }, { 0x8700, 0xfc35, 0x4000 }, { 0x8700, 0xfc31, 0x3000 }, { 0x8700, 0xfc2f, 0x2000 }, { 0x0700, 0xfc2e, 0x0000 }, { 0x0700, 0xfc30, 0x0000 }, { 0x8700, 0xfc33, 0x2000 }, { 0x0700, 0xfc32, 0x0000 }, { 0x0700, 0xfc34, 0x0000 }, { 0x8700, 0xfc39, 0x3000 }, { 0x8700, 0xfc37, 0x2000 }, { 0x0700, 0xfc36, 0x0000 }, { 0x0700, 0xfc38, 0x0000 }, { 0x8700, 0xfc3b, 0x2000 }, { 0x0700, 0xfc3a, 0x0000 }, { 0x0700, 0xfc3c, 0x0000 }, { 0x8700, 0xfc45, 0x4000 }, { 0x8700, 0xfc41, 0x3000 }, { 0x8700, 0xfc3f, 0x2000 }, { 0x0700, 0xfc3e, 0x0000 }, { 0x0700, 0xfc40, 0x0000 }, { 0x8700, 0xfc43, 0x2000 }, { 0x0700, 0xfc42, 0x0000 }, { 0x0700, 0xfc44, 0x0000 }, { 0x8700, 0xfc49, 0x3000 }, { 0x8700, 0xfc47, 0x2000 }, { 0x0700, 0xfc46, 0x0000 }, { 0x0700, 0xfc48, 0x0000 }, { 0x8700, 0xfc4b, 0x2000 }, { 0x0700, 0xfc4a, 0x0000 }, { 0x0700, 0xfc4c, 0x0000 }, { 0x8700, 0xfeac, 0xa000 }, { 0x8700, 0xfd5d, 0x9000 }, { 0x8700, 0xfccd, 0x8000 }, { 0x8700, 0xfc8d, 0x7000 }, { 0x8700, 0xfc6d, 0x6000 }, { 0x8700, 0xfc5d, 0x5000 }, { 0x8700, 0xfc55, 0x4000 }, { 0x8700, 0xfc51, 0x3000 }, { 0x8700, 0xfc4f, 0x2000 }, { 0x0700, 0xfc4e, 0x0000 }, { 0x0700, 0xfc50, 0x0000 }, { 0x8700, 0xfc53, 0x2000 }, { 0x0700, 0xfc52, 0x0000 }, { 0x0700, 0xfc54, 0x0000 }, { 0x8700, 0xfc59, 0x3000 }, { 0x8700, 0xfc57, 0x2000 }, { 0x0700, 0xfc56, 0x0000 }, { 0x0700, 0xfc58, 0x0000 }, { 0x8700, 0xfc5b, 0x2000 }, { 0x0700, 0xfc5a, 0x0000 }, { 0x0700, 0xfc5c, 0x0000 }, { 0x8700, 0xfc65, 0x4000 }, { 0x8700, 0xfc61, 0x3000 }, { 0x8700, 0xfc5f, 0x2000 }, { 0x0700, 0xfc5e, 0x0000 }, { 0x0700, 0xfc60, 0x0000 }, { 0x8700, 0xfc63, 0x2000 }, { 0x0700, 0xfc62, 0x0000 }, { 0x0700, 0xfc64, 0x0000 }, { 0x8700, 0xfc69, 0x3000 }, { 0x8700, 0xfc67, 0x2000 }, { 0x0700, 0xfc66, 0x0000 }, { 0x0700, 0xfc68, 0x0000 }, { 0x8700, 0xfc6b, 0x2000 }, { 0x0700, 0xfc6a, 0x0000 }, { 0x0700, 0xfc6c, 0x0000 }, { 0x8700, 0xfc7d, 0x5000 }, { 0x8700, 0xfc75, 0x4000 }, { 0x8700, 0xfc71, 0x3000 }, { 0x8700, 0xfc6f, 0x2000 }, { 0x0700, 0xfc6e, 0x0000 }, { 0x0700, 0xfc70, 0x0000 }, { 0x8700, 0xfc73, 0x2000 }, { 0x0700, 0xfc72, 0x0000 }, { 0x0700, 0xfc74, 0x0000 }, { 0x8700, 0xfc79, 0x3000 }, { 0x8700, 0xfc77, 0x2000 }, { 0x0700, 0xfc76, 0x0000 }, { 0x0700, 0xfc78, 0x0000 }, { 0x8700, 0xfc7b, 0x2000 }, { 0x0700, 0xfc7a, 0x0000 }, { 0x0700, 0xfc7c, 0x0000 }, { 0x8700, 0xfc85, 0x4000 }, { 0x8700, 0xfc81, 0x3000 }, { 0x8700, 0xfc7f, 0x2000 }, { 0x0700, 0xfc7e, 0x0000 }, { 0x0700, 0xfc80, 0x0000 }, { 0x8700, 0xfc83, 0x2000 }, { 0x0700, 0xfc82, 0x0000 }, { 0x0700, 0xfc84, 0x0000 }, { 0x8700, 0xfc89, 0x3000 }, { 0x8700, 0xfc87, 0x2000 }, { 0x0700, 0xfc86, 0x0000 }, { 0x0700, 0xfc88, 0x0000 }, { 0x8700, 0xfc8b, 0x2000 }, { 0x0700, 0xfc8a, 0x0000 }, { 0x0700, 0xfc8c, 0x0000 }, { 0x8700, 0xfcad, 0x6000 }, { 0x8700, 0xfc9d, 0x5000 }, { 0x8700, 0xfc95, 0x4000 }, { 0x8700, 0xfc91, 0x3000 }, { 0x8700, 0xfc8f, 0x2000 }, { 0x0700, 0xfc8e, 0x0000 }, { 0x0700, 0xfc90, 0x0000 }, { 0x8700, 0xfc93, 0x2000 }, { 0x0700, 0xfc92, 0x0000 }, { 0x0700, 0xfc94, 0x0000 }, { 0x8700, 0xfc99, 0x3000 }, { 0x8700, 0xfc97, 0x2000 }, { 0x0700, 0xfc96, 0x0000 }, { 0x0700, 0xfc98, 0x0000 }, { 0x8700, 0xfc9b, 0x2000 }, { 0x0700, 0xfc9a, 0x0000 }, { 0x0700, 0xfc9c, 0x0000 }, { 0x8700, 0xfca5, 0x4000 }, { 0x8700, 0xfca1, 0x3000 }, { 0x8700, 0xfc9f, 0x2000 }, { 0x0700, 0xfc9e, 0x0000 }, { 0x0700, 0xfca0, 0x0000 }, { 0x8700, 0xfca3, 0x2000 }, { 0x0700, 0xfca2, 0x0000 }, { 0x0700, 0xfca4, 0x0000 }, { 0x8700, 0xfca9, 0x3000 }, { 0x8700, 0xfca7, 0x2000 }, { 0x0700, 0xfca6, 0x0000 }, { 0x0700, 0xfca8, 0x0000 }, { 0x8700, 0xfcab, 0x2000 }, { 0x0700, 0xfcaa, 0x0000 }, { 0x0700, 0xfcac, 0x0000 }, { 0x8700, 0xfcbd, 0x5000 }, { 0x8700, 0xfcb5, 0x4000 }, { 0x8700, 0xfcb1, 0x3000 }, { 0x8700, 0xfcaf, 0x2000 }, { 0x0700, 0xfcae, 0x0000 }, { 0x0700, 0xfcb0, 0x0000 }, { 0x8700, 0xfcb3, 0x2000 }, { 0x0700, 0xfcb2, 0x0000 }, { 0x0700, 0xfcb4, 0x0000 }, { 0x8700, 0xfcb9, 0x3000 }, { 0x8700, 0xfcb7, 0x2000 }, { 0x0700, 0xfcb6, 0x0000 }, { 0x0700, 0xfcb8, 0x0000 }, { 0x8700, 0xfcbb, 0x2000 }, { 0x0700, 0xfcba, 0x0000 }, { 0x0700, 0xfcbc, 0x0000 }, { 0x8700, 0xfcc5, 0x4000 }, { 0x8700, 0xfcc1, 0x3000 }, { 0x8700, 0xfcbf, 0x2000 }, { 0x0700, 0xfcbe, 0x0000 }, { 0x0700, 0xfcc0, 0x0000 }, { 0x8700, 0xfcc3, 0x2000 }, { 0x0700, 0xfcc2, 0x0000 }, { 0x0700, 0xfcc4, 0x0000 }, { 0x8700, 0xfcc9, 0x3000 }, { 0x8700, 0xfcc7, 0x2000 }, { 0x0700, 0xfcc6, 0x0000 }, { 0x0700, 0xfcc8, 0x0000 }, { 0x8700, 0xfccb, 0x2000 }, { 0x0700, 0xfcca, 0x0000 }, { 0x0700, 0xfccc, 0x0000 }, { 0x8700, 0xfd0d, 0x7000 }, { 0x8700, 0xfced, 0x6000 }, { 0x8700, 0xfcdd, 0x5000 }, { 0x8700, 0xfcd5, 0x4000 }, { 0x8700, 0xfcd1, 0x3000 }, { 0x8700, 0xfccf, 0x2000 }, { 0x0700, 0xfcce, 0x0000 }, { 0x0700, 0xfcd0, 0x0000 }, { 0x8700, 0xfcd3, 0x2000 }, { 0x0700, 0xfcd2, 0x0000 }, { 0x0700, 0xfcd4, 0x0000 }, { 0x8700, 0xfcd9, 0x3000 }, { 0x8700, 0xfcd7, 0x2000 }, { 0x0700, 0xfcd6, 0x0000 }, { 0x0700, 0xfcd8, 0x0000 }, { 0x8700, 0xfcdb, 0x2000 }, { 0x0700, 0xfcda, 0x0000 }, { 0x0700, 0xfcdc, 0x0000 }, { 0x8700, 0xfce5, 0x4000 }, { 0x8700, 0xfce1, 0x3000 }, { 0x8700, 0xfcdf, 0x2000 }, { 0x0700, 0xfcde, 0x0000 }, { 0x0700, 0xfce0, 0x0000 }, { 0x8700, 0xfce3, 0x2000 }, { 0x0700, 0xfce2, 0x0000 }, { 0x0700, 0xfce4, 0x0000 }, { 0x8700, 0xfce9, 0x3000 }, { 0x8700, 0xfce7, 0x2000 }, { 0x0700, 0xfce6, 0x0000 }, { 0x0700, 0xfce8, 0x0000 }, { 0x8700, 0xfceb, 0x2000 }, { 0x0700, 0xfcea, 0x0000 }, { 0x0700, 0xfcec, 0x0000 }, { 0x8700, 0xfcfd, 0x5000 }, { 0x8700, 0xfcf5, 0x4000 }, { 0x8700, 0xfcf1, 0x3000 }, { 0x8700, 0xfcef, 0x2000 }, { 0x0700, 0xfcee, 0x0000 }, { 0x0700, 0xfcf0, 0x0000 }, { 0x8700, 0xfcf3, 0x2000 }, { 0x0700, 0xfcf2, 0x0000 }, { 0x0700, 0xfcf4, 0x0000 }, { 0x8700, 0xfcf9, 0x3000 }, { 0x8700, 0xfcf7, 0x2000 }, { 0x0700, 0xfcf6, 0x0000 }, { 0x0700, 0xfcf8, 0x0000 }, { 0x8700, 0xfcfb, 0x2000 }, { 0x0700, 0xfcfa, 0x0000 }, { 0x0700, 0xfcfc, 0x0000 }, { 0x8700, 0xfd05, 0x4000 }, { 0x8700, 0xfd01, 0x3000 }, { 0x8700, 0xfcff, 0x2000 }, { 0x0700, 0xfcfe, 0x0000 }, { 0x0700, 0xfd00, 0x0000 }, { 0x8700, 0xfd03, 0x2000 }, { 0x0700, 0xfd02, 0x0000 }, { 0x0700, 0xfd04, 0x0000 }, { 0x8700, 0xfd09, 0x3000 }, { 0x8700, 0xfd07, 0x2000 }, { 0x0700, 0xfd06, 0x0000 }, { 0x0700, 0xfd08, 0x0000 }, { 0x8700, 0xfd0b, 0x2000 }, { 0x0700, 0xfd0a, 0x0000 }, { 0x0700, 0xfd0c, 0x0000 }, { 0x8700, 0xfd2d, 0x6000 }, { 0x8700, 0xfd1d, 0x5000 }, { 0x8700, 0xfd15, 0x4000 }, { 0x8700, 0xfd11, 0x3000 }, { 0x8700, 0xfd0f, 0x2000 }, { 0x0700, 0xfd0e, 0x0000 }, { 0x0700, 0xfd10, 0x0000 }, { 0x8700, 0xfd13, 0x2000 }, { 0x0700, 0xfd12, 0x0000 }, { 0x0700, 0xfd14, 0x0000 }, { 0x8700, 0xfd19, 0x3000 }, { 0x8700, 0xfd17, 0x2000 }, { 0x0700, 0xfd16, 0x0000 }, { 0x0700, 0xfd18, 0x0000 }, { 0x8700, 0xfd1b, 0x2000 }, { 0x0700, 0xfd1a, 0x0000 }, { 0x0700, 0xfd1c, 0x0000 }, { 0x8700, 0xfd25, 0x4000 }, { 0x8700, 0xfd21, 0x3000 }, { 0x8700, 0xfd1f, 0x2000 }, { 0x0700, 0xfd1e, 0x0000 }, { 0x0700, 0xfd20, 0x0000 }, { 0x8700, 0xfd23, 0x2000 }, { 0x0700, 0xfd22, 0x0000 }, { 0x0700, 0xfd24, 0x0000 }, { 0x8700, 0xfd29, 0x3000 }, { 0x8700, 0xfd27, 0x2000 }, { 0x0700, 0xfd26, 0x0000 }, { 0x0700, 0xfd28, 0x0000 }, { 0x8700, 0xfd2b, 0x2000 }, { 0x0700, 0xfd2a, 0x0000 }, { 0x0700, 0xfd2c, 0x0000 }, { 0x8700, 0xfd3d, 0x5000 }, { 0x8700, 0xfd35, 0x4000 }, { 0x8700, 0xfd31, 0x3000 }, { 0x8700, 0xfd2f, 0x2000 }, { 0x0700, 0xfd2e, 0x0000 }, { 0x0700, 0xfd30, 0x0000 }, { 0x8700, 0xfd33, 0x2000 }, { 0x0700, 0xfd32, 0x0000 }, { 0x0700, 0xfd34, 0x0000 }, { 0x8700, 0xfd39, 0x3000 }, { 0x8700, 0xfd37, 0x2000 }, { 0x0700, 0xfd36, 0x0000 }, { 0x0700, 0xfd38, 0x0000 }, { 0x8700, 0xfd3b, 0x2000 }, { 0x0700, 0xfd3a, 0x0000 }, { 0x0700, 0xfd3c, 0x0000 }, { 0x8700, 0xfd55, 0x4000 }, { 0x8700, 0xfd51, 0x3000 }, { 0x9200, 0xfd3f, 0x2000 }, { 0x1600, 0xfd3e, 0x0000 }, { 0x0700, 0xfd50, 0x0000 }, { 0x8700, 0xfd53, 0x2000 }, { 0x0700, 0xfd52, 0x0000 }, { 0x0700, 0xfd54, 0x0000 }, { 0x8700, 0xfd59, 0x3000 }, { 0x8700, 0xfd57, 0x2000 }, { 0x0700, 0xfd56, 0x0000 }, { 0x0700, 0xfd58, 0x0000 }, { 0x8700, 0xfd5b, 0x2000 }, { 0x0700, 0xfd5a, 0x0000 }, { 0x0700, 0xfd5c, 0x0000 }, { 0x8c00, 0xfe09, 0x8000 }, { 0x8700, 0xfd9f, 0x7000 }, { 0x8700, 0xfd7d, 0x6000 }, { 0x8700, 0xfd6d, 0x5000 }, { 0x8700, 0xfd65, 0x4000 }, { 0x8700, 0xfd61, 0x3000 }, { 0x8700, 0xfd5f, 0x2000 }, { 0x0700, 0xfd5e, 0x0000 }, { 0x0700, 0xfd60, 0x0000 }, { 0x8700, 0xfd63, 0x2000 }, { 0x0700, 0xfd62, 0x0000 }, { 0x0700, 0xfd64, 0x0000 }, { 0x8700, 0xfd69, 0x3000 }, { 0x8700, 0xfd67, 0x2000 }, { 0x0700, 0xfd66, 0x0000 }, { 0x0700, 0xfd68, 0x0000 }, { 0x8700, 0xfd6b, 0x2000 }, { 0x0700, 0xfd6a, 0x0000 }, { 0x0700, 0xfd6c, 0x0000 }, { 0x8700, 0xfd75, 0x4000 }, { 0x8700, 0xfd71, 0x3000 }, { 0x8700, 0xfd6f, 0x2000 }, { 0x0700, 0xfd6e, 0x0000 }, { 0x0700, 0xfd70, 0x0000 }, { 0x8700, 0xfd73, 0x2000 }, { 0x0700, 0xfd72, 0x0000 }, { 0x0700, 0xfd74, 0x0000 }, { 0x8700, 0xfd79, 0x3000 }, { 0x8700, 0xfd77, 0x2000 }, { 0x0700, 0xfd76, 0x0000 }, { 0x0700, 0xfd78, 0x0000 }, { 0x8700, 0xfd7b, 0x2000 }, { 0x0700, 0xfd7a, 0x0000 }, { 0x0700, 0xfd7c, 0x0000 }, { 0x8700, 0xfd8d, 0x5000 }, { 0x8700, 0xfd85, 0x4000 }, { 0x8700, 0xfd81, 0x3000 }, { 0x8700, 0xfd7f, 0x2000 }, { 0x0700, 0xfd7e, 0x0000 }, { 0x0700, 0xfd80, 0x0000 }, { 0x8700, 0xfd83, 0x2000 }, { 0x0700, 0xfd82, 0x0000 }, { 0x0700, 0xfd84, 0x0000 }, { 0x8700, 0xfd89, 0x3000 }, { 0x8700, 0xfd87, 0x2000 }, { 0x0700, 0xfd86, 0x0000 }, { 0x0700, 0xfd88, 0x0000 }, { 0x8700, 0xfd8b, 0x2000 }, { 0x0700, 0xfd8a, 0x0000 }, { 0x0700, 0xfd8c, 0x0000 }, { 0x8700, 0xfd97, 0x4000 }, { 0x8700, 0xfd93, 0x3000 }, { 0x8700, 0xfd8f, 0x2000 }, { 0x0700, 0xfd8e, 0x0000 }, { 0x0700, 0xfd92, 0x0000 }, { 0x8700, 0xfd95, 0x2000 }, { 0x0700, 0xfd94, 0x0000 }, { 0x0700, 0xfd96, 0x0000 }, { 0x8700, 0xfd9b, 0x3000 }, { 0x8700, 0xfd99, 0x2000 }, { 0x0700, 0xfd98, 0x0000 }, { 0x0700, 0xfd9a, 0x0000 }, { 0x8700, 0xfd9d, 0x2000 }, { 0x0700, 0xfd9c, 0x0000 }, { 0x0700, 0xfd9e, 0x0000 }, { 0x8700, 0xfdbf, 0x6000 }, { 0x8700, 0xfdaf, 0x5000 }, { 0x8700, 0xfda7, 0x4000 }, { 0x8700, 0xfda3, 0x3000 }, { 0x8700, 0xfda1, 0x2000 }, { 0x0700, 0xfda0, 0x0000 }, { 0x0700, 0xfda2, 0x0000 }, { 0x8700, 0xfda5, 0x2000 }, { 0x0700, 0xfda4, 0x0000 }, { 0x0700, 0xfda6, 0x0000 }, { 0x8700, 0xfdab, 0x3000 }, { 0x8700, 0xfda9, 0x2000 }, { 0x0700, 0xfda8, 0x0000 }, { 0x0700, 0xfdaa, 0x0000 }, { 0x8700, 0xfdad, 0x2000 }, { 0x0700, 0xfdac, 0x0000 }, { 0x0700, 0xfdae, 0x0000 }, { 0x8700, 0xfdb7, 0x4000 }, { 0x8700, 0xfdb3, 0x3000 }, { 0x8700, 0xfdb1, 0x2000 }, { 0x0700, 0xfdb0, 0x0000 }, { 0x0700, 0xfdb2, 0x0000 }, { 0x8700, 0xfdb5, 0x2000 }, { 0x0700, 0xfdb4, 0x0000 }, { 0x0700, 0xfdb6, 0x0000 }, { 0x8700, 0xfdbb, 0x3000 }, { 0x8700, 0xfdb9, 0x2000 }, { 0x0700, 0xfdb8, 0x0000 }, { 0x0700, 0xfdba, 0x0000 }, { 0x8700, 0xfdbd, 0x2000 }, { 0x0700, 0xfdbc, 0x0000 }, { 0x0700, 0xfdbe, 0x0000 }, { 0x8700, 0xfdf7, 0x5000 }, { 0x8700, 0xfdc7, 0x4000 }, { 0x8700, 0xfdc3, 0x3000 }, { 0x8700, 0xfdc1, 0x2000 }, { 0x0700, 0xfdc0, 0x0000 }, { 0x0700, 0xfdc2, 0x0000 }, { 0x8700, 0xfdc5, 0x2000 }, { 0x0700, 0xfdc4, 0x0000 }, { 0x0700, 0xfdc6, 0x0000 }, { 0x8700, 0xfdf3, 0x3000 }, { 0x8700, 0xfdf1, 0x2000 }, { 0x0700, 0xfdf0, 0x0000 }, { 0x0700, 0xfdf2, 0x0000 }, { 0x8700, 0xfdf5, 0x2000 }, { 0x0700, 0xfdf4, 0x0000 }, { 0x0700, 0xfdf6, 0x0000 }, { 0x8c00, 0xfe01, 0x4000 }, { 0x8700, 0xfdfb, 0x3000 }, { 0x8700, 0xfdf9, 0x2000 }, { 0x0700, 0xfdf8, 0x0000 }, { 0x0700, 0xfdfa, 0x0000 }, { 0x9a00, 0xfdfd, 0x2000 }, { 0x1700, 0xfdfc, 0x0000 }, { 0x0c00, 0xfe00, 0x0000 }, { 0x8c00, 0xfe05, 0x3000 }, { 0x8c00, 0xfe03, 0x2000 }, { 0x0c00, 0xfe02, 0x0000 }, { 0x0c00, 0xfe04, 0x0000 }, { 0x8c00, 0xfe07, 0x2000 }, { 0x0c00, 0xfe06, 0x0000 }, { 0x0c00, 0xfe08, 0x0000 }, { 0x9900, 0xfe66, 0x7000 }, { 0x9500, 0xfe45, 0x6000 }, { 0x9600, 0xfe35, 0x5000 }, { 0x8c00, 0xfe21, 0x4000 }, { 0x8c00, 0xfe0d, 0x3000 }, { 0x8c00, 0xfe0b, 0x2000 }, { 0x0c00, 0xfe0a, 0x0000 }, { 0x0c00, 0xfe0c, 0x0000 }, { 0x8c00, 0xfe0f, 0x2000 }, { 0x0c00, 0xfe0e, 0x0000 }, { 0x0c00, 0xfe20, 0x0000 }, { 0x9100, 0xfe31, 0x3000 }, { 0x8c00, 0xfe23, 0x2000 }, { 0x0c00, 0xfe22, 0x0000 }, { 0x1500, 0xfe30, 0x0000 }, { 0x9000, 0xfe33, 0x2000 }, { 0x1100, 0xfe32, 0x0000 }, { 0x1000, 0xfe34, 0x0000 }, { 0x9600, 0xfe3d, 0x4000 }, { 0x9600, 0xfe39, 0x3000 }, { 0x9600, 0xfe37, 0x2000 }, { 0x1200, 0xfe36, 0x0000 }, { 0x1200, 0xfe38, 0x0000 }, { 0x9600, 0xfe3b, 0x2000 }, { 0x1200, 0xfe3a, 0x0000 }, { 0x1200, 0xfe3c, 0x0000 }, { 0x9600, 0xfe41, 0x3000 }, { 0x9600, 0xfe3f, 0x2000 }, { 0x1200, 0xfe3e, 0x0000 }, { 0x1200, 0xfe40, 0x0000 }, { 0x9600, 0xfe43, 0x2000 }, { 0x1200, 0xfe42, 0x0000 }, { 0x1200, 0xfe44, 0x0000 }, { 0x9500, 0xfe56, 0x5000 }, { 0x9000, 0xfe4d, 0x4000 }, { 0x9500, 0xfe49, 0x3000 }, { 0x9600, 0xfe47, 0x2000 }, { 0x1500, 0xfe46, 0x0000 }, { 0x1200, 0xfe48, 0x0000 }, { 0x9500, 0xfe4b, 0x2000 }, { 0x1500, 0xfe4a, 0x0000 }, { 0x1500, 0xfe4c, 0x0000 }, { 0x9500, 0xfe51, 0x3000 }, { 0x9000, 0xfe4f, 0x2000 }, { 0x1000, 0xfe4e, 0x0000 }, { 0x1500, 0xfe50, 0x0000 }, { 0x9500, 0xfe54, 0x2000 }, { 0x1500, 0xfe52, 0x0000 }, { 0x1500, 0xfe55, 0x0000 }, { 0x9200, 0xfe5e, 0x4000 }, { 0x9200, 0xfe5a, 0x3000 }, { 0x9100, 0xfe58, 0x2000 }, { 0x1500, 0xfe57, 0x0000 }, { 0x1600, 0xfe59, 0x0000 }, { 0x9200, 0xfe5c, 0x2000 }, { 0x1600, 0xfe5b, 0x0000 }, { 0x1600, 0xfe5d, 0x0000 }, { 0x9900, 0xfe62, 0x3000 }, { 0x9500, 0xfe60, 0x2000 }, { 0x1500, 0xfe5f, 0x0000 }, { 0x1500, 0xfe61, 0x0000 }, { 0x9900, 0xfe64, 0x2000 }, { 0x1100, 0xfe63, 0x0000 }, { 0x1900, 0xfe65, 0x0000 }, { 0x8700, 0xfe8c, 0x6000 }, { 0x8700, 0xfe7c, 0x5000 }, { 0x8700, 0xfe73, 0x4000 }, { 0x9500, 0xfe6b, 0x3000 }, { 0x9700, 0xfe69, 0x2000 }, { 0x1500, 0xfe68, 0x0000 }, { 0x1500, 0xfe6a, 0x0000 }, { 0x8700, 0xfe71, 0x2000 }, { 0x0700, 0xfe70, 0x0000 }, { 0x0700, 0xfe72, 0x0000 }, { 0x8700, 0xfe78, 0x3000 }, { 0x8700, 0xfe76, 0x2000 }, { 0x0700, 0xfe74, 0x0000 }, { 0x0700, 0xfe77, 0x0000 }, { 0x8700, 0xfe7a, 0x2000 }, { 0x0700, 0xfe79, 0x0000 }, { 0x0700, 0xfe7b, 0x0000 }, { 0x8700, 0xfe84, 0x4000 }, { 0x8700, 0xfe80, 0x3000 }, { 0x8700, 0xfe7e, 0x2000 }, { 0x0700, 0xfe7d, 0x0000 }, { 0x0700, 0xfe7f, 0x0000 }, { 0x8700, 0xfe82, 0x2000 }, { 0x0700, 0xfe81, 0x0000 }, { 0x0700, 0xfe83, 0x0000 }, { 0x8700, 0xfe88, 0x3000 }, { 0x8700, 0xfe86, 0x2000 }, { 0x0700, 0xfe85, 0x0000 }, { 0x0700, 0xfe87, 0x0000 }, { 0x8700, 0xfe8a, 0x2000 }, { 0x0700, 0xfe89, 0x0000 }, { 0x0700, 0xfe8b, 0x0000 }, { 0x8700, 0xfe9c, 0x5000 }, { 0x8700, 0xfe94, 0x4000 }, { 0x8700, 0xfe90, 0x3000 }, { 0x8700, 0xfe8e, 0x2000 }, { 0x0700, 0xfe8d, 0x0000 }, { 0x0700, 0xfe8f, 0x0000 }, { 0x8700, 0xfe92, 0x2000 }, { 0x0700, 0xfe91, 0x0000 }, { 0x0700, 0xfe93, 0x0000 }, { 0x8700, 0xfe98, 0x3000 }, { 0x8700, 0xfe96, 0x2000 }, { 0x0700, 0xfe95, 0x0000 }, { 0x0700, 0xfe97, 0x0000 }, { 0x8700, 0xfe9a, 0x2000 }, { 0x0700, 0xfe99, 0x0000 }, { 0x0700, 0xfe9b, 0x0000 }, { 0x8700, 0xfea4, 0x4000 }, { 0x8700, 0xfea0, 0x3000 }, { 0x8700, 0xfe9e, 0x2000 }, { 0x0700, 0xfe9d, 0x0000 }, { 0x0700, 0xfe9f, 0x0000 }, { 0x8700, 0xfea2, 0x2000 }, { 0x0700, 0xfea1, 0x0000 }, { 0x0700, 0xfea3, 0x0000 }, { 0x8700, 0xfea8, 0x3000 }, { 0x8700, 0xfea6, 0x2000 }, { 0x0700, 0xfea5, 0x0000 }, { 0x0700, 0xfea7, 0x0000 }, { 0x8700, 0xfeaa, 0x2000 }, { 0x0700, 0xfea9, 0x0000 }, { 0x0700, 0xfeab, 0x0000 }, { 0x8700, 0xffaf, 0x9000 }, { 0x8900, 0xff2f, 0x8020 }, { 0x8700, 0xfeec, 0x7000 }, { 0x8700, 0xfecc, 0x6000 }, { 0x8700, 0xfebc, 0x5000 }, { 0x8700, 0xfeb4, 0x4000 }, { 0x8700, 0xfeb0, 0x3000 }, { 0x8700, 0xfeae, 0x2000 }, { 0x0700, 0xfead, 0x0000 }, { 0x0700, 0xfeaf, 0x0000 }, { 0x8700, 0xfeb2, 0x2000 }, { 0x0700, 0xfeb1, 0x0000 }, { 0x0700, 0xfeb3, 0x0000 }, { 0x8700, 0xfeb8, 0x3000 }, { 0x8700, 0xfeb6, 0x2000 }, { 0x0700, 0xfeb5, 0x0000 }, { 0x0700, 0xfeb7, 0x0000 }, { 0x8700, 0xfeba, 0x2000 }, { 0x0700, 0xfeb9, 0x0000 }, { 0x0700, 0xfebb, 0x0000 }, { 0x8700, 0xfec4, 0x4000 }, { 0x8700, 0xfec0, 0x3000 }, { 0x8700, 0xfebe, 0x2000 }, { 0x0700, 0xfebd, 0x0000 }, { 0x0700, 0xfebf, 0x0000 }, { 0x8700, 0xfec2, 0x2000 }, { 0x0700, 0xfec1, 0x0000 }, { 0x0700, 0xfec3, 0x0000 }, { 0x8700, 0xfec8, 0x3000 }, { 0x8700, 0xfec6, 0x2000 }, { 0x0700, 0xfec5, 0x0000 }, { 0x0700, 0xfec7, 0x0000 }, { 0x8700, 0xfeca, 0x2000 }, { 0x0700, 0xfec9, 0x0000 }, { 0x0700, 0xfecb, 0x0000 }, { 0x8700, 0xfedc, 0x5000 }, { 0x8700, 0xfed4, 0x4000 }, { 0x8700, 0xfed0, 0x3000 }, { 0x8700, 0xfece, 0x2000 }, { 0x0700, 0xfecd, 0x0000 }, { 0x0700, 0xfecf, 0x0000 }, { 0x8700, 0xfed2, 0x2000 }, { 0x0700, 0xfed1, 0x0000 }, { 0x0700, 0xfed3, 0x0000 }, { 0x8700, 0xfed8, 0x3000 }, { 0x8700, 0xfed6, 0x2000 }, { 0x0700, 0xfed5, 0x0000 }, { 0x0700, 0xfed7, 0x0000 }, { 0x8700, 0xfeda, 0x2000 }, { 0x0700, 0xfed9, 0x0000 }, { 0x0700, 0xfedb, 0x0000 }, { 0x8700, 0xfee4, 0x4000 }, { 0x8700, 0xfee0, 0x3000 }, { 0x8700, 0xfede, 0x2000 }, { 0x0700, 0xfedd, 0x0000 }, { 0x0700, 0xfedf, 0x0000 }, { 0x8700, 0xfee2, 0x2000 }, { 0x0700, 0xfee1, 0x0000 }, { 0x0700, 0xfee3, 0x0000 }, { 0x8700, 0xfee8, 0x3000 }, { 0x8700, 0xfee6, 0x2000 }, { 0x0700, 0xfee5, 0x0000 }, { 0x0700, 0xfee7, 0x0000 }, { 0x8700, 0xfeea, 0x2000 }, { 0x0700, 0xfee9, 0x0000 }, { 0x0700, 0xfeeb, 0x0000 }, { 0x9500, 0xff0f, 0x6000 }, { 0x8700, 0xfefc, 0x5000 }, { 0x8700, 0xfef4, 0x4000 }, { 0x8700, 0xfef0, 0x3000 }, { 0x8700, 0xfeee, 0x2000 }, { 0x0700, 0xfeed, 0x0000 }, { 0x0700, 0xfeef, 0x0000 }, { 0x8700, 0xfef2, 0x2000 }, { 0x0700, 0xfef1, 0x0000 }, { 0x0700, 0xfef3, 0x0000 }, { 0x8700, 0xfef8, 0x3000 }, { 0x8700, 0xfef6, 0x2000 }, { 0x0700, 0xfef5, 0x0000 }, { 0x0700, 0xfef7, 0x0000 }, { 0x8700, 0xfefa, 0x2000 }, { 0x0700, 0xfef9, 0x0000 }, { 0x0700, 0xfefb, 0x0000 }, { 0x9500, 0xff07, 0x4000 }, { 0x9500, 0xff03, 0x3000 }, { 0x9500, 0xff01, 0x2000 }, { 0x0100, 0xfeff, 0x0000 }, { 0x1500, 0xff02, 0x0000 }, { 0x9500, 0xff05, 0x2000 }, { 0x1700, 0xff04, 0x0000 }, { 0x1500, 0xff06, 0x0000 }, { 0x9900, 0xff0b, 0x3000 }, { 0x9200, 0xff09, 0x2000 }, { 0x1600, 0xff08, 0x0000 }, { 0x1500, 0xff0a, 0x0000 }, { 0x9100, 0xff0d, 0x2000 }, { 0x1500, 0xff0c, 0x0000 }, { 0x1500, 0xff0e, 0x0000 }, { 0x9500, 0xff1f, 0x5000 }, { 0x8d00, 0xff17, 0x4000 }, { 0x8d00, 0xff13, 0x3000 }, { 0x8d00, 0xff11, 0x2000 }, { 0x0d00, 0xff10, 0x0000 }, { 0x0d00, 0xff12, 0x0000 }, { 0x8d00, 0xff15, 0x2000 }, { 0x0d00, 0xff14, 0x0000 }, { 0x0d00, 0xff16, 0x0000 }, { 0x9500, 0xff1b, 0x3000 }, { 0x8d00, 0xff19, 0x2000 }, { 0x0d00, 0xff18, 0x0000 }, { 0x1500, 0xff1a, 0x0000 }, { 0x9900, 0xff1d, 0x2000 }, { 0x1900, 0xff1c, 0x0000 }, { 0x1900, 0xff1e, 0x0000 }, { 0x8900, 0xff27, 0x4020 }, { 0x8900, 0xff23, 0x3020 }, { 0x8900, 0xff21, 0x2020 }, { 0x1500, 0xff20, 0x0000 }, { 0x0900, 0xff22, 0x0020 }, { 0x8900, 0xff25, 0x2020 }, { 0x0900, 0xff24, 0x0020 }, { 0x0900, 0xff26, 0x0020 }, { 0x8900, 0xff2b, 0x3020 }, { 0x8900, 0xff29, 0x2020 }, { 0x0900, 0xff28, 0x0020 }, { 0x0900, 0xff2a, 0x0020 }, { 0x8900, 0xff2d, 0x2020 }, { 0x0900, 0xff2c, 0x0020 }, { 0x0900, 0xff2e, 0x0020 }, { 0x8700, 0xff6f, 0x7000 }, { 0x8500, 0xff4f, 0x6fe0 }, { 0x9000, 0xff3f, 0x5000 }, { 0x8900, 0xff37, 0x4020 }, { 0x8900, 0xff33, 0x3020 }, { 0x8900, 0xff31, 0x2020 }, { 0x0900, 0xff30, 0x0020 }, { 0x0900, 0xff32, 0x0020 }, { 0x8900, 0xff35, 0x2020 }, { 0x0900, 0xff34, 0x0020 }, { 0x0900, 0xff36, 0x0020 }, { 0x9600, 0xff3b, 0x3000 }, { 0x8900, 0xff39, 0x2020 }, { 0x0900, 0xff38, 0x0020 }, { 0x0900, 0xff3a, 0x0020 }, { 0x9200, 0xff3d, 0x2000 }, { 0x1500, 0xff3c, 0x0000 }, { 0x1800, 0xff3e, 0x0000 }, { 0x8500, 0xff47, 0x4fe0 }, { 0x8500, 0xff43, 0x3fe0 }, { 0x8500, 0xff41, 0x2fe0 }, { 0x1800, 0xff40, 0x0000 }, { 0x0500, 0xff42, 0x0fe0 }, { 0x8500, 0xff45, 0x2fe0 }, { 0x0500, 0xff44, 0x0fe0 }, { 0x0500, 0xff46, 0x0fe0 }, { 0x8500, 0xff4b, 0x3fe0 }, { 0x8500, 0xff49, 0x2fe0 }, { 0x0500, 0xff48, 0x0fe0 }, { 0x0500, 0xff4a, 0x0fe0 }, { 0x8500, 0xff4d, 0x2fe0 }, { 0x0500, 0xff4c, 0x0fe0 }, { 0x0500, 0xff4e, 0x0fe0 }, { 0x9600, 0xff5f, 0x5000 }, { 0x8500, 0xff57, 0x4fe0 }, { 0x8500, 0xff53, 0x3fe0 }, { 0x8500, 0xff51, 0x2fe0 }, { 0x0500, 0xff50, 0x0fe0 }, { 0x0500, 0xff52, 0x0fe0 }, { 0x8500, 0xff55, 0x2fe0 }, { 0x0500, 0xff54, 0x0fe0 }, { 0x0500, 0xff56, 0x0fe0 }, { 0x9600, 0xff5b, 0x3000 }, { 0x8500, 0xff59, 0x2fe0 }, { 0x0500, 0xff58, 0x0fe0 }, { 0x0500, 0xff5a, 0x0fe0 }, { 0x9200, 0xff5d, 0x2000 }, { 0x1900, 0xff5c, 0x0000 }, { 0x1900, 0xff5e, 0x0000 }, { 0x8700, 0xff67, 0x4000 }, { 0x9200, 0xff63, 0x3000 }, { 0x9500, 0xff61, 0x2000 }, { 0x1200, 0xff60, 0x0000 }, { 0x1600, 0xff62, 0x0000 }, { 0x9000, 0xff65, 0x2000 }, { 0x1500, 0xff64, 0x0000 }, { 0x0700, 0xff66, 0x0000 }, { 0x8700, 0xff6b, 0x3000 }, { 0x8700, 0xff69, 0x2000 }, { 0x0700, 0xff68, 0x0000 }, { 0x0700, 0xff6a, 0x0000 }, { 0x8700, 0xff6d, 0x2000 }, { 0x0700, 0xff6c, 0x0000 }, { 0x0700, 0xff6e, 0x0000 }, { 0x8700, 0xff8f, 0x6000 }, { 0x8700, 0xff7f, 0x5000 }, { 0x8700, 0xff77, 0x4000 }, { 0x8700, 0xff73, 0x3000 }, { 0x8700, 0xff71, 0x2000 }, { 0x0600, 0xff70, 0x0000 }, { 0x0700, 0xff72, 0x0000 }, { 0x8700, 0xff75, 0x2000 }, { 0x0700, 0xff74, 0x0000 }, { 0x0700, 0xff76, 0x0000 }, { 0x8700, 0xff7b, 0x3000 }, { 0x8700, 0xff79, 0x2000 }, { 0x0700, 0xff78, 0x0000 }, { 0x0700, 0xff7a, 0x0000 }, { 0x8700, 0xff7d, 0x2000 }, { 0x0700, 0xff7c, 0x0000 }, { 0x0700, 0xff7e, 0x0000 }, { 0x8700, 0xff87, 0x4000 }, { 0x8700, 0xff83, 0x3000 }, { 0x8700, 0xff81, 0x2000 }, { 0x0700, 0xff80, 0x0000 }, { 0x0700, 0xff82, 0x0000 }, { 0x8700, 0xff85, 0x2000 }, { 0x0700, 0xff84, 0x0000 }, { 0x0700, 0xff86, 0x0000 }, { 0x8700, 0xff8b, 0x3000 }, { 0x8700, 0xff89, 0x2000 }, { 0x0700, 0xff88, 0x0000 }, { 0x0700, 0xff8a, 0x0000 }, { 0x8700, 0xff8d, 0x2000 }, { 0x0700, 0xff8c, 0x0000 }, { 0x0700, 0xff8e, 0x0000 }, { 0x8600, 0xff9f, 0x5000 }, { 0x8700, 0xff97, 0x4000 }, { 0x8700, 0xff93, 0x3000 }, { 0x8700, 0xff91, 0x2000 }, { 0x0700, 0xff90, 0x0000 }, { 0x0700, 0xff92, 0x0000 }, { 0x8700, 0xff95, 0x2000 }, { 0x0700, 0xff94, 0x0000 }, { 0x0700, 0xff96, 0x0000 }, { 0x8700, 0xff9b, 0x3000 }, { 0x8700, 0xff99, 0x2000 }, { 0x0700, 0xff98, 0x0000 }, { 0x0700, 0xff9a, 0x0000 }, { 0x8700, 0xff9d, 0x2000 }, { 0x0700, 0xff9c, 0x0000 }, { 0x0600, 0xff9e, 0x0000 }, { 0x8700, 0xffa7, 0x4000 }, { 0x8700, 0xffa3, 0x3000 }, { 0x8700, 0xffa1, 0x2000 }, { 0x0700, 0xffa0, 0x0000 }, { 0x0700, 0xffa2, 0x0000 }, { 0x8700, 0xffa5, 0x2000 }, { 0x0700, 0xffa4, 0x0000 }, { 0x0700, 0xffa6, 0x0000 }, { 0x8700, 0xffab, 0x3000 }, { 0x8700, 0xffa9, 0x2000 }, { 0x0700, 0xffa8, 0x0000 }, { 0x0700, 0xffaa, 0x0000 }, { 0x8700, 0xffad, 0x2000 }, { 0x0700, 0xffac, 0x0000 }, { 0x0700, 0xffae, 0x0000 }, { 0x8701, 0x004c, 0x8000 }, { 0x8701, 0x0008, 0x7000 }, { 0x8700, 0xffd6, 0x6000 }, { 0x8700, 0xffc2, 0x5000 }, { 0x8700, 0xffb7, 0x4000 }, { 0x8700, 0xffb3, 0x3000 }, { 0x8700, 0xffb1, 0x2000 }, { 0x0700, 0xffb0, 0x0000 }, { 0x0700, 0xffb2, 0x0000 }, { 0x8700, 0xffb5, 0x2000 }, { 0x0700, 0xffb4, 0x0000 }, { 0x0700, 0xffb6, 0x0000 }, { 0x8700, 0xffbb, 0x3000 }, { 0x8700, 0xffb9, 0x2000 }, { 0x0700, 0xffb8, 0x0000 }, { 0x0700, 0xffba, 0x0000 }, { 0x8700, 0xffbd, 0x2000 }, { 0x0700, 0xffbc, 0x0000 }, { 0x0700, 0xffbe, 0x0000 }, { 0x8700, 0xffcc, 0x4000 }, { 0x8700, 0xffc6, 0x3000 }, { 0x8700, 0xffc4, 0x2000 }, { 0x0700, 0xffc3, 0x0000 }, { 0x0700, 0xffc5, 0x0000 }, { 0x8700, 0xffca, 0x2000 }, { 0x0700, 0xffc7, 0x0000 }, { 0x0700, 0xffcb, 0x0000 }, { 0x8700, 0xffd2, 0x3000 }, { 0x8700, 0xffce, 0x2000 }, { 0x0700, 0xffcd, 0x0000 }, { 0x0700, 0xffcf, 0x0000 }, { 0x8700, 0xffd4, 0x2000 }, { 0x0700, 0xffd3, 0x0000 }, { 0x0700, 0xffd5, 0x0000 }, { 0x9900, 0xffec, 0x5000 }, { 0x9800, 0xffe3, 0x4000 }, { 0x8700, 0xffdc, 0x3000 }, { 0x8700, 0xffda, 0x2000 }, { 0x0700, 0xffd7, 0x0000 }, { 0x0700, 0xffdb, 0x0000 }, { 0x9700, 0xffe1, 0x2000 }, { 0x1700, 0xffe0, 0x0000 }, { 0x1900, 0xffe2, 0x0000 }, { 0x9a00, 0xffe8, 0x3000 }, { 0x9700, 0xffe5, 0x2000 }, { 0x1a00, 0xffe4, 0x0000 }, { 0x1700, 0xffe6, 0x0000 }, { 0x9900, 0xffea, 0x2000 }, { 0x1900, 0xffe9, 0x0000 }, { 0x1900, 0xffeb, 0x0000 }, { 0x8701, 0x0000, 0x4000 }, { 0x8100, 0xfffa, 0x3000 }, { 0x9a00, 0xffee, 0x2000 }, { 0x1a00, 0xffed, 0x0000 }, { 0x0100, 0xfff9, 0x0000 }, { 0x9a00, 0xfffc, 0x2000 }, { 0x0100, 0xfffb, 0x0000 }, { 0x1a00, 0xfffd, 0x0000 }, { 0x8701, 0x0004, 0x3000 }, { 0x8701, 0x0002, 0x2000 }, { 0x0701, 0x0001, 0x0000 }, { 0x0701, 0x0003, 0x0000 }, { 0x8701, 0x0006, 0x2000 }, { 0x0701, 0x0005, 0x0000 }, { 0x0701, 0x0007, 0x0000 }, { 0x8701, 0x002a, 0x6000 }, { 0x8701, 0x0019, 0x5000 }, { 0x8701, 0x0011, 0x4000 }, { 0x8701, 0x000d, 0x3000 }, { 0x8701, 0x000a, 0x2000 }, { 0x0701, 0x0009, 0x0000 }, { 0x0701, 0x000b, 0x0000 }, { 0x8701, 0x000f, 0x2000 }, { 0x0701, 0x000e, 0x0000 }, { 0x0701, 0x0010, 0x0000 }, { 0x8701, 0x0015, 0x3000 }, { 0x8701, 0x0013, 0x2000 }, { 0x0701, 0x0012, 0x0000 }, { 0x0701, 0x0014, 0x0000 }, { 0x8701, 0x0017, 0x2000 }, { 0x0701, 0x0016, 0x0000 }, { 0x0701, 0x0018, 0x0000 }, { 0x8701, 0x0021, 0x4000 }, { 0x8701, 0x001d, 0x3000 }, { 0x8701, 0x001b, 0x2000 }, { 0x0701, 0x001a, 0x0000 }, { 0x0701, 0x001c, 0x0000 }, { 0x8701, 0x001f, 0x2000 }, { 0x0701, 0x001e, 0x0000 }, { 0x0701, 0x0020, 0x0000 }, { 0x8701, 0x0025, 0x3000 }, { 0x8701, 0x0023, 0x2000 }, { 0x0701, 0x0022, 0x0000 }, { 0x0701, 0x0024, 0x0000 }, { 0x8701, 0x0028, 0x2000 }, { 0x0701, 0x0026, 0x0000 }, { 0x0701, 0x0029, 0x0000 }, { 0x8701, 0x003a, 0x5000 }, { 0x8701, 0x0032, 0x4000 }, { 0x8701, 0x002e, 0x3000 }, { 0x8701, 0x002c, 0x2000 }, { 0x0701, 0x002b, 0x0000 }, { 0x0701, 0x002d, 0x0000 }, { 0x8701, 0x0030, 0x2000 }, { 0x0701, 0x002f, 0x0000 }, { 0x0701, 0x0031, 0x0000 }, { 0x8701, 0x0036, 0x3000 }, { 0x8701, 0x0034, 0x2000 }, { 0x0701, 0x0033, 0x0000 }, { 0x0701, 0x0035, 0x0000 }, { 0x8701, 0x0038, 0x2000 }, { 0x0701, 0x0037, 0x0000 }, { 0x0701, 0x0039, 0x0000 }, { 0x8701, 0x0044, 0x4000 }, { 0x8701, 0x0040, 0x3000 }, { 0x8701, 0x003d, 0x2000 }, { 0x0701, 0x003c, 0x0000 }, { 0x0701, 0x003f, 0x0000 }, { 0x8701, 0x0042, 0x2000 }, { 0x0701, 0x0041, 0x0000 }, { 0x0701, 0x0043, 0x0000 }, { 0x8701, 0x0048, 0x3000 }, { 0x8701, 0x0046, 0x2000 }, { 0x0701, 0x0045, 0x0000 }, { 0x0701, 0x0047, 0x0000 }, { 0x8701, 0x004a, 0x2000 }, { 0x0701, 0x0049, 0x0000 }, { 0x0701, 0x004b, 0x0000 }, { 0x8701, 0x00b0, 0x7000 }, { 0x8701, 0x0090, 0x6000 }, { 0x8701, 0x0080, 0x5000 }, { 0x8701, 0x0056, 0x4000 }, { 0x8701, 0x0052, 0x3000 }, { 0x8701, 0x0050, 0x2000 }, { 0x0701, 0x004d, 0x0000 }, { 0x0701, 0x0051, 0x0000 }, { 0x8701, 0x0054, 0x2000 }, { 0x0701, 0x0053, 0x0000 }, { 0x0701, 0x0055, 0x0000 }, { 0x8701, 0x005a, 0x3000 }, { 0x8701, 0x0058, 0x2000 }, { 0x0701, 0x0057, 0x0000 }, { 0x0701, 0x0059, 0x0000 }, { 0x8701, 0x005c, 0x2000 }, { 0x0701, 0x005b, 0x0000 }, { 0x0701, 0x005d, 0x0000 }, { 0x8701, 0x0088, 0x4000 }, { 0x8701, 0x0084, 0x3000 }, { 0x8701, 0x0082, 0x2000 }, { 0x0701, 0x0081, 0x0000 }, { 0x0701, 0x0083, 0x0000 }, { 0x8701, 0x0086, 0x2000 }, { 0x0701, 0x0085, 0x0000 }, { 0x0701, 0x0087, 0x0000 }, { 0x8701, 0x008c, 0x3000 }, { 0x8701, 0x008a, 0x2000 }, { 0x0701, 0x0089, 0x0000 }, { 0x0701, 0x008b, 0x0000 }, { 0x8701, 0x008e, 0x2000 }, { 0x0701, 0x008d, 0x0000 }, { 0x0701, 0x008f, 0x0000 }, { 0x8701, 0x00a0, 0x5000 }, { 0x8701, 0x0098, 0x4000 }, { 0x8701, 0x0094, 0x3000 }, { 0x8701, 0x0092, 0x2000 }, { 0x0701, 0x0091, 0x0000 }, { 0x0701, 0x0093, 0x0000 }, { 0x8701, 0x0096, 0x2000 }, { 0x0701, 0x0095, 0x0000 }, { 0x0701, 0x0097, 0x0000 }, { 0x8701, 0x009c, 0x3000 }, { 0x8701, 0x009a, 0x2000 }, { 0x0701, 0x0099, 0x0000 }, { 0x0701, 0x009b, 0x0000 }, { 0x8701, 0x009e, 0x2000 }, { 0x0701, 0x009d, 0x0000 }, { 0x0701, 0x009f, 0x0000 }, { 0x8701, 0x00a8, 0x4000 }, { 0x8701, 0x00a4, 0x3000 }, { 0x8701, 0x00a2, 0x2000 }, { 0x0701, 0x00a1, 0x0000 }, { 0x0701, 0x00a3, 0x0000 }, { 0x8701, 0x00a6, 0x2000 }, { 0x0701, 0x00a5, 0x0000 }, { 0x0701, 0x00a7, 0x0000 }, { 0x8701, 0x00ac, 0x3000 }, { 0x8701, 0x00aa, 0x2000 }, { 0x0701, 0x00a9, 0x0000 }, { 0x0701, 0x00ab, 0x0000 }, { 0x8701, 0x00ae, 0x2000 }, { 0x0701, 0x00ad, 0x0000 }, { 0x0701, 0x00af, 0x0000 }, { 0x8701, 0x00d0, 0x6000 }, { 0x8701, 0x00c0, 0x5000 }, { 0x8701, 0x00b8, 0x4000 }, { 0x8701, 0x00b4, 0x3000 }, { 0x8701, 0x00b2, 0x2000 }, { 0x0701, 0x00b1, 0x0000 }, { 0x0701, 0x00b3, 0x0000 }, { 0x8701, 0x00b6, 0x2000 }, { 0x0701, 0x00b5, 0x0000 }, { 0x0701, 0x00b7, 0x0000 }, { 0x8701, 0x00bc, 0x3000 }, { 0x8701, 0x00ba, 0x2000 }, { 0x0701, 0x00b9, 0x0000 }, { 0x0701, 0x00bb, 0x0000 }, { 0x8701, 0x00be, 0x2000 }, { 0x0701, 0x00bd, 0x0000 }, { 0x0701, 0x00bf, 0x0000 }, { 0x8701, 0x00c8, 0x4000 }, { 0x8701, 0x00c4, 0x3000 }, { 0x8701, 0x00c2, 0x2000 }, { 0x0701, 0x00c1, 0x0000 }, { 0x0701, 0x00c3, 0x0000 }, { 0x8701, 0x00c6, 0x2000 }, { 0x0701, 0x00c5, 0x0000 }, { 0x0701, 0x00c7, 0x0000 }, { 0x8701, 0x00cc, 0x3000 }, { 0x8701, 0x00ca, 0x2000 }, { 0x0701, 0x00c9, 0x0000 }, { 0x0701, 0x00cb, 0x0000 }, { 0x8701, 0x00ce, 0x2000 }, { 0x0701, 0x00cd, 0x0000 }, { 0x0701, 0x00cf, 0x0000 }, { 0x8701, 0x00e0, 0x5000 }, { 0x8701, 0x00d8, 0x4000 }, { 0x8701, 0x00d4, 0x3000 }, { 0x8701, 0x00d2, 0x2000 }, { 0x0701, 0x00d1, 0x0000 }, { 0x0701, 0x00d3, 0x0000 }, { 0x8701, 0x00d6, 0x2000 }, { 0x0701, 0x00d5, 0x0000 }, { 0x0701, 0x00d7, 0x0000 }, { 0x8701, 0x00dc, 0x3000 }, { 0x8701, 0x00da, 0x2000 }, { 0x0701, 0x00d9, 0x0000 }, { 0x0701, 0x00db, 0x0000 }, { 0x8701, 0x00de, 0x2000 }, { 0x0701, 0x00dd, 0x0000 }, { 0x0701, 0x00df, 0x0000 }, { 0x8701, 0x00e8, 0x4000 }, { 0x8701, 0x00e4, 0x3000 }, { 0x8701, 0x00e2, 0x2000 }, { 0x0701, 0x00e1, 0x0000 }, { 0x0701, 0x00e3, 0x0000 }, { 0x8701, 0x00e6, 0x2000 }, { 0x0701, 0x00e5, 0x0000 }, { 0x0701, 0x00e7, 0x0000 }, { 0x8701, 0x00ec, 0x3000 }, { 0x8701, 0x00ea, 0x2000 }, { 0x0701, 0x00e9, 0x0000 }, { 0x0701, 0x00eb, 0x0000 }, { 0x8701, 0x00ee, 0x2000 }, { 0x0701, 0x00ed, 0x0000 }, { 0x0701, 0x00ef, 0x0000 }, { 0x8501, 0xd459, 0xb000 }, { 0x9a01, 0xd080, 0xa000 }, { 0x8701, 0x045f, 0x9000 }, { 0x8701, 0x0349, 0x8000 }, { 0x9a01, 0x013c, 0x7000 }, { 0x8f01, 0x0119, 0x6000 }, { 0x8f01, 0x0109, 0x5000 }, { 0x8701, 0x00f8, 0x4000 }, { 0x8701, 0x00f4, 0x3000 }, { 0x8701, 0x00f2, 0x2000 }, { 0x0701, 0x00f1, 0x0000 }, { 0x0701, 0x00f3, 0x0000 }, { 0x8701, 0x00f6, 0x2000 }, { 0x0701, 0x00f5, 0x0000 }, { 0x0701, 0x00f7, 0x0000 }, { 0x9501, 0x0101, 0x3000 }, { 0x8701, 0x00fa, 0x2000 }, { 0x0701, 0x00f9, 0x0000 }, { 0x1501, 0x0100, 0x0000 }, { 0x8f01, 0x0107, 0x2000 }, { 0x1a01, 0x0102, 0x0000 }, { 0x0f01, 0x0108, 0x0000 }, { 0x8f01, 0x0111, 0x4000 }, { 0x8f01, 0x010d, 0x3000 }, { 0x8f01, 0x010b, 0x2000 }, { 0x0f01, 0x010a, 0x0000 }, { 0x0f01, 0x010c, 0x0000 }, { 0x8f01, 0x010f, 0x2000 }, { 0x0f01, 0x010e, 0x0000 }, { 0x0f01, 0x0110, 0x0000 }, { 0x8f01, 0x0115, 0x3000 }, { 0x8f01, 0x0113, 0x2000 }, { 0x0f01, 0x0112, 0x0000 }, { 0x0f01, 0x0114, 0x0000 }, { 0x8f01, 0x0117, 0x2000 }, { 0x0f01, 0x0116, 0x0000 }, { 0x0f01, 0x0118, 0x0000 }, { 0x8f01, 0x0129, 0x5000 }, { 0x8f01, 0x0121, 0x4000 }, { 0x8f01, 0x011d, 0x3000 }, { 0x8f01, 0x011b, 0x2000 }, { 0x0f01, 0x011a, 0x0000 }, { 0x0f01, 0x011c, 0x0000 }, { 0x8f01, 0x011f, 0x2000 }, { 0x0f01, 0x011e, 0x0000 }, { 0x0f01, 0x0120, 0x0000 }, { 0x8f01, 0x0125, 0x3000 }, { 0x8f01, 0x0123, 0x2000 }, { 0x0f01, 0x0122, 0x0000 }, { 0x0f01, 0x0124, 0x0000 }, { 0x8f01, 0x0127, 0x2000 }, { 0x0f01, 0x0126, 0x0000 }, { 0x0f01, 0x0128, 0x0000 }, { 0x8f01, 0x0131, 0x4000 }, { 0x8f01, 0x012d, 0x3000 }, { 0x8f01, 0x012b, 0x2000 }, { 0x0f01, 0x012a, 0x0000 }, { 0x0f01, 0x012c, 0x0000 }, { 0x8f01, 0x012f, 0x2000 }, { 0x0f01, 0x012e, 0x0000 }, { 0x0f01, 0x0130, 0x0000 }, { 0x9a01, 0x0138, 0x3000 }, { 0x8f01, 0x0133, 0x2000 }, { 0x0f01, 0x0132, 0x0000 }, { 0x1a01, 0x0137, 0x0000 }, { 0x9a01, 0x013a, 0x2000 }, { 0x1a01, 0x0139, 0x0000 }, { 0x1a01, 0x013b, 0x0000 }, { 0x8701, 0x031c, 0x6000 }, { 0x8701, 0x030c, 0x5000 }, { 0x8701, 0x0304, 0x4000 }, { 0x8701, 0x0300, 0x3000 }, { 0x9a01, 0x013e, 0x2000 }, { 0x1a01, 0x013d, 0x0000 }, { 0x1a01, 0x013f, 0x0000 }, { 0x8701, 0x0302, 0x2000 }, { 0x0701, 0x0301, 0x0000 }, { 0x0701, 0x0303, 0x0000 }, { 0x8701, 0x0308, 0x3000 }, { 0x8701, 0x0306, 0x2000 }, { 0x0701, 0x0305, 0x0000 }, { 0x0701, 0x0307, 0x0000 }, { 0x8701, 0x030a, 0x2000 }, { 0x0701, 0x0309, 0x0000 }, { 0x0701, 0x030b, 0x0000 }, { 0x8701, 0x0314, 0x4000 }, { 0x8701, 0x0310, 0x3000 }, { 0x8701, 0x030e, 0x2000 }, { 0x0701, 0x030d, 0x0000 }, { 0x0701, 0x030f, 0x0000 }, { 0x8701, 0x0312, 0x2000 }, { 0x0701, 0x0311, 0x0000 }, { 0x0701, 0x0313, 0x0000 }, { 0x8701, 0x0318, 0x3000 }, { 0x8701, 0x0316, 0x2000 }, { 0x0701, 0x0315, 0x0000 }, { 0x0701, 0x0317, 0x0000 }, { 0x8701, 0x031a, 0x2000 }, { 0x0701, 0x0319, 0x0000 }, { 0x0701, 0x031b, 0x0000 }, { 0x8701, 0x0339, 0x5000 }, { 0x8701, 0x0331, 0x4000 }, { 0x8f01, 0x0321, 0x3000 }, { 0x8701, 0x031e, 0x2000 }, { 0x0701, 0x031d, 0x0000 }, { 0x0f01, 0x0320, 0x0000 }, { 0x8f01, 0x0323, 0x2000 }, { 0x0f01, 0x0322, 0x0000 }, { 0x0701, 0x0330, 0x0000 }, { 0x8701, 0x0335, 0x3000 }, { 0x8701, 0x0333, 0x2000 }, { 0x0701, 0x0332, 0x0000 }, { 0x0701, 0x0334, 0x0000 }, { 0x8701, 0x0337, 0x2000 }, { 0x0701, 0x0336, 0x0000 }, { 0x0701, 0x0338, 0x0000 }, { 0x8701, 0x0341, 0x4000 }, { 0x8701, 0x033d, 0x3000 }, { 0x8701, 0x033b, 0x2000 }, { 0x0701, 0x033a, 0x0000 }, { 0x0701, 0x033c, 0x0000 }, { 0x8701, 0x033f, 0x2000 }, { 0x0701, 0x033e, 0x0000 }, { 0x0701, 0x0340, 0x0000 }, { 0x8701, 0x0345, 0x3000 }, { 0x8701, 0x0343, 0x2000 }, { 0x0701, 0x0342, 0x0000 }, { 0x0701, 0x0344, 0x0000 }, { 0x8701, 0x0347, 0x2000 }, { 0x0701, 0x0346, 0x0000 }, { 0x0701, 0x0348, 0x0000 }, { 0x8901, 0x041f, 0x7028 }, { 0x9501, 0x039f, 0x6000 }, { 0x8701, 0x038e, 0x5000 }, { 0x8701, 0x0386, 0x4000 }, { 0x8701, 0x0382, 0x3000 }, { 0x8701, 0x0380, 0x2000 }, { 0x0e01, 0x034a, 0x0000 }, { 0x0701, 0x0381, 0x0000 }, { 0x8701, 0x0384, 0x2000 }, { 0x0701, 0x0383, 0x0000 }, { 0x0701, 0x0385, 0x0000 }, { 0x8701, 0x038a, 0x3000 }, { 0x8701, 0x0388, 0x2000 }, { 0x0701, 0x0387, 0x0000 }, { 0x0701, 0x0389, 0x0000 }, { 0x8701, 0x038c, 0x2000 }, { 0x0701, 0x038b, 0x0000 }, { 0x0701, 0x038d, 0x0000 }, { 0x8701, 0x0396, 0x4000 }, { 0x8701, 0x0392, 0x3000 }, { 0x8701, 0x0390, 0x2000 }, { 0x0701, 0x038f, 0x0000 }, { 0x0701, 0x0391, 0x0000 }, { 0x8701, 0x0394, 0x2000 }, { 0x0701, 0x0393, 0x0000 }, { 0x0701, 0x0395, 0x0000 }, { 0x8701, 0x039a, 0x3000 }, { 0x8701, 0x0398, 0x2000 }, { 0x0701, 0x0397, 0x0000 }, { 0x0701, 0x0399, 0x0000 }, { 0x8701, 0x039c, 0x2000 }, { 0x0701, 0x039b, 0x0000 }, { 0x0701, 0x039d, 0x0000 }, { 0x8901, 0x040f, 0x5028 }, { 0x8901, 0x0407, 0x4028 }, { 0x8901, 0x0403, 0x3028 }, { 0x8901, 0x0401, 0x2028 }, { 0x0901, 0x0400, 0x0028 }, { 0x0901, 0x0402, 0x0028 }, { 0x8901, 0x0405, 0x2028 }, { 0x0901, 0x0404, 0x0028 }, { 0x0901, 0x0406, 0x0028 }, { 0x8901, 0x040b, 0x3028 }, { 0x8901, 0x0409, 0x2028 }, { 0x0901, 0x0408, 0x0028 }, { 0x0901, 0x040a, 0x0028 }, { 0x8901, 0x040d, 0x2028 }, { 0x0901, 0x040c, 0x0028 }, { 0x0901, 0x040e, 0x0028 }, { 0x8901, 0x0417, 0x4028 }, { 0x8901, 0x0413, 0x3028 }, { 0x8901, 0x0411, 0x2028 }, { 0x0901, 0x0410, 0x0028 }, { 0x0901, 0x0412, 0x0028 }, { 0x8901, 0x0415, 0x2028 }, { 0x0901, 0x0414, 0x0028 }, { 0x0901, 0x0416, 0x0028 }, { 0x8901, 0x041b, 0x3028 }, { 0x8901, 0x0419, 0x2028 }, { 0x0901, 0x0418, 0x0028 }, { 0x0901, 0x041a, 0x0028 }, { 0x8901, 0x041d, 0x2028 }, { 0x0901, 0x041c, 0x0028 }, { 0x0901, 0x041e, 0x0028 }, { 0x8501, 0x043f, 0x6fd8 }, { 0x8501, 0x042f, 0x5fd8 }, { 0x8901, 0x0427, 0x4028 }, { 0x8901, 0x0423, 0x3028 }, { 0x8901, 0x0421, 0x2028 }, { 0x0901, 0x0420, 0x0028 }, { 0x0901, 0x0422, 0x0028 }, { 0x8901, 0x0425, 0x2028 }, { 0x0901, 0x0424, 0x0028 }, { 0x0901, 0x0426, 0x0028 }, { 0x8501, 0x042b, 0x3fd8 }, { 0x8501, 0x0429, 0x2fd8 }, { 0x0501, 0x0428, 0x0fd8 }, { 0x0501, 0x042a, 0x0fd8 }, { 0x8501, 0x042d, 0x2fd8 }, { 0x0501, 0x042c, 0x0fd8 }, { 0x0501, 0x042e, 0x0fd8 }, { 0x8501, 0x0437, 0x4fd8 }, { 0x8501, 0x0433, 0x3fd8 }, { 0x8501, 0x0431, 0x2fd8 }, { 0x0501, 0x0430, 0x0fd8 }, { 0x0501, 0x0432, 0x0fd8 }, { 0x8501, 0x0435, 0x2fd8 }, { 0x0501, 0x0434, 0x0fd8 }, { 0x0501, 0x0436, 0x0fd8 }, { 0x8501, 0x043b, 0x3fd8 }, { 0x8501, 0x0439, 0x2fd8 }, { 0x0501, 0x0438, 0x0fd8 }, { 0x0501, 0x043a, 0x0fd8 }, { 0x8501, 0x043d, 0x2fd8 }, { 0x0501, 0x043c, 0x0fd8 }, { 0x0501, 0x043e, 0x0fd8 }, { 0x8501, 0x044f, 0x5fd8 }, { 0x8501, 0x0447, 0x4fd8 }, { 0x8501, 0x0443, 0x3fd8 }, { 0x8501, 0x0441, 0x2fd8 }, { 0x0501, 0x0440, 0x0fd8 }, { 0x0501, 0x0442, 0x0fd8 }, { 0x8501, 0x0445, 0x2fd8 }, { 0x0501, 0x0444, 0x0fd8 }, { 0x0501, 0x0446, 0x0fd8 }, { 0x8501, 0x044b, 0x3fd8 }, { 0x8501, 0x0449, 0x2fd8 }, { 0x0501, 0x0448, 0x0fd8 }, { 0x0501, 0x044a, 0x0fd8 }, { 0x8501, 0x044d, 0x2fd8 }, { 0x0501, 0x044c, 0x0fd8 }, { 0x0501, 0x044e, 0x0fd8 }, { 0x8701, 0x0457, 0x4000 }, { 0x8701, 0x0453, 0x3000 }, { 0x8701, 0x0451, 0x2000 }, { 0x0701, 0x0450, 0x0000 }, { 0x0701, 0x0452, 0x0000 }, { 0x8701, 0x0455, 0x2000 }, { 0x0701, 0x0454, 0x0000 }, { 0x0701, 0x0456, 0x0000 }, { 0x8701, 0x045b, 0x3000 }, { 0x8701, 0x0459, 0x2000 }, { 0x0701, 0x0458, 0x0000 }, { 0x0701, 0x045a, 0x0000 }, { 0x8701, 0x045d, 0x2000 }, { 0x0701, 0x045c, 0x0000 }, { 0x0701, 0x045e, 0x0000 }, { 0x9a01, 0xd000, 0x8000 }, { 0x8d01, 0x04a1, 0x7000 }, { 0x8701, 0x047f, 0x6000 }, { 0x8701, 0x046f, 0x5000 }, { 0x8701, 0x0467, 0x4000 }, { 0x8701, 0x0463, 0x3000 }, { 0x8701, 0x0461, 0x2000 }, { 0x0701, 0x0460, 0x0000 }, { 0x0701, 0x0462, 0x0000 }, { 0x8701, 0x0465, 0x2000 }, { 0x0701, 0x0464, 0x0000 }, { 0x0701, 0x0466, 0x0000 }, { 0x8701, 0x046b, 0x3000 }, { 0x8701, 0x0469, 0x2000 }, { 0x0701, 0x0468, 0x0000 }, { 0x0701, 0x046a, 0x0000 }, { 0x8701, 0x046d, 0x2000 }, { 0x0701, 0x046c, 0x0000 }, { 0x0701, 0x046e, 0x0000 }, { 0x8701, 0x0477, 0x4000 }, { 0x8701, 0x0473, 0x3000 }, { 0x8701, 0x0471, 0x2000 }, { 0x0701, 0x0470, 0x0000 }, { 0x0701, 0x0472, 0x0000 }, { 0x8701, 0x0475, 0x2000 }, { 0x0701, 0x0474, 0x0000 }, { 0x0701, 0x0476, 0x0000 }, { 0x8701, 0x047b, 0x3000 }, { 0x8701, 0x0479, 0x2000 }, { 0x0701, 0x0478, 0x0000 }, { 0x0701, 0x047a, 0x0000 }, { 0x8701, 0x047d, 0x2000 }, { 0x0701, 0x047c, 0x0000 }, { 0x0701, 0x047e, 0x0000 }, { 0x8701, 0x048f, 0x5000 }, { 0x8701, 0x0487, 0x4000 }, { 0x8701, 0x0483, 0x3000 }, { 0x8701, 0x0481, 0x2000 }, { 0x0701, 0x0480, 0x0000 }, { 0x0701, 0x0482, 0x0000 }, { 0x8701, 0x0485, 0x2000 }, { 0x0701, 0x0484, 0x0000 }, { 0x0701, 0x0486, 0x0000 }, { 0x8701, 0x048b, 0x3000 }, { 0x8701, 0x0489, 0x2000 }, { 0x0701, 0x0488, 0x0000 }, { 0x0701, 0x048a, 0x0000 }, { 0x8701, 0x048d, 0x2000 }, { 0x0701, 0x048c, 0x0000 }, { 0x0701, 0x048e, 0x0000 }, { 0x8701, 0x0497, 0x4000 }, { 0x8701, 0x0493, 0x3000 }, { 0x8701, 0x0491, 0x2000 }, { 0x0701, 0x0490, 0x0000 }, { 0x0701, 0x0492, 0x0000 }, { 0x8701, 0x0495, 0x2000 }, { 0x0701, 0x0494, 0x0000 }, { 0x0701, 0x0496, 0x0000 }, { 0x8701, 0x049b, 0x3000 }, { 0x8701, 0x0499, 0x2000 }, { 0x0701, 0x0498, 0x0000 }, { 0x0701, 0x049a, 0x0000 }, { 0x8701, 0x049d, 0x2000 }, { 0x0701, 0x049c, 0x0000 }, { 0x0d01, 0x04a0, 0x0000 }, { 0x8701, 0x081a, 0x6000 }, { 0x8701, 0x080a, 0x5000 }, { 0x8d01, 0x04a9, 0x4000 }, { 0x8d01, 0x04a5, 0x3000 }, { 0x8d01, 0x04a3, 0x2000 }, { 0x0d01, 0x04a2, 0x0000 }, { 0x0d01, 0x04a4, 0x0000 }, { 0x8d01, 0x04a7, 0x2000 }, { 0x0d01, 0x04a6, 0x0000 }, { 0x0d01, 0x04a8, 0x0000 }, { 0x8701, 0x0803, 0x3000 }, { 0x8701, 0x0801, 0x2000 }, { 0x0701, 0x0800, 0x0000 }, { 0x0701, 0x0802, 0x0000 }, { 0x8701, 0x0805, 0x2000 }, { 0x0701, 0x0804, 0x0000 }, { 0x0701, 0x0808, 0x0000 }, { 0x8701, 0x0812, 0x4000 }, { 0x8701, 0x080e, 0x3000 }, { 0x8701, 0x080c, 0x2000 }, { 0x0701, 0x080b, 0x0000 }, { 0x0701, 0x080d, 0x0000 }, { 0x8701, 0x0810, 0x2000 }, { 0x0701, 0x080f, 0x0000 }, { 0x0701, 0x0811, 0x0000 }, { 0x8701, 0x0816, 0x3000 }, { 0x8701, 0x0814, 0x2000 }, { 0x0701, 0x0813, 0x0000 }, { 0x0701, 0x0815, 0x0000 }, { 0x8701, 0x0818, 0x2000 }, { 0x0701, 0x0817, 0x0000 }, { 0x0701, 0x0819, 0x0000 }, { 0x8701, 0x082a, 0x5000 }, { 0x8701, 0x0822, 0x4000 }, { 0x8701, 0x081e, 0x3000 }, { 0x8701, 0x081c, 0x2000 }, { 0x0701, 0x081b, 0x0000 }, { 0x0701, 0x081d, 0x0000 }, { 0x8701, 0x0820, 0x2000 }, { 0x0701, 0x081f, 0x0000 }, { 0x0701, 0x0821, 0x0000 }, { 0x8701, 0x0826, 0x3000 }, { 0x8701, 0x0824, 0x2000 }, { 0x0701, 0x0823, 0x0000 }, { 0x0701, 0x0825, 0x0000 }, { 0x8701, 0x0828, 0x2000 }, { 0x0701, 0x0827, 0x0000 }, { 0x0701, 0x0829, 0x0000 }, { 0x8701, 0x0832, 0x4000 }, { 0x8701, 0x082e, 0x3000 }, { 0x8701, 0x082c, 0x2000 }, { 0x0701, 0x082b, 0x0000 }, { 0x0701, 0x082d, 0x0000 }, { 0x8701, 0x0830, 0x2000 }, { 0x0701, 0x082f, 0x0000 }, { 0x0701, 0x0831, 0x0000 }, { 0x8701, 0x0837, 0x3000 }, { 0x8701, 0x0834, 0x2000 }, { 0x0701, 0x0833, 0x0000 }, { 0x0701, 0x0835, 0x0000 }, { 0x8701, 0x083c, 0x2000 }, { 0x0701, 0x0838, 0x0000 }, { 0x0701, 0x083f, 0x0000 }, { 0x9a01, 0xd040, 0x7000 }, { 0x9a01, 0xd020, 0x6000 }, { 0x9a01, 0xd010, 0x5000 }, { 0x9a01, 0xd008, 0x4000 }, { 0x9a01, 0xd004, 0x3000 }, { 0x9a01, 0xd002, 0x2000 }, { 0x1a01, 0xd001, 0x0000 }, { 0x1a01, 0xd003, 0x0000 }, { 0x9a01, 0xd006, 0x2000 }, { 0x1a01, 0xd005, 0x0000 }, { 0x1a01, 0xd007, 0x0000 }, { 0x9a01, 0xd00c, 0x3000 }, { 0x9a01, 0xd00a, 0x2000 }, { 0x1a01, 0xd009, 0x0000 }, { 0x1a01, 0xd00b, 0x0000 }, { 0x9a01, 0xd00e, 0x2000 }, { 0x1a01, 0xd00d, 0x0000 }, { 0x1a01, 0xd00f, 0x0000 }, { 0x9a01, 0xd018, 0x4000 }, { 0x9a01, 0xd014, 0x3000 }, { 0x9a01, 0xd012, 0x2000 }, { 0x1a01, 0xd011, 0x0000 }, { 0x1a01, 0xd013, 0x0000 }, { 0x9a01, 0xd016, 0x2000 }, { 0x1a01, 0xd015, 0x0000 }, { 0x1a01, 0xd017, 0x0000 }, { 0x9a01, 0xd01c, 0x3000 }, { 0x9a01, 0xd01a, 0x2000 }, { 0x1a01, 0xd019, 0x0000 }, { 0x1a01, 0xd01b, 0x0000 }, { 0x9a01, 0xd01e, 0x2000 }, { 0x1a01, 0xd01d, 0x0000 }, { 0x1a01, 0xd01f, 0x0000 }, { 0x9a01, 0xd030, 0x5000 }, { 0x9a01, 0xd028, 0x4000 }, { 0x9a01, 0xd024, 0x3000 }, { 0x9a01, 0xd022, 0x2000 }, { 0x1a01, 0xd021, 0x0000 }, { 0x1a01, 0xd023, 0x0000 }, { 0x9a01, 0xd026, 0x2000 }, { 0x1a01, 0xd025, 0x0000 }, { 0x1a01, 0xd027, 0x0000 }, { 0x9a01, 0xd02c, 0x3000 }, { 0x9a01, 0xd02a, 0x2000 }, { 0x1a01, 0xd029, 0x0000 }, { 0x1a01, 0xd02b, 0x0000 }, { 0x9a01, 0xd02e, 0x2000 }, { 0x1a01, 0xd02d, 0x0000 }, { 0x1a01, 0xd02f, 0x0000 }, { 0x9a01, 0xd038, 0x4000 }, { 0x9a01, 0xd034, 0x3000 }, { 0x9a01, 0xd032, 0x2000 }, { 0x1a01, 0xd031, 0x0000 }, { 0x1a01, 0xd033, 0x0000 }, { 0x9a01, 0xd036, 0x2000 }, { 0x1a01, 0xd035, 0x0000 }, { 0x1a01, 0xd037, 0x0000 }, { 0x9a01, 0xd03c, 0x3000 }, { 0x9a01, 0xd03a, 0x2000 }, { 0x1a01, 0xd039, 0x0000 }, { 0x1a01, 0xd03b, 0x0000 }, { 0x9a01, 0xd03e, 0x2000 }, { 0x1a01, 0xd03d, 0x0000 }, { 0x1a01, 0xd03f, 0x0000 }, { 0x9a01, 0xd060, 0x6000 }, { 0x9a01, 0xd050, 0x5000 }, { 0x9a01, 0xd048, 0x4000 }, { 0x9a01, 0xd044, 0x3000 }, { 0x9a01, 0xd042, 0x2000 }, { 0x1a01, 0xd041, 0x0000 }, { 0x1a01, 0xd043, 0x0000 }, { 0x9a01, 0xd046, 0x2000 }, { 0x1a01, 0xd045, 0x0000 }, { 0x1a01, 0xd047, 0x0000 }, { 0x9a01, 0xd04c, 0x3000 }, { 0x9a01, 0xd04a, 0x2000 }, { 0x1a01, 0xd049, 0x0000 }, { 0x1a01, 0xd04b, 0x0000 }, { 0x9a01, 0xd04e, 0x2000 }, { 0x1a01, 0xd04d, 0x0000 }, { 0x1a01, 0xd04f, 0x0000 }, { 0x9a01, 0xd058, 0x4000 }, { 0x9a01, 0xd054, 0x3000 }, { 0x9a01, 0xd052, 0x2000 }, { 0x1a01, 0xd051, 0x0000 }, { 0x1a01, 0xd053, 0x0000 }, { 0x9a01, 0xd056, 0x2000 }, { 0x1a01, 0xd055, 0x0000 }, { 0x1a01, 0xd057, 0x0000 }, { 0x9a01, 0xd05c, 0x3000 }, { 0x9a01, 0xd05a, 0x2000 }, { 0x1a01, 0xd059, 0x0000 }, { 0x1a01, 0xd05b, 0x0000 }, { 0x9a01, 0xd05e, 0x2000 }, { 0x1a01, 0xd05d, 0x0000 }, { 0x1a01, 0xd05f, 0x0000 }, { 0x9a01, 0xd070, 0x5000 }, { 0x9a01, 0xd068, 0x4000 }, { 0x9a01, 0xd064, 0x3000 }, { 0x9a01, 0xd062, 0x2000 }, { 0x1a01, 0xd061, 0x0000 }, { 0x1a01, 0xd063, 0x0000 }, { 0x9a01, 0xd066, 0x2000 }, { 0x1a01, 0xd065, 0x0000 }, { 0x1a01, 0xd067, 0x0000 }, { 0x9a01, 0xd06c, 0x3000 }, { 0x9a01, 0xd06a, 0x2000 }, { 0x1a01, 0xd069, 0x0000 }, { 0x1a01, 0xd06b, 0x0000 }, { 0x9a01, 0xd06e, 0x2000 }, { 0x1a01, 0xd06d, 0x0000 }, { 0x1a01, 0xd06f, 0x0000 }, { 0x9a01, 0xd078, 0x4000 }, { 0x9a01, 0xd074, 0x3000 }, { 0x9a01, 0xd072, 0x2000 }, { 0x1a01, 0xd071, 0x0000 }, { 0x1a01, 0xd073, 0x0000 }, { 0x9a01, 0xd076, 0x2000 }, { 0x1a01, 0xd075, 0x0000 }, { 0x1a01, 0xd077, 0x0000 }, { 0x9a01, 0xd07c, 0x3000 }, { 0x9a01, 0xd07a, 0x2000 }, { 0x1a01, 0xd079, 0x0000 }, { 0x1a01, 0xd07b, 0x0000 }, { 0x9a01, 0xd07e, 0x2000 }, { 0x1a01, 0xd07d, 0x0000 }, { 0x1a01, 0xd07f, 0x0000 }, { 0x9a01, 0xd18d, 0x9000 }, { 0x9a01, 0xd10a, 0x8000 }, { 0x9a01, 0xd0c0, 0x7000 }, { 0x9a01, 0xd0a0, 0x6000 }, { 0x9a01, 0xd090, 0x5000 }, { 0x9a01, 0xd088, 0x4000 }, { 0x9a01, 0xd084, 0x3000 }, { 0x9a01, 0xd082, 0x2000 }, { 0x1a01, 0xd081, 0x0000 }, { 0x1a01, 0xd083, 0x0000 }, { 0x9a01, 0xd086, 0x2000 }, { 0x1a01, 0xd085, 0x0000 }, { 0x1a01, 0xd087, 0x0000 }, { 0x9a01, 0xd08c, 0x3000 }, { 0x9a01, 0xd08a, 0x2000 }, { 0x1a01, 0xd089, 0x0000 }, { 0x1a01, 0xd08b, 0x0000 }, { 0x9a01, 0xd08e, 0x2000 }, { 0x1a01, 0xd08d, 0x0000 }, { 0x1a01, 0xd08f, 0x0000 }, { 0x9a01, 0xd098, 0x4000 }, { 0x9a01, 0xd094, 0x3000 }, { 0x9a01, 0xd092, 0x2000 }, { 0x1a01, 0xd091, 0x0000 }, { 0x1a01, 0xd093, 0x0000 }, { 0x9a01, 0xd096, 0x2000 }, { 0x1a01, 0xd095, 0x0000 }, { 0x1a01, 0xd097, 0x0000 }, { 0x9a01, 0xd09c, 0x3000 }, { 0x9a01, 0xd09a, 0x2000 }, { 0x1a01, 0xd099, 0x0000 }, { 0x1a01, 0xd09b, 0x0000 }, { 0x9a01, 0xd09e, 0x2000 }, { 0x1a01, 0xd09d, 0x0000 }, { 0x1a01, 0xd09f, 0x0000 }, { 0x9a01, 0xd0b0, 0x5000 }, { 0x9a01, 0xd0a8, 0x4000 }, { 0x9a01, 0xd0a4, 0x3000 }, { 0x9a01, 0xd0a2, 0x2000 }, { 0x1a01, 0xd0a1, 0x0000 }, { 0x1a01, 0xd0a3, 0x0000 }, { 0x9a01, 0xd0a6, 0x2000 }, { 0x1a01, 0xd0a5, 0x0000 }, { 0x1a01, 0xd0a7, 0x0000 }, { 0x9a01, 0xd0ac, 0x3000 }, { 0x9a01, 0xd0aa, 0x2000 }, { 0x1a01, 0xd0a9, 0x0000 }, { 0x1a01, 0xd0ab, 0x0000 }, { 0x9a01, 0xd0ae, 0x2000 }, { 0x1a01, 0xd0ad, 0x0000 }, { 0x1a01, 0xd0af, 0x0000 }, { 0x9a01, 0xd0b8, 0x4000 }, { 0x9a01, 0xd0b4, 0x3000 }, { 0x9a01, 0xd0b2, 0x2000 }, { 0x1a01, 0xd0b1, 0x0000 }, { 0x1a01, 0xd0b3, 0x0000 }, { 0x9a01, 0xd0b6, 0x2000 }, { 0x1a01, 0xd0b5, 0x0000 }, { 0x1a01, 0xd0b7, 0x0000 }, { 0x9a01, 0xd0bc, 0x3000 }, { 0x9a01, 0xd0ba, 0x2000 }, { 0x1a01, 0xd0b9, 0x0000 }, { 0x1a01, 0xd0bb, 0x0000 }, { 0x9a01, 0xd0be, 0x2000 }, { 0x1a01, 0xd0bd, 0x0000 }, { 0x1a01, 0xd0bf, 0x0000 }, { 0x9a01, 0xd0e0, 0x6000 }, { 0x9a01, 0xd0d0, 0x5000 }, { 0x9a01, 0xd0c8, 0x4000 }, { 0x9a01, 0xd0c4, 0x3000 }, { 0x9a01, 0xd0c2, 0x2000 }, { 0x1a01, 0xd0c1, 0x0000 }, { 0x1a01, 0xd0c3, 0x0000 }, { 0x9a01, 0xd0c6, 0x2000 }, { 0x1a01, 0xd0c5, 0x0000 }, { 0x1a01, 0xd0c7, 0x0000 }, { 0x9a01, 0xd0cc, 0x3000 }, { 0x9a01, 0xd0ca, 0x2000 }, { 0x1a01, 0xd0c9, 0x0000 }, { 0x1a01, 0xd0cb, 0x0000 }, { 0x9a01, 0xd0ce, 0x2000 }, { 0x1a01, 0xd0cd, 0x0000 }, { 0x1a01, 0xd0cf, 0x0000 }, { 0x9a01, 0xd0d8, 0x4000 }, { 0x9a01, 0xd0d4, 0x3000 }, { 0x9a01, 0xd0d2, 0x2000 }, { 0x1a01, 0xd0d1, 0x0000 }, { 0x1a01, 0xd0d3, 0x0000 }, { 0x9a01, 0xd0d6, 0x2000 }, { 0x1a01, 0xd0d5, 0x0000 }, { 0x1a01, 0xd0d7, 0x0000 }, { 0x9a01, 0xd0dc, 0x3000 }, { 0x9a01, 0xd0da, 0x2000 }, { 0x1a01, 0xd0d9, 0x0000 }, { 0x1a01, 0xd0db, 0x0000 }, { 0x9a01, 0xd0de, 0x2000 }, { 0x1a01, 0xd0dd, 0x0000 }, { 0x1a01, 0xd0df, 0x0000 }, { 0x9a01, 0xd0f0, 0x5000 }, { 0x9a01, 0xd0e8, 0x4000 }, { 0x9a01, 0xd0e4, 0x3000 }, { 0x9a01, 0xd0e2, 0x2000 }, { 0x1a01, 0xd0e1, 0x0000 }, { 0x1a01, 0xd0e3, 0x0000 }, { 0x9a01, 0xd0e6, 0x2000 }, { 0x1a01, 0xd0e5, 0x0000 }, { 0x1a01, 0xd0e7, 0x0000 }, { 0x9a01, 0xd0ec, 0x3000 }, { 0x9a01, 0xd0ea, 0x2000 }, { 0x1a01, 0xd0e9, 0x0000 }, { 0x1a01, 0xd0eb, 0x0000 }, { 0x9a01, 0xd0ee, 0x2000 }, { 0x1a01, 0xd0ed, 0x0000 }, { 0x1a01, 0xd0ef, 0x0000 }, { 0x9a01, 0xd102, 0x4000 }, { 0x9a01, 0xd0f4, 0x3000 }, { 0x9a01, 0xd0f2, 0x2000 }, { 0x1a01, 0xd0f1, 0x0000 }, { 0x1a01, 0xd0f3, 0x0000 }, { 0x9a01, 0xd100, 0x2000 }, { 0x1a01, 0xd0f5, 0x0000 }, { 0x1a01, 0xd101, 0x0000 }, { 0x9a01, 0xd106, 0x3000 }, { 0x9a01, 0xd104, 0x2000 }, { 0x1a01, 0xd103, 0x0000 }, { 0x1a01, 0xd105, 0x0000 }, { 0x9a01, 0xd108, 0x2000 }, { 0x1a01, 0xd107, 0x0000 }, { 0x1a01, 0xd109, 0x0000 }, { 0x9a01, 0xd14d, 0x7000 }, { 0x9a01, 0xd12d, 0x6000 }, { 0x9a01, 0xd11a, 0x5000 }, { 0x9a01, 0xd112, 0x4000 }, { 0x9a01, 0xd10e, 0x3000 }, { 0x9a01, 0xd10c, 0x2000 }, { 0x1a01, 0xd10b, 0x0000 }, { 0x1a01, 0xd10d, 0x0000 }, { 0x9a01, 0xd110, 0x2000 }, { 0x1a01, 0xd10f, 0x0000 }, { 0x1a01, 0xd111, 0x0000 }, { 0x9a01, 0xd116, 0x3000 }, { 0x9a01, 0xd114, 0x2000 }, { 0x1a01, 0xd113, 0x0000 }, { 0x1a01, 0xd115, 0x0000 }, { 0x9a01, 0xd118, 0x2000 }, { 0x1a01, 0xd117, 0x0000 }, { 0x1a01, 0xd119, 0x0000 }, { 0x9a01, 0xd122, 0x4000 }, { 0x9a01, 0xd11e, 0x3000 }, { 0x9a01, 0xd11c, 0x2000 }, { 0x1a01, 0xd11b, 0x0000 }, { 0x1a01, 0xd11d, 0x0000 }, { 0x9a01, 0xd120, 0x2000 }, { 0x1a01, 0xd11f, 0x0000 }, { 0x1a01, 0xd121, 0x0000 }, { 0x9a01, 0xd126, 0x3000 }, { 0x9a01, 0xd124, 0x2000 }, { 0x1a01, 0xd123, 0x0000 }, { 0x1a01, 0xd125, 0x0000 }, { 0x9a01, 0xd12b, 0x2000 }, { 0x1a01, 0xd12a, 0x0000 }, { 0x1a01, 0xd12c, 0x0000 }, { 0x9a01, 0xd13d, 0x5000 }, { 0x9a01, 0xd135, 0x4000 }, { 0x9a01, 0xd131, 0x3000 }, { 0x9a01, 0xd12f, 0x2000 }, { 0x1a01, 0xd12e, 0x0000 }, { 0x1a01, 0xd130, 0x0000 }, { 0x9a01, 0xd133, 0x2000 }, { 0x1a01, 0xd132, 0x0000 }, { 0x1a01, 0xd134, 0x0000 }, { 0x9a01, 0xd139, 0x3000 }, { 0x9a01, 0xd137, 0x2000 }, { 0x1a01, 0xd136, 0x0000 }, { 0x1a01, 0xd138, 0x0000 }, { 0x9a01, 0xd13b, 0x2000 }, { 0x1a01, 0xd13a, 0x0000 }, { 0x1a01, 0xd13c, 0x0000 }, { 0x9a01, 0xd145, 0x4000 }, { 0x9a01, 0xd141, 0x3000 }, { 0x9a01, 0xd13f, 0x2000 }, { 0x1a01, 0xd13e, 0x0000 }, { 0x1a01, 0xd140, 0x0000 }, { 0x9a01, 0xd143, 0x2000 }, { 0x1a01, 0xd142, 0x0000 }, { 0x1a01, 0xd144, 0x0000 }, { 0x9a01, 0xd149, 0x3000 }, { 0x9a01, 0xd147, 0x2000 }, { 0x1a01, 0xd146, 0x0000 }, { 0x1a01, 0xd148, 0x0000 }, { 0x9a01, 0xd14b, 0x2000 }, { 0x1a01, 0xd14a, 0x0000 }, { 0x1a01, 0xd14c, 0x0000 }, { 0x8a01, 0xd16d, 0x6000 }, { 0x9a01, 0xd15d, 0x5000 }, { 0x9a01, 0xd155, 0x4000 }, { 0x9a01, 0xd151, 0x3000 }, { 0x9a01, 0xd14f, 0x2000 }, { 0x1a01, 0xd14e, 0x0000 }, { 0x1a01, 0xd150, 0x0000 }, { 0x9a01, 0xd153, 0x2000 }, { 0x1a01, 0xd152, 0x0000 }, { 0x1a01, 0xd154, 0x0000 }, { 0x9a01, 0xd159, 0x3000 }, { 0x9a01, 0xd157, 0x2000 }, { 0x1a01, 0xd156, 0x0000 }, { 0x1a01, 0xd158, 0x0000 }, { 0x9a01, 0xd15b, 0x2000 }, { 0x1a01, 0xd15a, 0x0000 }, { 0x1a01, 0xd15c, 0x0000 }, { 0x8a01, 0xd165, 0x4000 }, { 0x9a01, 0xd161, 0x3000 }, { 0x9a01, 0xd15f, 0x2000 }, { 0x1a01, 0xd15e, 0x0000 }, { 0x1a01, 0xd160, 0x0000 }, { 0x9a01, 0xd163, 0x2000 }, { 0x1a01, 0xd162, 0x0000 }, { 0x1a01, 0xd164, 0x0000 }, { 0x8c01, 0xd169, 0x3000 }, { 0x8c01, 0xd167, 0x2000 }, { 0x0a01, 0xd166, 0x0000 }, { 0x0c01, 0xd168, 0x0000 }, { 0x9a01, 0xd16b, 0x2000 }, { 0x1a01, 0xd16a, 0x0000 }, { 0x1a01, 0xd16c, 0x0000 }, { 0x8c01, 0xd17d, 0x5000 }, { 0x8101, 0xd175, 0x4000 }, { 0x8a01, 0xd171, 0x3000 }, { 0x8a01, 0xd16f, 0x2000 }, { 0x0a01, 0xd16e, 0x0000 }, { 0x0a01, 0xd170, 0x0000 }, { 0x8101, 0xd173, 0x2000 }, { 0x0a01, 0xd172, 0x0000 }, { 0x0101, 0xd174, 0x0000 }, { 0x8101, 0xd179, 0x3000 }, { 0x8101, 0xd177, 0x2000 }, { 0x0101, 0xd176, 0x0000 }, { 0x0101, 0xd178, 0x0000 }, { 0x8c01, 0xd17b, 0x2000 }, { 0x0101, 0xd17a, 0x0000 }, { 0x0c01, 0xd17c, 0x0000 }, { 0x8c01, 0xd185, 0x4000 }, { 0x8c01, 0xd181, 0x3000 }, { 0x8c01, 0xd17f, 0x2000 }, { 0x0c01, 0xd17e, 0x0000 }, { 0x0c01, 0xd180, 0x0000 }, { 0x9a01, 0xd183, 0x2000 }, { 0x0c01, 0xd182, 0x0000 }, { 0x1a01, 0xd184, 0x0000 }, { 0x8c01, 0xd189, 0x3000 }, { 0x8c01, 0xd187, 0x2000 }, { 0x0c01, 0xd186, 0x0000 }, { 0x0c01, 0xd188, 0x0000 }, { 0x8c01, 0xd18b, 0x2000 }, { 0x0c01, 0xd18a, 0x0000 }, { 0x1a01, 0xd18c, 0x0000 }, { 0x9a01, 0xd32f, 0x8000 }, { 0x9a01, 0xd1cd, 0x7000 }, { 0x8c01, 0xd1ad, 0x6000 }, { 0x9a01, 0xd19d, 0x5000 }, { 0x9a01, 0xd195, 0x4000 }, { 0x9a01, 0xd191, 0x3000 }, { 0x9a01, 0xd18f, 0x2000 }, { 0x1a01, 0xd18e, 0x0000 }, { 0x1a01, 0xd190, 0x0000 }, { 0x9a01, 0xd193, 0x2000 }, { 0x1a01, 0xd192, 0x0000 }, { 0x1a01, 0xd194, 0x0000 }, { 0x9a01, 0xd199, 0x3000 }, { 0x9a01, 0xd197, 0x2000 }, { 0x1a01, 0xd196, 0x0000 }, { 0x1a01, 0xd198, 0x0000 }, { 0x9a01, 0xd19b, 0x2000 }, { 0x1a01, 0xd19a, 0x0000 }, { 0x1a01, 0xd19c, 0x0000 }, { 0x9a01, 0xd1a5, 0x4000 }, { 0x9a01, 0xd1a1, 0x3000 }, { 0x9a01, 0xd19f, 0x2000 }, { 0x1a01, 0xd19e, 0x0000 }, { 0x1a01, 0xd1a0, 0x0000 }, { 0x9a01, 0xd1a3, 0x2000 }, { 0x1a01, 0xd1a2, 0x0000 }, { 0x1a01, 0xd1a4, 0x0000 }, { 0x9a01, 0xd1a9, 0x3000 }, { 0x9a01, 0xd1a7, 0x2000 }, { 0x1a01, 0xd1a6, 0x0000 }, { 0x1a01, 0xd1a8, 0x0000 }, { 0x8c01, 0xd1ab, 0x2000 }, { 0x0c01, 0xd1aa, 0x0000 }, { 0x0c01, 0xd1ac, 0x0000 }, { 0x9a01, 0xd1bd, 0x5000 }, { 0x9a01, 0xd1b5, 0x4000 }, { 0x9a01, 0xd1b1, 0x3000 }, { 0x9a01, 0xd1af, 0x2000 }, { 0x1a01, 0xd1ae, 0x0000 }, { 0x1a01, 0xd1b0, 0x0000 }, { 0x9a01, 0xd1b3, 0x2000 }, { 0x1a01, 0xd1b2, 0x0000 }, { 0x1a01, 0xd1b4, 0x0000 }, { 0x9a01, 0xd1b9, 0x3000 }, { 0x9a01, 0xd1b7, 0x2000 }, { 0x1a01, 0xd1b6, 0x0000 }, { 0x1a01, 0xd1b8, 0x0000 }, { 0x9a01, 0xd1bb, 0x2000 }, { 0x1a01, 0xd1ba, 0x0000 }, { 0x1a01, 0xd1bc, 0x0000 }, { 0x9a01, 0xd1c5, 0x4000 }, { 0x9a01, 0xd1c1, 0x3000 }, { 0x9a01, 0xd1bf, 0x2000 }, { 0x1a01, 0xd1be, 0x0000 }, { 0x1a01, 0xd1c0, 0x0000 }, { 0x9a01, 0xd1c3, 0x2000 }, { 0x1a01, 0xd1c2, 0x0000 }, { 0x1a01, 0xd1c4, 0x0000 }, { 0x9a01, 0xd1c9, 0x3000 }, { 0x9a01, 0xd1c7, 0x2000 }, { 0x1a01, 0xd1c6, 0x0000 }, { 0x1a01, 0xd1c8, 0x0000 }, { 0x9a01, 0xd1cb, 0x2000 }, { 0x1a01, 0xd1ca, 0x0000 }, { 0x1a01, 0xd1cc, 0x0000 }, { 0x9a01, 0xd30f, 0x6000 }, { 0x9a01, 0xd1dd, 0x5000 }, { 0x9a01, 0xd1d5, 0x4000 }, { 0x9a01, 0xd1d1, 0x3000 }, { 0x9a01, 0xd1cf, 0x2000 }, { 0x1a01, 0xd1ce, 0x0000 }, { 0x1a01, 0xd1d0, 0x0000 }, { 0x9a01, 0xd1d3, 0x2000 }, { 0x1a01, 0xd1d2, 0x0000 }, { 0x1a01, 0xd1d4, 0x0000 }, { 0x9a01, 0xd1d9, 0x3000 }, { 0x9a01, 0xd1d7, 0x2000 }, { 0x1a01, 0xd1d6, 0x0000 }, { 0x1a01, 0xd1d8, 0x0000 }, { 0x9a01, 0xd1db, 0x2000 }, { 0x1a01, 0xd1da, 0x0000 }, { 0x1a01, 0xd1dc, 0x0000 }, { 0x9a01, 0xd307, 0x4000 }, { 0x9a01, 0xd303, 0x3000 }, { 0x9a01, 0xd301, 0x2000 }, { 0x1a01, 0xd300, 0x0000 }, { 0x1a01, 0xd302, 0x0000 }, { 0x9a01, 0xd305, 0x2000 }, { 0x1a01, 0xd304, 0x0000 }, { 0x1a01, 0xd306, 0x0000 }, { 0x9a01, 0xd30b, 0x3000 }, { 0x9a01, 0xd309, 0x2000 }, { 0x1a01, 0xd308, 0x0000 }, { 0x1a01, 0xd30a, 0x0000 }, { 0x9a01, 0xd30d, 0x2000 }, { 0x1a01, 0xd30c, 0x0000 }, { 0x1a01, 0xd30e, 0x0000 }, { 0x9a01, 0xd31f, 0x5000 }, { 0x9a01, 0xd317, 0x4000 }, { 0x9a01, 0xd313, 0x3000 }, { 0x9a01, 0xd311, 0x2000 }, { 0x1a01, 0xd310, 0x0000 }, { 0x1a01, 0xd312, 0x0000 }, { 0x9a01, 0xd315, 0x2000 }, { 0x1a01, 0xd314, 0x0000 }, { 0x1a01, 0xd316, 0x0000 }, { 0x9a01, 0xd31b, 0x3000 }, { 0x9a01, 0xd319, 0x2000 }, { 0x1a01, 0xd318, 0x0000 }, { 0x1a01, 0xd31a, 0x0000 }, { 0x9a01, 0xd31d, 0x2000 }, { 0x1a01, 0xd31c, 0x0000 }, { 0x1a01, 0xd31e, 0x0000 }, { 0x9a01, 0xd327, 0x4000 }, { 0x9a01, 0xd323, 0x3000 }, { 0x9a01, 0xd321, 0x2000 }, { 0x1a01, 0xd320, 0x0000 }, { 0x1a01, 0xd322, 0x0000 }, { 0x9a01, 0xd325, 0x2000 }, { 0x1a01, 0xd324, 0x0000 }, { 0x1a01, 0xd326, 0x0000 }, { 0x9a01, 0xd32b, 0x3000 }, { 0x9a01, 0xd329, 0x2000 }, { 0x1a01, 0xd328, 0x0000 }, { 0x1a01, 0xd32a, 0x0000 }, { 0x9a01, 0xd32d, 0x2000 }, { 0x1a01, 0xd32c, 0x0000 }, { 0x1a01, 0xd32e, 0x0000 }, { 0x8901, 0xd418, 0x7000 }, { 0x9a01, 0xd34f, 0x6000 }, { 0x9a01, 0xd33f, 0x5000 }, { 0x9a01, 0xd337, 0x4000 }, { 0x9a01, 0xd333, 0x3000 }, { 0x9a01, 0xd331, 0x2000 }, { 0x1a01, 0xd330, 0x0000 }, { 0x1a01, 0xd332, 0x0000 }, { 0x9a01, 0xd335, 0x2000 }, { 0x1a01, 0xd334, 0x0000 }, { 0x1a01, 0xd336, 0x0000 }, { 0x9a01, 0xd33b, 0x3000 }, { 0x9a01, 0xd339, 0x2000 }, { 0x1a01, 0xd338, 0x0000 }, { 0x1a01, 0xd33a, 0x0000 }, { 0x9a01, 0xd33d, 0x2000 }, { 0x1a01, 0xd33c, 0x0000 }, { 0x1a01, 0xd33e, 0x0000 }, { 0x9a01, 0xd347, 0x4000 }, { 0x9a01, 0xd343, 0x3000 }, { 0x9a01, 0xd341, 0x2000 }, { 0x1a01, 0xd340, 0x0000 }, { 0x1a01, 0xd342, 0x0000 }, { 0x9a01, 0xd345, 0x2000 }, { 0x1a01, 0xd344, 0x0000 }, { 0x1a01, 0xd346, 0x0000 }, { 0x9a01, 0xd34b, 0x3000 }, { 0x9a01, 0xd349, 0x2000 }, { 0x1a01, 0xd348, 0x0000 }, { 0x1a01, 0xd34a, 0x0000 }, { 0x9a01, 0xd34d, 0x2000 }, { 0x1a01, 0xd34c, 0x0000 }, { 0x1a01, 0xd34e, 0x0000 }, { 0x8901, 0xd408, 0x5000 }, { 0x8901, 0xd400, 0x4000 }, { 0x9a01, 0xd353, 0x3000 }, { 0x9a01, 0xd351, 0x2000 }, { 0x1a01, 0xd350, 0x0000 }, { 0x1a01, 0xd352, 0x0000 }, { 0x9a01, 0xd355, 0x2000 }, { 0x1a01, 0xd354, 0x0000 }, { 0x1a01, 0xd356, 0x0000 }, { 0x8901, 0xd404, 0x3000 }, { 0x8901, 0xd402, 0x2000 }, { 0x0901, 0xd401, 0x0000 }, { 0x0901, 0xd403, 0x0000 }, { 0x8901, 0xd406, 0x2000 }, { 0x0901, 0xd405, 0x0000 }, { 0x0901, 0xd407, 0x0000 }, { 0x8901, 0xd410, 0x4000 }, { 0x8901, 0xd40c, 0x3000 }, { 0x8901, 0xd40a, 0x2000 }, { 0x0901, 0xd409, 0x0000 }, { 0x0901, 0xd40b, 0x0000 }, { 0x8901, 0xd40e, 0x2000 }, { 0x0901, 0xd40d, 0x0000 }, { 0x0901, 0xd40f, 0x0000 }, { 0x8901, 0xd414, 0x3000 }, { 0x8901, 0xd412, 0x2000 }, { 0x0901, 0xd411, 0x0000 }, { 0x0901, 0xd413, 0x0000 }, { 0x8901, 0xd416, 0x2000 }, { 0x0901, 0xd415, 0x0000 }, { 0x0901, 0xd417, 0x0000 }, { 0x8901, 0xd438, 0x6000 }, { 0x8501, 0xd428, 0x5000 }, { 0x8501, 0xd420, 0x4000 }, { 0x8501, 0xd41c, 0x3000 }, { 0x8501, 0xd41a, 0x2000 }, { 0x0901, 0xd419, 0x0000 }, { 0x0501, 0xd41b, 0x0000 }, { 0x8501, 0xd41e, 0x2000 }, { 0x0501, 0xd41d, 0x0000 }, { 0x0501, 0xd41f, 0x0000 }, { 0x8501, 0xd424, 0x3000 }, { 0x8501, 0xd422, 0x2000 }, { 0x0501, 0xd421, 0x0000 }, { 0x0501, 0xd423, 0x0000 }, { 0x8501, 0xd426, 0x2000 }, { 0x0501, 0xd425, 0x0000 }, { 0x0501, 0xd427, 0x0000 }, { 0x8501, 0xd430, 0x4000 }, { 0x8501, 0xd42c, 0x3000 }, { 0x8501, 0xd42a, 0x2000 }, { 0x0501, 0xd429, 0x0000 }, { 0x0501, 0xd42b, 0x0000 }, { 0x8501, 0xd42e, 0x2000 }, { 0x0501, 0xd42d, 0x0000 }, { 0x0501, 0xd42f, 0x0000 }, { 0x8901, 0xd434, 0x3000 }, { 0x8501, 0xd432, 0x2000 }, { 0x0501, 0xd431, 0x0000 }, { 0x0501, 0xd433, 0x0000 }, { 0x8901, 0xd436, 0x2000 }, { 0x0901, 0xd435, 0x0000 }, { 0x0901, 0xd437, 0x0000 }, { 0x8901, 0xd448, 0x5000 }, { 0x8901, 0xd440, 0x4000 }, { 0x8901, 0xd43c, 0x3000 }, { 0x8901, 0xd43a, 0x2000 }, { 0x0901, 0xd439, 0x0000 }, { 0x0901, 0xd43b, 0x0000 }, { 0x8901, 0xd43e, 0x2000 }, { 0x0901, 0xd43d, 0x0000 }, { 0x0901, 0xd43f, 0x0000 }, { 0x8901, 0xd444, 0x3000 }, { 0x8901, 0xd442, 0x2000 }, { 0x0901, 0xd441, 0x0000 }, { 0x0901, 0xd443, 0x0000 }, { 0x8901, 0xd446, 0x2000 }, { 0x0901, 0xd445, 0x0000 }, { 0x0901, 0xd447, 0x0000 }, { 0x8501, 0xd450, 0x4000 }, { 0x8901, 0xd44c, 0x3000 }, { 0x8901, 0xd44a, 0x2000 }, { 0x0901, 0xd449, 0x0000 }, { 0x0901, 0xd44b, 0x0000 }, { 0x8501, 0xd44e, 0x2000 }, { 0x0901, 0xd44d, 0x0000 }, { 0x0501, 0xd44f, 0x0000 }, { 0x8501, 0xd454, 0x3000 }, { 0x8501, 0xd452, 0x2000 }, { 0x0501, 0xd451, 0x0000 }, { 0x0501, 0xd453, 0x0000 }, { 0x8501, 0xd457, 0x2000 }, { 0x0501, 0xd456, 0x0000 }, { 0x0501, 0xd458, 0x0000 }, { 0x8702, 0xf876, 0xb000 }, { 0x8901, 0xd670, 0xa000 }, { 0x8901, 0xd570, 0x9000 }, { 0x8901, 0xd4e4, 0x8000 }, { 0x8501, 0xd499, 0x7000 }, { 0x8901, 0xd479, 0x6000 }, { 0x8901, 0xd469, 0x5000 }, { 0x8501, 0xd461, 0x4000 }, { 0x8501, 0xd45d, 0x3000 }, { 0x8501, 0xd45b, 0x2000 }, { 0x0501, 0xd45a, 0x0000 }, { 0x0501, 0xd45c, 0x0000 }, { 0x8501, 0xd45f, 0x2000 }, { 0x0501, 0xd45e, 0x0000 }, { 0x0501, 0xd460, 0x0000 }, { 0x8501, 0xd465, 0x3000 }, { 0x8501, 0xd463, 0x2000 }, { 0x0501, 0xd462, 0x0000 }, { 0x0501, 0xd464, 0x0000 }, { 0x8501, 0xd467, 0x2000 }, { 0x0501, 0xd466, 0x0000 }, { 0x0901, 0xd468, 0x0000 }, { 0x8901, 0xd471, 0x4000 }, { 0x8901, 0xd46d, 0x3000 }, { 0x8901, 0xd46b, 0x2000 }, { 0x0901, 0xd46a, 0x0000 }, { 0x0901, 0xd46c, 0x0000 }, { 0x8901, 0xd46f, 0x2000 }, { 0x0901, 0xd46e, 0x0000 }, { 0x0901, 0xd470, 0x0000 }, { 0x8901, 0xd475, 0x3000 }, { 0x8901, 0xd473, 0x2000 }, { 0x0901, 0xd472, 0x0000 }, { 0x0901, 0xd474, 0x0000 }, { 0x8901, 0xd477, 0x2000 }, { 0x0901, 0xd476, 0x0000 }, { 0x0901, 0xd478, 0x0000 }, { 0x8501, 0xd489, 0x5000 }, { 0x8901, 0xd481, 0x4000 }, { 0x8901, 0xd47d, 0x3000 }, { 0x8901, 0xd47b, 0x2000 }, { 0x0901, 0xd47a, 0x0000 }, { 0x0901, 0xd47c, 0x0000 }, { 0x8901, 0xd47f, 0x2000 }, { 0x0901, 0xd47e, 0x0000 }, { 0x0901, 0xd480, 0x0000 }, { 0x8501, 0xd485, 0x3000 }, { 0x8501, 0xd483, 0x2000 }, { 0x0501, 0xd482, 0x0000 }, { 0x0501, 0xd484, 0x0000 }, { 0x8501, 0xd487, 0x2000 }, { 0x0501, 0xd486, 0x0000 }, { 0x0501, 0xd488, 0x0000 }, { 0x8501, 0xd491, 0x4000 }, { 0x8501, 0xd48d, 0x3000 }, { 0x8501, 0xd48b, 0x2000 }, { 0x0501, 0xd48a, 0x0000 }, { 0x0501, 0xd48c, 0x0000 }, { 0x8501, 0xd48f, 0x2000 }, { 0x0501, 0xd48e, 0x0000 }, { 0x0501, 0xd490, 0x0000 }, { 0x8501, 0xd495, 0x3000 }, { 0x8501, 0xd493, 0x2000 }, { 0x0501, 0xd492, 0x0000 }, { 0x0501, 0xd494, 0x0000 }, { 0x8501, 0xd497, 0x2000 }, { 0x0501, 0xd496, 0x0000 }, { 0x0501, 0xd498, 0x0000 }, { 0x8501, 0xd4c3, 0x6000 }, { 0x8901, 0xd4b1, 0x5000 }, { 0x8901, 0xd4a6, 0x4000 }, { 0x8901, 0xd49e, 0x3000 }, { 0x8501, 0xd49b, 0x2000 }, { 0x0501, 0xd49a, 0x0000 }, { 0x0901, 0xd49c, 0x0000 }, { 0x8901, 0xd4a2, 0x2000 }, { 0x0901, 0xd49f, 0x0000 }, { 0x0901, 0xd4a5, 0x0000 }, { 0x8901, 0xd4ac, 0x3000 }, { 0x8901, 0xd4aa, 0x2000 }, { 0x0901, 0xd4a9, 0x0000 }, { 0x0901, 0xd4ab, 0x0000 }, { 0x8901, 0xd4af, 0x2000 }, { 0x0901, 0xd4ae, 0x0000 }, { 0x0901, 0xd4b0, 0x0000 }, { 0x8501, 0xd4b9, 0x4000 }, { 0x8901, 0xd4b5, 0x3000 }, { 0x8901, 0xd4b3, 0x2000 }, { 0x0901, 0xd4b2, 0x0000 }, { 0x0901, 0xd4b4, 0x0000 }, { 0x8501, 0xd4b7, 0x2000 }, { 0x0501, 0xd4b6, 0x0000 }, { 0x0501, 0xd4b8, 0x0000 }, { 0x8501, 0xd4bf, 0x3000 }, { 0x8501, 0xd4bd, 0x2000 }, { 0x0501, 0xd4bb, 0x0000 }, { 0x0501, 0xd4be, 0x0000 }, { 0x8501, 0xd4c1, 0x2000 }, { 0x0501, 0xd4c0, 0x0000 }, { 0x0501, 0xd4c2, 0x0000 }, { 0x8901, 0xd4d4, 0x5000 }, { 0x8501, 0xd4cc, 0x4000 }, { 0x8501, 0xd4c8, 0x3000 }, { 0x8501, 0xd4c6, 0x2000 }, { 0x0501, 0xd4c5, 0x0000 }, { 0x0501, 0xd4c7, 0x0000 }, { 0x8501, 0xd4ca, 0x2000 }, { 0x0501, 0xd4c9, 0x0000 }, { 0x0501, 0xd4cb, 0x0000 }, { 0x8901, 0xd4d0, 0x3000 }, { 0x8501, 0xd4ce, 0x2000 }, { 0x0501, 0xd4cd, 0x0000 }, { 0x0501, 0xd4cf, 0x0000 }, { 0x8901, 0xd4d2, 0x2000 }, { 0x0901, 0xd4d1, 0x0000 }, { 0x0901, 0xd4d3, 0x0000 }, { 0x8901, 0xd4dc, 0x4000 }, { 0x8901, 0xd4d8, 0x3000 }, { 0x8901, 0xd4d6, 0x2000 }, { 0x0901, 0xd4d5, 0x0000 }, { 0x0901, 0xd4d7, 0x0000 }, { 0x8901, 0xd4da, 0x2000 }, { 0x0901, 0xd4d9, 0x0000 }, { 0x0901, 0xd4db, 0x0000 }, { 0x8901, 0xd4e0, 0x3000 }, { 0x8901, 0xd4de, 0x2000 }, { 0x0901, 0xd4dd, 0x0000 }, { 0x0901, 0xd4df, 0x0000 }, { 0x8901, 0xd4e2, 0x2000 }, { 0x0901, 0xd4e1, 0x0000 }, { 0x0901, 0xd4e3, 0x0000 }, { 0x8501, 0xd529, 0x7000 }, { 0x8901, 0xd504, 0x6000 }, { 0x8501, 0xd4f4, 0x5000 }, { 0x8501, 0xd4ec, 0x4000 }, { 0x8901, 0xd4e8, 0x3000 }, { 0x8901, 0xd4e6, 0x2000 }, { 0x0901, 0xd4e5, 0x0000 }, { 0x0901, 0xd4e7, 0x0000 }, { 0x8501, 0xd4ea, 0x2000 }, { 0x0901, 0xd4e9, 0x0000 }, { 0x0501, 0xd4eb, 0x0000 }, { 0x8501, 0xd4f0, 0x3000 }, { 0x8501, 0xd4ee, 0x2000 }, { 0x0501, 0xd4ed, 0x0000 }, { 0x0501, 0xd4ef, 0x0000 }, { 0x8501, 0xd4f2, 0x2000 }, { 0x0501, 0xd4f1, 0x0000 }, { 0x0501, 0xd4f3, 0x0000 }, { 0x8501, 0xd4fc, 0x4000 }, { 0x8501, 0xd4f8, 0x3000 }, { 0x8501, 0xd4f6, 0x2000 }, { 0x0501, 0xd4f5, 0x0000 }, { 0x0501, 0xd4f7, 0x0000 }, { 0x8501, 0xd4fa, 0x2000 }, { 0x0501, 0xd4f9, 0x0000 }, { 0x0501, 0xd4fb, 0x0000 }, { 0x8501, 0xd500, 0x3000 }, { 0x8501, 0xd4fe, 0x2000 }, { 0x0501, 0xd4fd, 0x0000 }, { 0x0501, 0xd4ff, 0x0000 }, { 0x8501, 0xd502, 0x2000 }, { 0x0501, 0xd501, 0x0000 }, { 0x0501, 0xd503, 0x0000 }, { 0x8901, 0xd518, 0x5000 }, { 0x8901, 0xd50f, 0x4000 }, { 0x8901, 0xd509, 0x3000 }, { 0x8901, 0xd507, 0x2000 }, { 0x0901, 0xd505, 0x0000 }, { 0x0901, 0xd508, 0x0000 }, { 0x8901, 0xd50d, 0x2000 }, { 0x0901, 0xd50a, 0x0000 }, { 0x0901, 0xd50e, 0x0000 }, { 0x8901, 0xd513, 0x3000 }, { 0x8901, 0xd511, 0x2000 }, { 0x0901, 0xd510, 0x0000 }, { 0x0901, 0xd512, 0x0000 }, { 0x8901, 0xd516, 0x2000 }, { 0x0901, 0xd514, 0x0000 }, { 0x0901, 0xd517, 0x0000 }, { 0x8501, 0xd521, 0x4000 }, { 0x8901, 0xd51c, 0x3000 }, { 0x8901, 0xd51a, 0x2000 }, { 0x0901, 0xd519, 0x0000 }, { 0x0901, 0xd51b, 0x0000 }, { 0x8501, 0xd51f, 0x2000 }, { 0x0501, 0xd51e, 0x0000 }, { 0x0501, 0xd520, 0x0000 }, { 0x8501, 0xd525, 0x3000 }, { 0x8501, 0xd523, 0x2000 }, { 0x0501, 0xd522, 0x0000 }, { 0x0501, 0xd524, 0x0000 }, { 0x8501, 0xd527, 0x2000 }, { 0x0501, 0xd526, 0x0000 }, { 0x0501, 0xd528, 0x0000 }, { 0x8901, 0xd54f, 0x6000 }, { 0x8901, 0xd539, 0x5000 }, { 0x8501, 0xd531, 0x4000 }, { 0x8501, 0xd52d, 0x3000 }, { 0x8501, 0xd52b, 0x2000 }, { 0x0501, 0xd52a, 0x0000 }, { 0x0501, 0xd52c, 0x0000 }, { 0x8501, 0xd52f, 0x2000 }, { 0x0501, 0xd52e, 0x0000 }, { 0x0501, 0xd530, 0x0000 }, { 0x8501, 0xd535, 0x3000 }, { 0x8501, 0xd533, 0x2000 }, { 0x0501, 0xd532, 0x0000 }, { 0x0501, 0xd534, 0x0000 }, { 0x8501, 0xd537, 0x2000 }, { 0x0501, 0xd536, 0x0000 }, { 0x0901, 0xd538, 0x0000 }, { 0x8901, 0xd543, 0x4000 }, { 0x8901, 0xd53e, 0x3000 }, { 0x8901, 0xd53c, 0x2000 }, { 0x0901, 0xd53b, 0x0000 }, { 0x0901, 0xd53d, 0x0000 }, { 0x8901, 0xd541, 0x2000 }, { 0x0901, 0xd540, 0x0000 }, { 0x0901, 0xd542, 0x0000 }, { 0x8901, 0xd54b, 0x3000 }, { 0x8901, 0xd546, 0x2000 }, { 0x0901, 0xd544, 0x0000 }, { 0x0901, 0xd54a, 0x0000 }, { 0x8901, 0xd54d, 0x2000 }, { 0x0901, 0xd54c, 0x0000 }, { 0x0901, 0xd54e, 0x0000 }, { 0x8501, 0xd560, 0x5000 }, { 0x8501, 0xd558, 0x4000 }, { 0x8501, 0xd554, 0x3000 }, { 0x8501, 0xd552, 0x2000 }, { 0x0901, 0xd550, 0x0000 }, { 0x0501, 0xd553, 0x0000 }, { 0x8501, 0xd556, 0x2000 }, { 0x0501, 0xd555, 0x0000 }, { 0x0501, 0xd557, 0x0000 }, { 0x8501, 0xd55c, 0x3000 }, { 0x8501, 0xd55a, 0x2000 }, { 0x0501, 0xd559, 0x0000 }, { 0x0501, 0xd55b, 0x0000 }, { 0x8501, 0xd55e, 0x2000 }, { 0x0501, 0xd55d, 0x0000 }, { 0x0501, 0xd55f, 0x0000 }, { 0x8501, 0xd568, 0x4000 }, { 0x8501, 0xd564, 0x3000 }, { 0x8501, 0xd562, 0x2000 }, { 0x0501, 0xd561, 0x0000 }, { 0x0501, 0xd563, 0x0000 }, { 0x8501, 0xd566, 0x2000 }, { 0x0501, 0xd565, 0x0000 }, { 0x0501, 0xd567, 0x0000 }, { 0x8901, 0xd56c, 0x3000 }, { 0x8501, 0xd56a, 0x2000 }, { 0x0501, 0xd569, 0x0000 }, { 0x0501, 0xd56b, 0x0000 }, { 0x8901, 0xd56e, 0x2000 }, { 0x0901, 0xd56d, 0x0000 }, { 0x0901, 0xd56f, 0x0000 }, { 0x8501, 0xd5f0, 0x8000 }, { 0x8901, 0xd5b0, 0x7000 }, { 0x8501, 0xd590, 0x6000 }, { 0x8901, 0xd580, 0x5000 }, { 0x8901, 0xd578, 0x4000 }, { 0x8901, 0xd574, 0x3000 }, { 0x8901, 0xd572, 0x2000 }, { 0x0901, 0xd571, 0x0000 }, { 0x0901, 0xd573, 0x0000 }, { 0x8901, 0xd576, 0x2000 }, { 0x0901, 0xd575, 0x0000 }, { 0x0901, 0xd577, 0x0000 }, { 0x8901, 0xd57c, 0x3000 }, { 0x8901, 0xd57a, 0x2000 }, { 0x0901, 0xd579, 0x0000 }, { 0x0901, 0xd57b, 0x0000 }, { 0x8901, 0xd57e, 0x2000 }, { 0x0901, 0xd57d, 0x0000 }, { 0x0901, 0xd57f, 0x0000 }, { 0x8501, 0xd588, 0x4000 }, { 0x8901, 0xd584, 0x3000 }, { 0x8901, 0xd582, 0x2000 }, { 0x0901, 0xd581, 0x0000 }, { 0x0901, 0xd583, 0x0000 }, { 0x8501, 0xd586, 0x2000 }, { 0x0901, 0xd585, 0x0000 }, { 0x0501, 0xd587, 0x0000 }, { 0x8501, 0xd58c, 0x3000 }, { 0x8501, 0xd58a, 0x2000 }, { 0x0501, 0xd589, 0x0000 }, { 0x0501, 0xd58b, 0x0000 }, { 0x8501, 0xd58e, 0x2000 }, { 0x0501, 0xd58d, 0x0000 }, { 0x0501, 0xd58f, 0x0000 }, { 0x8901, 0xd5a0, 0x5000 }, { 0x8501, 0xd598, 0x4000 }, { 0x8501, 0xd594, 0x3000 }, { 0x8501, 0xd592, 0x2000 }, { 0x0501, 0xd591, 0x0000 }, { 0x0501, 0xd593, 0x0000 }, { 0x8501, 0xd596, 0x2000 }, { 0x0501, 0xd595, 0x0000 }, { 0x0501, 0xd597, 0x0000 }, { 0x8501, 0xd59c, 0x3000 }, { 0x8501, 0xd59a, 0x2000 }, { 0x0501, 0xd599, 0x0000 }, { 0x0501, 0xd59b, 0x0000 }, { 0x8501, 0xd59e, 0x2000 }, { 0x0501, 0xd59d, 0x0000 }, { 0x0501, 0xd59f, 0x0000 }, { 0x8901, 0xd5a8, 0x4000 }, { 0x8901, 0xd5a4, 0x3000 }, { 0x8901, 0xd5a2, 0x2000 }, { 0x0901, 0xd5a1, 0x0000 }, { 0x0901, 0xd5a3, 0x0000 }, { 0x8901, 0xd5a6, 0x2000 }, { 0x0901, 0xd5a5, 0x0000 }, { 0x0901, 0xd5a7, 0x0000 }, { 0x8901, 0xd5ac, 0x3000 }, { 0x8901, 0xd5aa, 0x2000 }, { 0x0901, 0xd5a9, 0x0000 }, { 0x0901, 0xd5ab, 0x0000 }, { 0x8901, 0xd5ae, 0x2000 }, { 0x0901, 0xd5ad, 0x0000 }, { 0x0901, 0xd5af, 0x0000 }, { 0x8501, 0xd5d0, 0x6000 }, { 0x8501, 0xd5c0, 0x5000 }, { 0x8901, 0xd5b8, 0x4000 }, { 0x8901, 0xd5b4, 0x3000 }, { 0x8901, 0xd5b2, 0x2000 }, { 0x0901, 0xd5b1, 0x0000 }, { 0x0901, 0xd5b3, 0x0000 }, { 0x8901, 0xd5b6, 0x2000 }, { 0x0901, 0xd5b5, 0x0000 }, { 0x0901, 0xd5b7, 0x0000 }, { 0x8501, 0xd5bc, 0x3000 }, { 0x8501, 0xd5ba, 0x2000 }, { 0x0901, 0xd5b9, 0x0000 }, { 0x0501, 0xd5bb, 0x0000 }, { 0x8501, 0xd5be, 0x2000 }, { 0x0501, 0xd5bd, 0x0000 }, { 0x0501, 0xd5bf, 0x0000 }, { 0x8501, 0xd5c8, 0x4000 }, { 0x8501, 0xd5c4, 0x3000 }, { 0x8501, 0xd5c2, 0x2000 }, { 0x0501, 0xd5c1, 0x0000 }, { 0x0501, 0xd5c3, 0x0000 }, { 0x8501, 0xd5c6, 0x2000 }, { 0x0501, 0xd5c5, 0x0000 }, { 0x0501, 0xd5c7, 0x0000 }, { 0x8501, 0xd5cc, 0x3000 }, { 0x8501, 0xd5ca, 0x2000 }, { 0x0501, 0xd5c9, 0x0000 }, { 0x0501, 0xd5cb, 0x0000 }, { 0x8501, 0xd5ce, 0x2000 }, { 0x0501, 0xd5cd, 0x0000 }, { 0x0501, 0xd5cf, 0x0000 }, { 0x8901, 0xd5e0, 0x5000 }, { 0x8901, 0xd5d8, 0x4000 }, { 0x8901, 0xd5d4, 0x3000 }, { 0x8501, 0xd5d2, 0x2000 }, { 0x0501, 0xd5d1, 0x0000 }, { 0x0501, 0xd5d3, 0x0000 }, { 0x8901, 0xd5d6, 0x2000 }, { 0x0901, 0xd5d5, 0x0000 }, { 0x0901, 0xd5d7, 0x0000 }, { 0x8901, 0xd5dc, 0x3000 }, { 0x8901, 0xd5da, 0x2000 }, { 0x0901, 0xd5d9, 0x0000 }, { 0x0901, 0xd5db, 0x0000 }, { 0x8901, 0xd5de, 0x2000 }, { 0x0901, 0xd5dd, 0x0000 }, { 0x0901, 0xd5df, 0x0000 }, { 0x8901, 0xd5e8, 0x4000 }, { 0x8901, 0xd5e4, 0x3000 }, { 0x8901, 0xd5e2, 0x2000 }, { 0x0901, 0xd5e1, 0x0000 }, { 0x0901, 0xd5e3, 0x0000 }, { 0x8901, 0xd5e6, 0x2000 }, { 0x0901, 0xd5e5, 0x0000 }, { 0x0901, 0xd5e7, 0x0000 }, { 0x8901, 0xd5ec, 0x3000 }, { 0x8901, 0xd5ea, 0x2000 }, { 0x0901, 0xd5e9, 0x0000 }, { 0x0901, 0xd5eb, 0x0000 }, { 0x8501, 0xd5ee, 0x2000 }, { 0x0901, 0xd5ed, 0x0000 }, { 0x0501, 0xd5ef, 0x0000 }, { 0x8501, 0xd630, 0x7000 }, { 0x8901, 0xd610, 0x6000 }, { 0x8501, 0xd600, 0x5000 }, { 0x8501, 0xd5f8, 0x4000 }, { 0x8501, 0xd5f4, 0x3000 }, { 0x8501, 0xd5f2, 0x2000 }, { 0x0501, 0xd5f1, 0x0000 }, { 0x0501, 0xd5f3, 0x0000 }, { 0x8501, 0xd5f6, 0x2000 }, { 0x0501, 0xd5f5, 0x0000 }, { 0x0501, 0xd5f7, 0x0000 }, { 0x8501, 0xd5fc, 0x3000 }, { 0x8501, 0xd5fa, 0x2000 }, { 0x0501, 0xd5f9, 0x0000 }, { 0x0501, 0xd5fb, 0x0000 }, { 0x8501, 0xd5fe, 0x2000 }, { 0x0501, 0xd5fd, 0x0000 }, { 0x0501, 0xd5ff, 0x0000 }, { 0x8901, 0xd608, 0x4000 }, { 0x8501, 0xd604, 0x3000 }, { 0x8501, 0xd602, 0x2000 }, { 0x0501, 0xd601, 0x0000 }, { 0x0501, 0xd603, 0x0000 }, { 0x8501, 0xd606, 0x2000 }, { 0x0501, 0xd605, 0x0000 }, { 0x0501, 0xd607, 0x0000 }, { 0x8901, 0xd60c, 0x3000 }, { 0x8901, 0xd60a, 0x2000 }, { 0x0901, 0xd609, 0x0000 }, { 0x0901, 0xd60b, 0x0000 }, { 0x8901, 0xd60e, 0x2000 }, { 0x0901, 0xd60d, 0x0000 }, { 0x0901, 0xd60f, 0x0000 }, { 0x8901, 0xd620, 0x5000 }, { 0x8901, 0xd618, 0x4000 }, { 0x8901, 0xd614, 0x3000 }, { 0x8901, 0xd612, 0x2000 }, { 0x0901, 0xd611, 0x0000 }, { 0x0901, 0xd613, 0x0000 }, { 0x8901, 0xd616, 0x2000 }, { 0x0901, 0xd615, 0x0000 }, { 0x0901, 0xd617, 0x0000 }, { 0x8901, 0xd61c, 0x3000 }, { 0x8901, 0xd61a, 0x2000 }, { 0x0901, 0xd619, 0x0000 }, { 0x0901, 0xd61b, 0x0000 }, { 0x8901, 0xd61e, 0x2000 }, { 0x0901, 0xd61d, 0x0000 }, { 0x0901, 0xd61f, 0x0000 }, { 0x8501, 0xd628, 0x4000 }, { 0x8501, 0xd624, 0x3000 }, { 0x8501, 0xd622, 0x2000 }, { 0x0901, 0xd621, 0x0000 }, { 0x0501, 0xd623, 0x0000 }, { 0x8501, 0xd626, 0x2000 }, { 0x0501, 0xd625, 0x0000 }, { 0x0501, 0xd627, 0x0000 }, { 0x8501, 0xd62c, 0x3000 }, { 0x8501, 0xd62a, 0x2000 }, { 0x0501, 0xd629, 0x0000 }, { 0x0501, 0xd62b, 0x0000 }, { 0x8501, 0xd62e, 0x2000 }, { 0x0501, 0xd62d, 0x0000 }, { 0x0501, 0xd62f, 0x0000 }, { 0x8901, 0xd650, 0x6000 }, { 0x8901, 0xd640, 0x5000 }, { 0x8501, 0xd638, 0x4000 }, { 0x8501, 0xd634, 0x3000 }, { 0x8501, 0xd632, 0x2000 }, { 0x0501, 0xd631, 0x0000 }, { 0x0501, 0xd633, 0x0000 }, { 0x8501, 0xd636, 0x2000 }, { 0x0501, 0xd635, 0x0000 }, { 0x0501, 0xd637, 0x0000 }, { 0x8901, 0xd63c, 0x3000 }, { 0x8501, 0xd63a, 0x2000 }, { 0x0501, 0xd639, 0x0000 }, { 0x0501, 0xd63b, 0x0000 }, { 0x8901, 0xd63e, 0x2000 }, { 0x0901, 0xd63d, 0x0000 }, { 0x0901, 0xd63f, 0x0000 }, { 0x8901, 0xd648, 0x4000 }, { 0x8901, 0xd644, 0x3000 }, { 0x8901, 0xd642, 0x2000 }, { 0x0901, 0xd641, 0x0000 }, { 0x0901, 0xd643, 0x0000 }, { 0x8901, 0xd646, 0x2000 }, { 0x0901, 0xd645, 0x0000 }, { 0x0901, 0xd647, 0x0000 }, { 0x8901, 0xd64c, 0x3000 }, { 0x8901, 0xd64a, 0x2000 }, { 0x0901, 0xd649, 0x0000 }, { 0x0901, 0xd64b, 0x0000 }, { 0x8901, 0xd64e, 0x2000 }, { 0x0901, 0xd64d, 0x0000 }, { 0x0901, 0xd64f, 0x0000 }, { 0x8501, 0xd660, 0x5000 }, { 0x8501, 0xd658, 0x4000 }, { 0x8901, 0xd654, 0x3000 }, { 0x8901, 0xd652, 0x2000 }, { 0x0901, 0xd651, 0x0000 }, { 0x0901, 0xd653, 0x0000 }, { 0x8501, 0xd656, 0x2000 }, { 0x0901, 0xd655, 0x0000 }, { 0x0501, 0xd657, 0x0000 }, { 0x8501, 0xd65c, 0x3000 }, { 0x8501, 0xd65a, 0x2000 }, { 0x0501, 0xd659, 0x0000 }, { 0x0501, 0xd65b, 0x0000 }, { 0x8501, 0xd65e, 0x2000 }, { 0x0501, 0xd65d, 0x0000 }, { 0x0501, 0xd65f, 0x0000 }, { 0x8501, 0xd668, 0x4000 }, { 0x8501, 0xd664, 0x3000 }, { 0x8501, 0xd662, 0x2000 }, { 0x0501, 0xd661, 0x0000 }, { 0x0501, 0xd663, 0x0000 }, { 0x8501, 0xd666, 0x2000 }, { 0x0501, 0xd665, 0x0000 }, { 0x0501, 0xd667, 0x0000 }, { 0x8501, 0xd66c, 0x3000 }, { 0x8501, 0xd66a, 0x2000 }, { 0x0501, 0xd669, 0x0000 }, { 0x0501, 0xd66b, 0x0000 }, { 0x8501, 0xd66e, 0x2000 }, { 0x0501, 0xd66d, 0x0000 }, { 0x0501, 0xd66f, 0x0000 }, { 0x8501, 0xd774, 0x9000 }, { 0x8901, 0xd6f4, 0x8000 }, { 0x8901, 0xd6b4, 0x7000 }, { 0x8501, 0xd690, 0x6000 }, { 0x8901, 0xd680, 0x5000 }, { 0x8901, 0xd678, 0x4000 }, { 0x8901, 0xd674, 0x3000 }, { 0x8901, 0xd672, 0x2000 }, { 0x0901, 0xd671, 0x0000 }, { 0x0901, 0xd673, 0x0000 }, { 0x8901, 0xd676, 0x2000 }, { 0x0901, 0xd675, 0x0000 }, { 0x0901, 0xd677, 0x0000 }, { 0x8901, 0xd67c, 0x3000 }, { 0x8901, 0xd67a, 0x2000 }, { 0x0901, 0xd679, 0x0000 }, { 0x0901, 0xd67b, 0x0000 }, { 0x8901, 0xd67e, 0x2000 }, { 0x0901, 0xd67d, 0x0000 }, { 0x0901, 0xd67f, 0x0000 }, { 0x8901, 0xd688, 0x4000 }, { 0x8901, 0xd684, 0x3000 }, { 0x8901, 0xd682, 0x2000 }, { 0x0901, 0xd681, 0x0000 }, { 0x0901, 0xd683, 0x0000 }, { 0x8901, 0xd686, 0x2000 }, { 0x0901, 0xd685, 0x0000 }, { 0x0901, 0xd687, 0x0000 }, { 0x8501, 0xd68c, 0x3000 }, { 0x8501, 0xd68a, 0x2000 }, { 0x0901, 0xd689, 0x0000 }, { 0x0501, 0xd68b, 0x0000 }, { 0x8501, 0xd68e, 0x2000 }, { 0x0501, 0xd68d, 0x0000 }, { 0x0501, 0xd68f, 0x0000 }, { 0x8501, 0xd6a0, 0x5000 }, { 0x8501, 0xd698, 0x4000 }, { 0x8501, 0xd694, 0x3000 }, { 0x8501, 0xd692, 0x2000 }, { 0x0501, 0xd691, 0x0000 }, { 0x0501, 0xd693, 0x0000 }, { 0x8501, 0xd696, 0x2000 }, { 0x0501, 0xd695, 0x0000 }, { 0x0501, 0xd697, 0x0000 }, { 0x8501, 0xd69c, 0x3000 }, { 0x8501, 0xd69a, 0x2000 }, { 0x0501, 0xd699, 0x0000 }, { 0x0501, 0xd69b, 0x0000 }, { 0x8501, 0xd69e, 0x2000 }, { 0x0501, 0xd69d, 0x0000 }, { 0x0501, 0xd69f, 0x0000 }, { 0x8901, 0xd6ac, 0x4000 }, { 0x8901, 0xd6a8, 0x3000 }, { 0x8501, 0xd6a2, 0x2000 }, { 0x0501, 0xd6a1, 0x0000 }, { 0x0501, 0xd6a3, 0x0000 }, { 0x8901, 0xd6aa, 0x2000 }, { 0x0901, 0xd6a9, 0x0000 }, { 0x0901, 0xd6ab, 0x0000 }, { 0x8901, 0xd6b0, 0x3000 }, { 0x8901, 0xd6ae, 0x2000 }, { 0x0901, 0xd6ad, 0x0000 }, { 0x0901, 0xd6af, 0x0000 }, { 0x8901, 0xd6b2, 0x2000 }, { 0x0901, 0xd6b1, 0x0000 }, { 0x0901, 0xd6b3, 0x0000 }, { 0x8501, 0xd6d4, 0x6000 }, { 0x8501, 0xd6c4, 0x5000 }, { 0x8901, 0xd6bc, 0x4000 }, { 0x8901, 0xd6b8, 0x3000 }, { 0x8901, 0xd6b6, 0x2000 }, { 0x0901, 0xd6b5, 0x0000 }, { 0x0901, 0xd6b7, 0x0000 }, { 0x8901, 0xd6ba, 0x2000 }, { 0x0901, 0xd6b9, 0x0000 }, { 0x0901, 0xd6bb, 0x0000 }, { 0x8901, 0xd6c0, 0x3000 }, { 0x8901, 0xd6be, 0x2000 }, { 0x0901, 0xd6bd, 0x0000 }, { 0x0901, 0xd6bf, 0x0000 }, { 0x8501, 0xd6c2, 0x2000 }, { 0x1901, 0xd6c1, 0x0000 }, { 0x0501, 0xd6c3, 0x0000 }, { 0x8501, 0xd6cc, 0x4000 }, { 0x8501, 0xd6c8, 0x3000 }, { 0x8501, 0xd6c6, 0x2000 }, { 0x0501, 0xd6c5, 0x0000 }, { 0x0501, 0xd6c7, 0x0000 }, { 0x8501, 0xd6ca, 0x2000 }, { 0x0501, 0xd6c9, 0x0000 }, { 0x0501, 0xd6cb, 0x0000 }, { 0x8501, 0xd6d0, 0x3000 }, { 0x8501, 0xd6ce, 0x2000 }, { 0x0501, 0xd6cd, 0x0000 }, { 0x0501, 0xd6cf, 0x0000 }, { 0x8501, 0xd6d2, 0x2000 }, { 0x0501, 0xd6d1, 0x0000 }, { 0x0501, 0xd6d3, 0x0000 }, { 0x8901, 0xd6e4, 0x5000 }, { 0x8501, 0xd6dc, 0x4000 }, { 0x8501, 0xd6d8, 0x3000 }, { 0x8501, 0xd6d6, 0x2000 }, { 0x0501, 0xd6d5, 0x0000 }, { 0x0501, 0xd6d7, 0x0000 }, { 0x8501, 0xd6da, 0x2000 }, { 0x0501, 0xd6d9, 0x0000 }, { 0x1901, 0xd6db, 0x0000 }, { 0x8501, 0xd6e0, 0x3000 }, { 0x8501, 0xd6de, 0x2000 }, { 0x0501, 0xd6dd, 0x0000 }, { 0x0501, 0xd6df, 0x0000 }, { 0x8901, 0xd6e2, 0x2000 }, { 0x0501, 0xd6e1, 0x0000 }, { 0x0901, 0xd6e3, 0x0000 }, { 0x8901, 0xd6ec, 0x4000 }, { 0x8901, 0xd6e8, 0x3000 }, { 0x8901, 0xd6e6, 0x2000 }, { 0x0901, 0xd6e5, 0x0000 }, { 0x0901, 0xd6e7, 0x0000 }, { 0x8901, 0xd6ea, 0x2000 }, { 0x0901, 0xd6e9, 0x0000 }, { 0x0901, 0xd6eb, 0x0000 }, { 0x8901, 0xd6f0, 0x3000 }, { 0x8901, 0xd6ee, 0x2000 }, { 0x0901, 0xd6ed, 0x0000 }, { 0x0901, 0xd6ef, 0x0000 }, { 0x8901, 0xd6f2, 0x2000 }, { 0x0901, 0xd6f1, 0x0000 }, { 0x0901, 0xd6f3, 0x0000 }, { 0x8901, 0xd734, 0x7000 }, { 0x8501, 0xd714, 0x6000 }, { 0x8501, 0xd704, 0x5000 }, { 0x8501, 0xd6fc, 0x4000 }, { 0x8901, 0xd6f8, 0x3000 }, { 0x8901, 0xd6f6, 0x2000 }, { 0x0901, 0xd6f5, 0x0000 }, { 0x0901, 0xd6f7, 0x0000 }, { 0x8901, 0xd6fa, 0x2000 }, { 0x0901, 0xd6f9, 0x0000 }, { 0x1901, 0xd6fb, 0x0000 }, { 0x8501, 0xd700, 0x3000 }, { 0x8501, 0xd6fe, 0x2000 }, { 0x0501, 0xd6fd, 0x0000 }, { 0x0501, 0xd6ff, 0x0000 }, { 0x8501, 0xd702, 0x2000 }, { 0x0501, 0xd701, 0x0000 }, { 0x0501, 0xd703, 0x0000 }, { 0x8501, 0xd70c, 0x4000 }, { 0x8501, 0xd708, 0x3000 }, { 0x8501, 0xd706, 0x2000 }, { 0x0501, 0xd705, 0x0000 }, { 0x0501, 0xd707, 0x0000 }, { 0x8501, 0xd70a, 0x2000 }, { 0x0501, 0xd709, 0x0000 }, { 0x0501, 0xd70b, 0x0000 }, { 0x8501, 0xd710, 0x3000 }, { 0x8501, 0xd70e, 0x2000 }, { 0x0501, 0xd70d, 0x0000 }, { 0x0501, 0xd70f, 0x0000 }, { 0x8501, 0xd712, 0x2000 }, { 0x0501, 0xd711, 0x0000 }, { 0x0501, 0xd713, 0x0000 }, { 0x8901, 0xd724, 0x5000 }, { 0x8901, 0xd71c, 0x4000 }, { 0x8501, 0xd718, 0x3000 }, { 0x8501, 0xd716, 0x2000 }, { 0x1901, 0xd715, 0x0000 }, { 0x0501, 0xd717, 0x0000 }, { 0x8501, 0xd71a, 0x2000 }, { 0x0501, 0xd719, 0x0000 }, { 0x0501, 0xd71b, 0x0000 }, { 0x8901, 0xd720, 0x3000 }, { 0x8901, 0xd71e, 0x2000 }, { 0x0901, 0xd71d, 0x0000 }, { 0x0901, 0xd71f, 0x0000 }, { 0x8901, 0xd722, 0x2000 }, { 0x0901, 0xd721, 0x0000 }, { 0x0901, 0xd723, 0x0000 }, { 0x8901, 0xd72c, 0x4000 }, { 0x8901, 0xd728, 0x3000 }, { 0x8901, 0xd726, 0x2000 }, { 0x0901, 0xd725, 0x0000 }, { 0x0901, 0xd727, 0x0000 }, { 0x8901, 0xd72a, 0x2000 }, { 0x0901, 0xd729, 0x0000 }, { 0x0901, 0xd72b, 0x0000 }, { 0x8901, 0xd730, 0x3000 }, { 0x8901, 0xd72e, 0x2000 }, { 0x0901, 0xd72d, 0x0000 }, { 0x0901, 0xd72f, 0x0000 }, { 0x8901, 0xd732, 0x2000 }, { 0x0901, 0xd731, 0x0000 }, { 0x0901, 0xd733, 0x0000 }, { 0x8501, 0xd754, 0x6000 }, { 0x8501, 0xd744, 0x5000 }, { 0x8501, 0xd73c, 0x4000 }, { 0x8501, 0xd738, 0x3000 }, { 0x8501, 0xd736, 0x2000 }, { 0x1901, 0xd735, 0x0000 }, { 0x0501, 0xd737, 0x0000 }, { 0x8501, 0xd73a, 0x2000 }, { 0x0501, 0xd739, 0x0000 }, { 0x0501, 0xd73b, 0x0000 }, { 0x8501, 0xd740, 0x3000 }, { 0x8501, 0xd73e, 0x2000 }, { 0x0501, 0xd73d, 0x0000 }, { 0x0501, 0xd73f, 0x0000 }, { 0x8501, 0xd742, 0x2000 }, { 0x0501, 0xd741, 0x0000 }, { 0x0501, 0xd743, 0x0000 }, { 0x8501, 0xd74c, 0x4000 }, { 0x8501, 0xd748, 0x3000 }, { 0x8501, 0xd746, 0x2000 }, { 0x0501, 0xd745, 0x0000 }, { 0x0501, 0xd747, 0x0000 }, { 0x8501, 0xd74a, 0x2000 }, { 0x0501, 0xd749, 0x0000 }, { 0x0501, 0xd74b, 0x0000 }, { 0x8501, 0xd750, 0x3000 }, { 0x8501, 0xd74e, 0x2000 }, { 0x0501, 0xd74d, 0x0000 }, { 0x1901, 0xd74f, 0x0000 }, { 0x8501, 0xd752, 0x2000 }, { 0x0501, 0xd751, 0x0000 }, { 0x0501, 0xd753, 0x0000 }, { 0x8901, 0xd764, 0x5000 }, { 0x8901, 0xd75c, 0x4000 }, { 0x8901, 0xd758, 0x3000 }, { 0x8901, 0xd756, 0x2000 }, { 0x0501, 0xd755, 0x0000 }, { 0x0901, 0xd757, 0x0000 }, { 0x8901, 0xd75a, 0x2000 }, { 0x0901, 0xd759, 0x0000 }, { 0x0901, 0xd75b, 0x0000 }, { 0x8901, 0xd760, 0x3000 }, { 0x8901, 0xd75e, 0x2000 }, { 0x0901, 0xd75d, 0x0000 }, { 0x0901, 0xd75f, 0x0000 }, { 0x8901, 0xd762, 0x2000 }, { 0x0901, 0xd761, 0x0000 }, { 0x0901, 0xd763, 0x0000 }, { 0x8901, 0xd76c, 0x4000 }, { 0x8901, 0xd768, 0x3000 }, { 0x8901, 0xd766, 0x2000 }, { 0x0901, 0xd765, 0x0000 }, { 0x0901, 0xd767, 0x0000 }, { 0x8901, 0xd76a, 0x2000 }, { 0x0901, 0xd769, 0x0000 }, { 0x0901, 0xd76b, 0x0000 }, { 0x8501, 0xd770, 0x3000 }, { 0x8901, 0xd76e, 0x2000 }, { 0x0901, 0xd76d, 0x0000 }, { 0x1901, 0xd76f, 0x0000 }, { 0x8501, 0xd772, 0x2000 }, { 0x0501, 0xd771, 0x0000 }, { 0x0501, 0xd773, 0x0000 }, { 0x8d01, 0xd7f8, 0x8000 }, { 0x8501, 0xd7b4, 0x7000 }, { 0x8901, 0xd794, 0x6000 }, { 0x8501, 0xd784, 0x5000 }, { 0x8501, 0xd77c, 0x4000 }, { 0x8501, 0xd778, 0x3000 }, { 0x8501, 0xd776, 0x2000 }, { 0x0501, 0xd775, 0x0000 }, { 0x0501, 0xd777, 0x0000 }, { 0x8501, 0xd77a, 0x2000 }, { 0x0501, 0xd779, 0x0000 }, { 0x0501, 0xd77b, 0x0000 }, { 0x8501, 0xd780, 0x3000 }, { 0x8501, 0xd77e, 0x2000 }, { 0x0501, 0xd77d, 0x0000 }, { 0x0501, 0xd77f, 0x0000 }, { 0x8501, 0xd782, 0x2000 }, { 0x0501, 0xd781, 0x0000 }, { 0x0501, 0xd783, 0x0000 }, { 0x8501, 0xd78c, 0x4000 }, { 0x8501, 0xd788, 0x3000 }, { 0x8501, 0xd786, 0x2000 }, { 0x0501, 0xd785, 0x0000 }, { 0x0501, 0xd787, 0x0000 }, { 0x8501, 0xd78a, 0x2000 }, { 0x1901, 0xd789, 0x0000 }, { 0x0501, 0xd78b, 0x0000 }, { 0x8901, 0xd790, 0x3000 }, { 0x8501, 0xd78e, 0x2000 }, { 0x0501, 0xd78d, 0x0000 }, { 0x0501, 0xd78f, 0x0000 }, { 0x8901, 0xd792, 0x2000 }, { 0x0901, 0xd791, 0x0000 }, { 0x0901, 0xd793, 0x0000 }, { 0x8901, 0xd7a4, 0x5000 }, { 0x8901, 0xd79c, 0x4000 }, { 0x8901, 0xd798, 0x3000 }, { 0x8901, 0xd796, 0x2000 }, { 0x0901, 0xd795, 0x0000 }, { 0x0901, 0xd797, 0x0000 }, { 0x8901, 0xd79a, 0x2000 }, { 0x0901, 0xd799, 0x0000 }, { 0x0901, 0xd79b, 0x0000 }, { 0x8901, 0xd7a0, 0x3000 }, { 0x8901, 0xd79e, 0x2000 }, { 0x0901, 0xd79d, 0x0000 }, { 0x0901, 0xd79f, 0x0000 }, { 0x8901, 0xd7a2, 0x2000 }, { 0x0901, 0xd7a1, 0x0000 }, { 0x0901, 0xd7a3, 0x0000 }, { 0x8501, 0xd7ac, 0x4000 }, { 0x8901, 0xd7a8, 0x3000 }, { 0x8901, 0xd7a6, 0x2000 }, { 0x0901, 0xd7a5, 0x0000 }, { 0x0901, 0xd7a7, 0x0000 }, { 0x8501, 0xd7aa, 0x2000 }, { 0x1901, 0xd7a9, 0x0000 }, { 0x0501, 0xd7ab, 0x0000 }, { 0x8501, 0xd7b0, 0x3000 }, { 0x8501, 0xd7ae, 0x2000 }, { 0x0501, 0xd7ad, 0x0000 }, { 0x0501, 0xd7af, 0x0000 }, { 0x8501, 0xd7b2, 0x2000 }, { 0x0501, 0xd7b1, 0x0000 }, { 0x0501, 0xd7b3, 0x0000 }, { 0x8d01, 0xd7d8, 0x6000 }, { 0x8501, 0xd7c4, 0x5000 }, { 0x8501, 0xd7bc, 0x4000 }, { 0x8501, 0xd7b8, 0x3000 }, { 0x8501, 0xd7b6, 0x2000 }, { 0x0501, 0xd7b5, 0x0000 }, { 0x0501, 0xd7b7, 0x0000 }, { 0x8501, 0xd7ba, 0x2000 }, { 0x0501, 0xd7b9, 0x0000 }, { 0x0501, 0xd7bb, 0x0000 }, { 0x8501, 0xd7c0, 0x3000 }, { 0x8501, 0xd7be, 0x2000 }, { 0x0501, 0xd7bd, 0x0000 }, { 0x0501, 0xd7bf, 0x0000 }, { 0x8501, 0xd7c2, 0x2000 }, { 0x0501, 0xd7c1, 0x0000 }, { 0x1901, 0xd7c3, 0x0000 }, { 0x8d01, 0xd7d0, 0x4000 }, { 0x8501, 0xd7c8, 0x3000 }, { 0x8501, 0xd7c6, 0x2000 }, { 0x0501, 0xd7c5, 0x0000 }, { 0x0501, 0xd7c7, 0x0000 }, { 0x8d01, 0xd7ce, 0x2000 }, { 0x0501, 0xd7c9, 0x0000 }, { 0x0d01, 0xd7cf, 0x0000 }, { 0x8d01, 0xd7d4, 0x3000 }, { 0x8d01, 0xd7d2, 0x2000 }, { 0x0d01, 0xd7d1, 0x0000 }, { 0x0d01, 0xd7d3, 0x0000 }, { 0x8d01, 0xd7d6, 0x2000 }, { 0x0d01, 0xd7d5, 0x0000 }, { 0x0d01, 0xd7d7, 0x0000 }, { 0x8d01, 0xd7e8, 0x5000 }, { 0x8d01, 0xd7e0, 0x4000 }, { 0x8d01, 0xd7dc, 0x3000 }, { 0x8d01, 0xd7da, 0x2000 }, { 0x0d01, 0xd7d9, 0x0000 }, { 0x0d01, 0xd7db, 0x0000 }, { 0x8d01, 0xd7de, 0x2000 }, { 0x0d01, 0xd7dd, 0x0000 }, { 0x0d01, 0xd7df, 0x0000 }, { 0x8d01, 0xd7e4, 0x3000 }, { 0x8d01, 0xd7e2, 0x2000 }, { 0x0d01, 0xd7e1, 0x0000 }, { 0x0d01, 0xd7e3, 0x0000 }, { 0x8d01, 0xd7e6, 0x2000 }, { 0x0d01, 0xd7e5, 0x0000 }, { 0x0d01, 0xd7e7, 0x0000 }, { 0x8d01, 0xd7f0, 0x4000 }, { 0x8d01, 0xd7ec, 0x3000 }, { 0x8d01, 0xd7ea, 0x2000 }, { 0x0d01, 0xd7e9, 0x0000 }, { 0x0d01, 0xd7eb, 0x0000 }, { 0x8d01, 0xd7ee, 0x2000 }, { 0x0d01, 0xd7ed, 0x0000 }, { 0x0d01, 0xd7ef, 0x0000 }, { 0x8d01, 0xd7f4, 0x3000 }, { 0x8d01, 0xd7f2, 0x2000 }, { 0x0d01, 0xd7f1, 0x0000 }, { 0x0d01, 0xd7f3, 0x0000 }, { 0x8d01, 0xd7f6, 0x2000 }, { 0x0d01, 0xd7f5, 0x0000 }, { 0x0d01, 0xd7f7, 0x0000 }, { 0x8702, 0xf836, 0x7000 }, { 0x8702, 0xf816, 0x6000 }, { 0x8702, 0xf806, 0x5000 }, { 0x8702, 0x0000, 0x4000 }, { 0x8d01, 0xd7fc, 0x3000 }, { 0x8d01, 0xd7fa, 0x2000 }, { 0x0d01, 0xd7f9, 0x0000 }, { 0x0d01, 0xd7fb, 0x0000 }, { 0x8d01, 0xd7fe, 0x2000 }, { 0x0d01, 0xd7fd, 0x0000 }, { 0x0d01, 0xd7ff, 0x0000 }, { 0x8702, 0xf802, 0x3000 }, { 0x8702, 0xf800, 0x2000 }, { 0x0702, 0xa6d6, 0x0000 }, { 0x0702, 0xf801, 0x0000 }, { 0x8702, 0xf804, 0x2000 }, { 0x0702, 0xf803, 0x0000 }, { 0x0702, 0xf805, 0x0000 }, { 0x8702, 0xf80e, 0x4000 }, { 0x8702, 0xf80a, 0x3000 }, { 0x8702, 0xf808, 0x2000 }, { 0x0702, 0xf807, 0x0000 }, { 0x0702, 0xf809, 0x0000 }, { 0x8702, 0xf80c, 0x2000 }, { 0x0702, 0xf80b, 0x0000 }, { 0x0702, 0xf80d, 0x0000 }, { 0x8702, 0xf812, 0x3000 }, { 0x8702, 0xf810, 0x2000 }, { 0x0702, 0xf80f, 0x0000 }, { 0x0702, 0xf811, 0x0000 }, { 0x8702, 0xf814, 0x2000 }, { 0x0702, 0xf813, 0x0000 }, { 0x0702, 0xf815, 0x0000 }, { 0x8702, 0xf826, 0x5000 }, { 0x8702, 0xf81e, 0x4000 }, { 0x8702, 0xf81a, 0x3000 }, { 0x8702, 0xf818, 0x2000 }, { 0x0702, 0xf817, 0x0000 }, { 0x0702, 0xf819, 0x0000 }, { 0x8702, 0xf81c, 0x2000 }, { 0x0702, 0xf81b, 0x0000 }, { 0x0702, 0xf81d, 0x0000 }, { 0x8702, 0xf822, 0x3000 }, { 0x8702, 0xf820, 0x2000 }, { 0x0702, 0xf81f, 0x0000 }, { 0x0702, 0xf821, 0x0000 }, { 0x8702, 0xf824, 0x2000 }, { 0x0702, 0xf823, 0x0000 }, { 0x0702, 0xf825, 0x0000 }, { 0x8702, 0xf82e, 0x4000 }, { 0x8702, 0xf82a, 0x3000 }, { 0x8702, 0xf828, 0x2000 }, { 0x0702, 0xf827, 0x0000 }, { 0x0702, 0xf829, 0x0000 }, { 0x8702, 0xf82c, 0x2000 }, { 0x0702, 0xf82b, 0x0000 }, { 0x0702, 0xf82d, 0x0000 }, { 0x8702, 0xf832, 0x3000 }, { 0x8702, 0xf830, 0x2000 }, { 0x0702, 0xf82f, 0x0000 }, { 0x0702, 0xf831, 0x0000 }, { 0x8702, 0xf834, 0x2000 }, { 0x0702, 0xf833, 0x0000 }, { 0x0702, 0xf835, 0x0000 }, { 0x8702, 0xf856, 0x6000 }, { 0x8702, 0xf846, 0x5000 }, { 0x8702, 0xf83e, 0x4000 }, { 0x8702, 0xf83a, 0x3000 }, { 0x8702, 0xf838, 0x2000 }, { 0x0702, 0xf837, 0x0000 }, { 0x0702, 0xf839, 0x0000 }, { 0x8702, 0xf83c, 0x2000 }, { 0x0702, 0xf83b, 0x0000 }, { 0x0702, 0xf83d, 0x0000 }, { 0x8702, 0xf842, 0x3000 }, { 0x8702, 0xf840, 0x2000 }, { 0x0702, 0xf83f, 0x0000 }, { 0x0702, 0xf841, 0x0000 }, { 0x8702, 0xf844, 0x2000 }, { 0x0702, 0xf843, 0x0000 }, { 0x0702, 0xf845, 0x0000 }, { 0x8702, 0xf84e, 0x4000 }, { 0x8702, 0xf84a, 0x3000 }, { 0x8702, 0xf848, 0x2000 }, { 0x0702, 0xf847, 0x0000 }, { 0x0702, 0xf849, 0x0000 }, { 0x8702, 0xf84c, 0x2000 }, { 0x0702, 0xf84b, 0x0000 }, { 0x0702, 0xf84d, 0x0000 }, { 0x8702, 0xf852, 0x3000 }, { 0x8702, 0xf850, 0x2000 }, { 0x0702, 0xf84f, 0x0000 }, { 0x0702, 0xf851, 0x0000 }, { 0x8702, 0xf854, 0x2000 }, { 0x0702, 0xf853, 0x0000 }, { 0x0702, 0xf855, 0x0000 }, { 0x8702, 0xf866, 0x5000 }, { 0x8702, 0xf85e, 0x4000 }, { 0x8702, 0xf85a, 0x3000 }, { 0x8702, 0xf858, 0x2000 }, { 0x0702, 0xf857, 0x0000 }, { 0x0702, 0xf859, 0x0000 }, { 0x8702, 0xf85c, 0x2000 }, { 0x0702, 0xf85b, 0x0000 }, { 0x0702, 0xf85d, 0x0000 }, { 0x8702, 0xf862, 0x3000 }, { 0x8702, 0xf860, 0x2000 }, { 0x0702, 0xf85f, 0x0000 }, { 0x0702, 0xf861, 0x0000 }, { 0x8702, 0xf864, 0x2000 }, { 0x0702, 0xf863, 0x0000 }, { 0x0702, 0xf865, 0x0000 }, { 0x8702, 0xf86e, 0x4000 }, { 0x8702, 0xf86a, 0x3000 }, { 0x8702, 0xf868, 0x2000 }, { 0x0702, 0xf867, 0x0000 }, { 0x0702, 0xf869, 0x0000 }, { 0x8702, 0xf86c, 0x2000 }, { 0x0702, 0xf86b, 0x0000 }, { 0x0702, 0xf86d, 0x0000 }, { 0x8702, 0xf872, 0x3000 }, { 0x8702, 0xf870, 0x2000 }, { 0x0702, 0xf86f, 0x0000 }, { 0x0702, 0xf871, 0x0000 }, { 0x8702, 0xf874, 0x2000 }, { 0x0702, 0xf873, 0x0000 }, { 0x0702, 0xf875, 0x0000 }, { 0x8702, 0xf976, 0x9000 }, { 0x8702, 0xf8f6, 0x8000 }, { 0x8702, 0xf8b6, 0x7000 }, { 0x8702, 0xf896, 0x6000 }, { 0x8702, 0xf886, 0x5000 }, { 0x8702, 0xf87e, 0x4000 }, { 0x8702, 0xf87a, 0x3000 }, { 0x8702, 0xf878, 0x2000 }, { 0x0702, 0xf877, 0x0000 }, { 0x0702, 0xf879, 0x0000 }, { 0x8702, 0xf87c, 0x2000 }, { 0x0702, 0xf87b, 0x0000 }, { 0x0702, 0xf87d, 0x0000 }, { 0x8702, 0xf882, 0x3000 }, { 0x8702, 0xf880, 0x2000 }, { 0x0702, 0xf87f, 0x0000 }, { 0x0702, 0xf881, 0x0000 }, { 0x8702, 0xf884, 0x2000 }, { 0x0702, 0xf883, 0x0000 }, { 0x0702, 0xf885, 0x0000 }, { 0x8702, 0xf88e, 0x4000 }, { 0x8702, 0xf88a, 0x3000 }, { 0x8702, 0xf888, 0x2000 }, { 0x0702, 0xf887, 0x0000 }, { 0x0702, 0xf889, 0x0000 }, { 0x8702, 0xf88c, 0x2000 }, { 0x0702, 0xf88b, 0x0000 }, { 0x0702, 0xf88d, 0x0000 }, { 0x8702, 0xf892, 0x3000 }, { 0x8702, 0xf890, 0x2000 }, { 0x0702, 0xf88f, 0x0000 }, { 0x0702, 0xf891, 0x0000 }, { 0x8702, 0xf894, 0x2000 }, { 0x0702, 0xf893, 0x0000 }, { 0x0702, 0xf895, 0x0000 }, { 0x8702, 0xf8a6, 0x5000 }, { 0x8702, 0xf89e, 0x4000 }, { 0x8702, 0xf89a, 0x3000 }, { 0x8702, 0xf898, 0x2000 }, { 0x0702, 0xf897, 0x0000 }, { 0x0702, 0xf899, 0x0000 }, { 0x8702, 0xf89c, 0x2000 }, { 0x0702, 0xf89b, 0x0000 }, { 0x0702, 0xf89d, 0x0000 }, { 0x8702, 0xf8a2, 0x3000 }, { 0x8702, 0xf8a0, 0x2000 }, { 0x0702, 0xf89f, 0x0000 }, { 0x0702, 0xf8a1, 0x0000 }, { 0x8702, 0xf8a4, 0x2000 }, { 0x0702, 0xf8a3, 0x0000 }, { 0x0702, 0xf8a5, 0x0000 }, { 0x8702, 0xf8ae, 0x4000 }, { 0x8702, 0xf8aa, 0x3000 }, { 0x8702, 0xf8a8, 0x2000 }, { 0x0702, 0xf8a7, 0x0000 }, { 0x0702, 0xf8a9, 0x0000 }, { 0x8702, 0xf8ac, 0x2000 }, { 0x0702, 0xf8ab, 0x0000 }, { 0x0702, 0xf8ad, 0x0000 }, { 0x8702, 0xf8b2, 0x3000 }, { 0x8702, 0xf8b0, 0x2000 }, { 0x0702, 0xf8af, 0x0000 }, { 0x0702, 0xf8b1, 0x0000 }, { 0x8702, 0xf8b4, 0x2000 }, { 0x0702, 0xf8b3, 0x0000 }, { 0x0702, 0xf8b5, 0x0000 }, { 0x8702, 0xf8d6, 0x6000 }, { 0x8702, 0xf8c6, 0x5000 }, { 0x8702, 0xf8be, 0x4000 }, { 0x8702, 0xf8ba, 0x3000 }, { 0x8702, 0xf8b8, 0x2000 }, { 0x0702, 0xf8b7, 0x0000 }, { 0x0702, 0xf8b9, 0x0000 }, { 0x8702, 0xf8bc, 0x2000 }, { 0x0702, 0xf8bb, 0x0000 }, { 0x0702, 0xf8bd, 0x0000 }, { 0x8702, 0xf8c2, 0x3000 }, { 0x8702, 0xf8c0, 0x2000 }, { 0x0702, 0xf8bf, 0x0000 }, { 0x0702, 0xf8c1, 0x0000 }, { 0x8702, 0xf8c4, 0x2000 }, { 0x0702, 0xf8c3, 0x0000 }, { 0x0702, 0xf8c5, 0x0000 }, { 0x8702, 0xf8ce, 0x4000 }, { 0x8702, 0xf8ca, 0x3000 }, { 0x8702, 0xf8c8, 0x2000 }, { 0x0702, 0xf8c7, 0x0000 }, { 0x0702, 0xf8c9, 0x0000 }, { 0x8702, 0xf8cc, 0x2000 }, { 0x0702, 0xf8cb, 0x0000 }, { 0x0702, 0xf8cd, 0x0000 }, { 0x8702, 0xf8d2, 0x3000 }, { 0x8702, 0xf8d0, 0x2000 }, { 0x0702, 0xf8cf, 0x0000 }, { 0x0702, 0xf8d1, 0x0000 }, { 0x8702, 0xf8d4, 0x2000 }, { 0x0702, 0xf8d3, 0x0000 }, { 0x0702, 0xf8d5, 0x0000 }, { 0x8702, 0xf8e6, 0x5000 }, { 0x8702, 0xf8de, 0x4000 }, { 0x8702, 0xf8da, 0x3000 }, { 0x8702, 0xf8d8, 0x2000 }, { 0x0702, 0xf8d7, 0x0000 }, { 0x0702, 0xf8d9, 0x0000 }, { 0x8702, 0xf8dc, 0x2000 }, { 0x0702, 0xf8db, 0x0000 }, { 0x0702, 0xf8dd, 0x0000 }, { 0x8702, 0xf8e2, 0x3000 }, { 0x8702, 0xf8e0, 0x2000 }, { 0x0702, 0xf8df, 0x0000 }, { 0x0702, 0xf8e1, 0x0000 }, { 0x8702, 0xf8e4, 0x2000 }, { 0x0702, 0xf8e3, 0x0000 }, { 0x0702, 0xf8e5, 0x0000 }, { 0x8702, 0xf8ee, 0x4000 }, { 0x8702, 0xf8ea, 0x3000 }, { 0x8702, 0xf8e8, 0x2000 }, { 0x0702, 0xf8e7, 0x0000 }, { 0x0702, 0xf8e9, 0x0000 }, { 0x8702, 0xf8ec, 0x2000 }, { 0x0702, 0xf8eb, 0x0000 }, { 0x0702, 0xf8ed, 0x0000 }, { 0x8702, 0xf8f2, 0x3000 }, { 0x8702, 0xf8f0, 0x2000 }, { 0x0702, 0xf8ef, 0x0000 }, { 0x0702, 0xf8f1, 0x0000 }, { 0x8702, 0xf8f4, 0x2000 }, { 0x0702, 0xf8f3, 0x0000 }, { 0x0702, 0xf8f5, 0x0000 }, { 0x8702, 0xf936, 0x7000 }, { 0x8702, 0xf916, 0x6000 }, { 0x8702, 0xf906, 0x5000 }, { 0x8702, 0xf8fe, 0x4000 }, { 0x8702, 0xf8fa, 0x3000 }, { 0x8702, 0xf8f8, 0x2000 }, { 0x0702, 0xf8f7, 0x0000 }, { 0x0702, 0xf8f9, 0x0000 }, { 0x8702, 0xf8fc, 0x2000 }, { 0x0702, 0xf8fb, 0x0000 }, { 0x0702, 0xf8fd, 0x0000 }, { 0x8702, 0xf902, 0x3000 }, { 0x8702, 0xf900, 0x2000 }, { 0x0702, 0xf8ff, 0x0000 }, { 0x0702, 0xf901, 0x0000 }, { 0x8702, 0xf904, 0x2000 }, { 0x0702, 0xf903, 0x0000 }, { 0x0702, 0xf905, 0x0000 }, { 0x8702, 0xf90e, 0x4000 }, { 0x8702, 0xf90a, 0x3000 }, { 0x8702, 0xf908, 0x2000 }, { 0x0702, 0xf907, 0x0000 }, { 0x0702, 0xf909, 0x0000 }, { 0x8702, 0xf90c, 0x2000 }, { 0x0702, 0xf90b, 0x0000 }, { 0x0702, 0xf90d, 0x0000 }, { 0x8702, 0xf912, 0x3000 }, { 0x8702, 0xf910, 0x2000 }, { 0x0702, 0xf90f, 0x0000 }, { 0x0702, 0xf911, 0x0000 }, { 0x8702, 0xf914, 0x2000 }, { 0x0702, 0xf913, 0x0000 }, { 0x0702, 0xf915, 0x0000 }, { 0x8702, 0xf926, 0x5000 }, { 0x8702, 0xf91e, 0x4000 }, { 0x8702, 0xf91a, 0x3000 }, { 0x8702, 0xf918, 0x2000 }, { 0x0702, 0xf917, 0x0000 }, { 0x0702, 0xf919, 0x0000 }, { 0x8702, 0xf91c, 0x2000 }, { 0x0702, 0xf91b, 0x0000 }, { 0x0702, 0xf91d, 0x0000 }, { 0x8702, 0xf922, 0x3000 }, { 0x8702, 0xf920, 0x2000 }, { 0x0702, 0xf91f, 0x0000 }, { 0x0702, 0xf921, 0x0000 }, { 0x8702, 0xf924, 0x2000 }, { 0x0702, 0xf923, 0x0000 }, { 0x0702, 0xf925, 0x0000 }, { 0x8702, 0xf92e, 0x4000 }, { 0x8702, 0xf92a, 0x3000 }, { 0x8702, 0xf928, 0x2000 }, { 0x0702, 0xf927, 0x0000 }, { 0x0702, 0xf929, 0x0000 }, { 0x8702, 0xf92c, 0x2000 }, { 0x0702, 0xf92b, 0x0000 }, { 0x0702, 0xf92d, 0x0000 }, { 0x8702, 0xf932, 0x3000 }, { 0x8702, 0xf930, 0x2000 }, { 0x0702, 0xf92f, 0x0000 }, { 0x0702, 0xf931, 0x0000 }, { 0x8702, 0xf934, 0x2000 }, { 0x0702, 0xf933, 0x0000 }, { 0x0702, 0xf935, 0x0000 }, { 0x8702, 0xf956, 0x6000 }, { 0x8702, 0xf946, 0x5000 }, { 0x8702, 0xf93e, 0x4000 }, { 0x8702, 0xf93a, 0x3000 }, { 0x8702, 0xf938, 0x2000 }, { 0x0702, 0xf937, 0x0000 }, { 0x0702, 0xf939, 0x0000 }, { 0x8702, 0xf93c, 0x2000 }, { 0x0702, 0xf93b, 0x0000 }, { 0x0702, 0xf93d, 0x0000 }, { 0x8702, 0xf942, 0x3000 }, { 0x8702, 0xf940, 0x2000 }, { 0x0702, 0xf93f, 0x0000 }, { 0x0702, 0xf941, 0x0000 }, { 0x8702, 0xf944, 0x2000 }, { 0x0702, 0xf943, 0x0000 }, { 0x0702, 0xf945, 0x0000 }, { 0x8702, 0xf94e, 0x4000 }, { 0x8702, 0xf94a, 0x3000 }, { 0x8702, 0xf948, 0x2000 }, { 0x0702, 0xf947, 0x0000 }, { 0x0702, 0xf949, 0x0000 }, { 0x8702, 0xf94c, 0x2000 }, { 0x0702, 0xf94b, 0x0000 }, { 0x0702, 0xf94d, 0x0000 }, { 0x8702, 0xf952, 0x3000 }, { 0x8702, 0xf950, 0x2000 }, { 0x0702, 0xf94f, 0x0000 }, { 0x0702, 0xf951, 0x0000 }, { 0x8702, 0xf954, 0x2000 }, { 0x0702, 0xf953, 0x0000 }, { 0x0702, 0xf955, 0x0000 }, { 0x8702, 0xf966, 0x5000 }, { 0x8702, 0xf95e, 0x4000 }, { 0x8702, 0xf95a, 0x3000 }, { 0x8702, 0xf958, 0x2000 }, { 0x0702, 0xf957, 0x0000 }, { 0x0702, 0xf959, 0x0000 }, { 0x8702, 0xf95c, 0x2000 }, { 0x0702, 0xf95b, 0x0000 }, { 0x0702, 0xf95d, 0x0000 }, { 0x8702, 0xf962, 0x3000 }, { 0x8702, 0xf960, 0x2000 }, { 0x0702, 0xf95f, 0x0000 }, { 0x0702, 0xf961, 0x0000 }, { 0x8702, 0xf964, 0x2000 }, { 0x0702, 0xf963, 0x0000 }, { 0x0702, 0xf965, 0x0000 }, { 0x8702, 0xf96e, 0x4000 }, { 0x8702, 0xf96a, 0x3000 }, { 0x8702, 0xf968, 0x2000 }, { 0x0702, 0xf967, 0x0000 }, { 0x0702, 0xf969, 0x0000 }, { 0x8702, 0xf96c, 0x2000 }, { 0x0702, 0xf96b, 0x0000 }, { 0x0702, 0xf96d, 0x0000 }, { 0x8702, 0xf972, 0x3000 }, { 0x8702, 0xf970, 0x2000 }, { 0x0702, 0xf96f, 0x0000 }, { 0x0702, 0xf971, 0x0000 }, { 0x8702, 0xf974, 0x2000 }, { 0x0702, 0xf973, 0x0000 }, { 0x0702, 0xf975, 0x0000 }, { 0x810e, 0x0077, 0x9000 }, { 0x8702, 0xf9f6, 0x8000 }, { 0x8702, 0xf9b6, 0x7000 }, { 0x8702, 0xf996, 0x6000 }, { 0x8702, 0xf986, 0x5000 }, { 0x8702, 0xf97e, 0x4000 }, { 0x8702, 0xf97a, 0x3000 }, { 0x8702, 0xf978, 0x2000 }, { 0x0702, 0xf977, 0x0000 }, { 0x0702, 0xf979, 0x0000 }, { 0x8702, 0xf97c, 0x2000 }, { 0x0702, 0xf97b, 0x0000 }, { 0x0702, 0xf97d, 0x0000 }, { 0x8702, 0xf982, 0x3000 }, { 0x8702, 0xf980, 0x2000 }, { 0x0702, 0xf97f, 0x0000 }, { 0x0702, 0xf981, 0x0000 }, { 0x8702, 0xf984, 0x2000 }, { 0x0702, 0xf983, 0x0000 }, { 0x0702, 0xf985, 0x0000 }, { 0x8702, 0xf98e, 0x4000 }, { 0x8702, 0xf98a, 0x3000 }, { 0x8702, 0xf988, 0x2000 }, { 0x0702, 0xf987, 0x0000 }, { 0x0702, 0xf989, 0x0000 }, { 0x8702, 0xf98c, 0x2000 }, { 0x0702, 0xf98b, 0x0000 }, { 0x0702, 0xf98d, 0x0000 }, { 0x8702, 0xf992, 0x3000 }, { 0x8702, 0xf990, 0x2000 }, { 0x0702, 0xf98f, 0x0000 }, { 0x0702, 0xf991, 0x0000 }, { 0x8702, 0xf994, 0x2000 }, { 0x0702, 0xf993, 0x0000 }, { 0x0702, 0xf995, 0x0000 }, { 0x8702, 0xf9a6, 0x5000 }, { 0x8702, 0xf99e, 0x4000 }, { 0x8702, 0xf99a, 0x3000 }, { 0x8702, 0xf998, 0x2000 }, { 0x0702, 0xf997, 0x0000 }, { 0x0702, 0xf999, 0x0000 }, { 0x8702, 0xf99c, 0x2000 }, { 0x0702, 0xf99b, 0x0000 }, { 0x0702, 0xf99d, 0x0000 }, { 0x8702, 0xf9a2, 0x3000 }, { 0x8702, 0xf9a0, 0x2000 }, { 0x0702, 0xf99f, 0x0000 }, { 0x0702, 0xf9a1, 0x0000 }, { 0x8702, 0xf9a4, 0x2000 }, { 0x0702, 0xf9a3, 0x0000 }, { 0x0702, 0xf9a5, 0x0000 }, { 0x8702, 0xf9ae, 0x4000 }, { 0x8702, 0xf9aa, 0x3000 }, { 0x8702, 0xf9a8, 0x2000 }, { 0x0702, 0xf9a7, 0x0000 }, { 0x0702, 0xf9a9, 0x0000 }, { 0x8702, 0xf9ac, 0x2000 }, { 0x0702, 0xf9ab, 0x0000 }, { 0x0702, 0xf9ad, 0x0000 }, { 0x8702, 0xf9b2, 0x3000 }, { 0x8702, 0xf9b0, 0x2000 }, { 0x0702, 0xf9af, 0x0000 }, { 0x0702, 0xf9b1, 0x0000 }, { 0x8702, 0xf9b4, 0x2000 }, { 0x0702, 0xf9b3, 0x0000 }, { 0x0702, 0xf9b5, 0x0000 }, { 0x8702, 0xf9d6, 0x6000 }, { 0x8702, 0xf9c6, 0x5000 }, { 0x8702, 0xf9be, 0x4000 }, { 0x8702, 0xf9ba, 0x3000 }, { 0x8702, 0xf9b8, 0x2000 }, { 0x0702, 0xf9b7, 0x0000 }, { 0x0702, 0xf9b9, 0x0000 }, { 0x8702, 0xf9bc, 0x2000 }, { 0x0702, 0xf9bb, 0x0000 }, { 0x0702, 0xf9bd, 0x0000 }, { 0x8702, 0xf9c2, 0x3000 }, { 0x8702, 0xf9c0, 0x2000 }, { 0x0702, 0xf9bf, 0x0000 }, { 0x0702, 0xf9c1, 0x0000 }, { 0x8702, 0xf9c4, 0x2000 }, { 0x0702, 0xf9c3, 0x0000 }, { 0x0702, 0xf9c5, 0x0000 }, { 0x8702, 0xf9ce, 0x4000 }, { 0x8702, 0xf9ca, 0x3000 }, { 0x8702, 0xf9c8, 0x2000 }, { 0x0702, 0xf9c7, 0x0000 }, { 0x0702, 0xf9c9, 0x0000 }, { 0x8702, 0xf9cc, 0x2000 }, { 0x0702, 0xf9cb, 0x0000 }, { 0x0702, 0xf9cd, 0x0000 }, { 0x8702, 0xf9d2, 0x3000 }, { 0x8702, 0xf9d0, 0x2000 }, { 0x0702, 0xf9cf, 0x0000 }, { 0x0702, 0xf9d1, 0x0000 }, { 0x8702, 0xf9d4, 0x2000 }, { 0x0702, 0xf9d3, 0x0000 }, { 0x0702, 0xf9d5, 0x0000 }, { 0x8702, 0xf9e6, 0x5000 }, { 0x8702, 0xf9de, 0x4000 }, { 0x8702, 0xf9da, 0x3000 }, { 0x8702, 0xf9d8, 0x2000 }, { 0x0702, 0xf9d7, 0x0000 }, { 0x0702, 0xf9d9, 0x0000 }, { 0x8702, 0xf9dc, 0x2000 }, { 0x0702, 0xf9db, 0x0000 }, { 0x0702, 0xf9dd, 0x0000 }, { 0x8702, 0xf9e2, 0x3000 }, { 0x8702, 0xf9e0, 0x2000 }, { 0x0702, 0xf9df, 0x0000 }, { 0x0702, 0xf9e1, 0x0000 }, { 0x8702, 0xf9e4, 0x2000 }, { 0x0702, 0xf9e3, 0x0000 }, { 0x0702, 0xf9e5, 0x0000 }, { 0x8702, 0xf9ee, 0x4000 }, { 0x8702, 0xf9ea, 0x3000 }, { 0x8702, 0xf9e8, 0x2000 }, { 0x0702, 0xf9e7, 0x0000 }, { 0x0702, 0xf9e9, 0x0000 }, { 0x8702, 0xf9ec, 0x2000 }, { 0x0702, 0xf9eb, 0x0000 }, { 0x0702, 0xf9ed, 0x0000 }, { 0x8702, 0xf9f2, 0x3000 }, { 0x8702, 0xf9f0, 0x2000 }, { 0x0702, 0xf9ef, 0x0000 }, { 0x0702, 0xf9f1, 0x0000 }, { 0x8702, 0xf9f4, 0x2000 }, { 0x0702, 0xf9f3, 0x0000 }, { 0x0702, 0xf9f5, 0x0000 }, { 0x810e, 0x0037, 0x7000 }, { 0x8702, 0xfa16, 0x6000 }, { 0x8702, 0xfa06, 0x5000 }, { 0x8702, 0xf9fe, 0x4000 }, { 0x8702, 0xf9fa, 0x3000 }, { 0x8702, 0xf9f8, 0x2000 }, { 0x0702, 0xf9f7, 0x0000 }, { 0x0702, 0xf9f9, 0x0000 }, { 0x8702, 0xf9fc, 0x2000 }, { 0x0702, 0xf9fb, 0x0000 }, { 0x0702, 0xf9fd, 0x0000 }, { 0x8702, 0xfa02, 0x3000 }, { 0x8702, 0xfa00, 0x2000 }, { 0x0702, 0xf9ff, 0x0000 }, { 0x0702, 0xfa01, 0x0000 }, { 0x8702, 0xfa04, 0x2000 }, { 0x0702, 0xfa03, 0x0000 }, { 0x0702, 0xfa05, 0x0000 }, { 0x8702, 0xfa0e, 0x4000 }, { 0x8702, 0xfa0a, 0x3000 }, { 0x8702, 0xfa08, 0x2000 }, { 0x0702, 0xfa07, 0x0000 }, { 0x0702, 0xfa09, 0x0000 }, { 0x8702, 0xfa0c, 0x2000 }, { 0x0702, 0xfa0b, 0x0000 }, { 0x0702, 0xfa0d, 0x0000 }, { 0x8702, 0xfa12, 0x3000 }, { 0x8702, 0xfa10, 0x2000 }, { 0x0702, 0xfa0f, 0x0000 }, { 0x0702, 0xfa11, 0x0000 }, { 0x8702, 0xfa14, 0x2000 }, { 0x0702, 0xfa13, 0x0000 }, { 0x0702, 0xfa15, 0x0000 }, { 0x810e, 0x0027, 0x5000 }, { 0x810e, 0x0001, 0x4000 }, { 0x8702, 0xfa1a, 0x3000 }, { 0x8702, 0xfa18, 0x2000 }, { 0x0702, 0xfa17, 0x0000 }, { 0x0702, 0xfa19, 0x0000 }, { 0x8702, 0xfa1c, 0x2000 }, { 0x0702, 0xfa1b, 0x0000 }, { 0x0702, 0xfa1d, 0x0000 }, { 0x810e, 0x0023, 0x3000 }, { 0x810e, 0x0021, 0x2000 }, { 0x010e, 0x0020, 0x0000 }, { 0x010e, 0x0022, 0x0000 }, { 0x810e, 0x0025, 0x2000 }, { 0x010e, 0x0024, 0x0000 }, { 0x010e, 0x0026, 0x0000 }, { 0x810e, 0x002f, 0x4000 }, { 0x810e, 0x002b, 0x3000 }, { 0x810e, 0x0029, 0x2000 }, { 0x010e, 0x0028, 0x0000 }, { 0x010e, 0x002a, 0x0000 }, { 0x810e, 0x002d, 0x2000 }, { 0x010e, 0x002c, 0x0000 }, { 0x010e, 0x002e, 0x0000 }, { 0x810e, 0x0033, 0x3000 }, { 0x810e, 0x0031, 0x2000 }, { 0x010e, 0x0030, 0x0000 }, { 0x010e, 0x0032, 0x0000 }, { 0x810e, 0x0035, 0x2000 }, { 0x010e, 0x0034, 0x0000 }, { 0x010e, 0x0036, 0x0000 }, { 0x810e, 0x0057, 0x6000 }, { 0x810e, 0x0047, 0x5000 }, { 0x810e, 0x003f, 0x4000 }, { 0x810e, 0x003b, 0x3000 }, { 0x810e, 0x0039, 0x2000 }, { 0x010e, 0x0038, 0x0000 }, { 0x010e, 0x003a, 0x0000 }, { 0x810e, 0x003d, 0x2000 }, { 0x010e, 0x003c, 0x0000 }, { 0x010e, 0x003e, 0x0000 }, { 0x810e, 0x0043, 0x3000 }, { 0x810e, 0x0041, 0x2000 }, { 0x010e, 0x0040, 0x0000 }, { 0x010e, 0x0042, 0x0000 }, { 0x810e, 0x0045, 0x2000 }, { 0x010e, 0x0044, 0x0000 }, { 0x010e, 0x0046, 0x0000 }, { 0x810e, 0x004f, 0x4000 }, { 0x810e, 0x004b, 0x3000 }, { 0x810e, 0x0049, 0x2000 }, { 0x010e, 0x0048, 0x0000 }, { 0x010e, 0x004a, 0x0000 }, { 0x810e, 0x004d, 0x2000 }, { 0x010e, 0x004c, 0x0000 }, { 0x010e, 0x004e, 0x0000 }, { 0x810e, 0x0053, 0x3000 }, { 0x810e, 0x0051, 0x2000 }, { 0x010e, 0x0050, 0x0000 }, { 0x010e, 0x0052, 0x0000 }, { 0x810e, 0x0055, 0x2000 }, { 0x010e, 0x0054, 0x0000 }, { 0x010e, 0x0056, 0x0000 }, { 0x810e, 0x0067, 0x5000 }, { 0x810e, 0x005f, 0x4000 }, { 0x810e, 0x005b, 0x3000 }, { 0x810e, 0x0059, 0x2000 }, { 0x010e, 0x0058, 0x0000 }, { 0x010e, 0x005a, 0x0000 }, { 0x810e, 0x005d, 0x2000 }, { 0x010e, 0x005c, 0x0000 }, { 0x010e, 0x005e, 0x0000 }, { 0x810e, 0x0063, 0x3000 }, { 0x810e, 0x0061, 0x2000 }, { 0x010e, 0x0060, 0x0000 }, { 0x010e, 0x0062, 0x0000 }, { 0x810e, 0x0065, 0x2000 }, { 0x010e, 0x0064, 0x0000 }, { 0x010e, 0x0066, 0x0000 }, { 0x810e, 0x006f, 0x4000 }, { 0x810e, 0x006b, 0x3000 }, { 0x810e, 0x0069, 0x2000 }, { 0x010e, 0x0068, 0x0000 }, { 0x010e, 0x006a, 0x0000 }, { 0x810e, 0x006d, 0x2000 }, { 0x010e, 0x006c, 0x0000 }, { 0x010e, 0x006e, 0x0000 }, { 0x810e, 0x0073, 0x3000 }, { 0x810e, 0x0071, 0x2000 }, { 0x010e, 0x0070, 0x0000 }, { 0x010e, 0x0072, 0x0000 }, { 0x810e, 0x0075, 0x2000 }, { 0x010e, 0x0074, 0x0000 }, { 0x010e, 0x0076, 0x0000 }, { 0x8c0e, 0x0177, 0x8000 }, { 0x8c0e, 0x0137, 0x7000 }, { 0x8c0e, 0x0117, 0x6000 }, { 0x8c0e, 0x0107, 0x5000 }, { 0x810e, 0x007f, 0x4000 }, { 0x810e, 0x007b, 0x3000 }, { 0x810e, 0x0079, 0x2000 }, { 0x010e, 0x0078, 0x0000 }, { 0x010e, 0x007a, 0x0000 }, { 0x810e, 0x007d, 0x2000 }, { 0x010e, 0x007c, 0x0000 }, { 0x010e, 0x007e, 0x0000 }, { 0x8c0e, 0x0103, 0x3000 }, { 0x8c0e, 0x0101, 0x2000 }, { 0x0c0e, 0x0100, 0x0000 }, { 0x0c0e, 0x0102, 0x0000 }, { 0x8c0e, 0x0105, 0x2000 }, { 0x0c0e, 0x0104, 0x0000 }, { 0x0c0e, 0x0106, 0x0000 }, { 0x8c0e, 0x010f, 0x4000 }, { 0x8c0e, 0x010b, 0x3000 }, { 0x8c0e, 0x0109, 0x2000 }, { 0x0c0e, 0x0108, 0x0000 }, { 0x0c0e, 0x010a, 0x0000 }, { 0x8c0e, 0x010d, 0x2000 }, { 0x0c0e, 0x010c, 0x0000 }, { 0x0c0e, 0x010e, 0x0000 }, { 0x8c0e, 0x0113, 0x3000 }, { 0x8c0e, 0x0111, 0x2000 }, { 0x0c0e, 0x0110, 0x0000 }, { 0x0c0e, 0x0112, 0x0000 }, { 0x8c0e, 0x0115, 0x2000 }, { 0x0c0e, 0x0114, 0x0000 }, { 0x0c0e, 0x0116, 0x0000 }, { 0x8c0e, 0x0127, 0x5000 }, { 0x8c0e, 0x011f, 0x4000 }, { 0x8c0e, 0x011b, 0x3000 }, { 0x8c0e, 0x0119, 0x2000 }, { 0x0c0e, 0x0118, 0x0000 }, { 0x0c0e, 0x011a, 0x0000 }, { 0x8c0e, 0x011d, 0x2000 }, { 0x0c0e, 0x011c, 0x0000 }, { 0x0c0e, 0x011e, 0x0000 }, { 0x8c0e, 0x0123, 0x3000 }, { 0x8c0e, 0x0121, 0x2000 }, { 0x0c0e, 0x0120, 0x0000 }, { 0x0c0e, 0x0122, 0x0000 }, { 0x8c0e, 0x0125, 0x2000 }, { 0x0c0e, 0x0124, 0x0000 }, { 0x0c0e, 0x0126, 0x0000 }, { 0x8c0e, 0x012f, 0x4000 }, { 0x8c0e, 0x012b, 0x3000 }, { 0x8c0e, 0x0129, 0x2000 }, { 0x0c0e, 0x0128, 0x0000 }, { 0x0c0e, 0x012a, 0x0000 }, { 0x8c0e, 0x012d, 0x2000 }, { 0x0c0e, 0x012c, 0x0000 }, { 0x0c0e, 0x012e, 0x0000 }, { 0x8c0e, 0x0133, 0x3000 }, { 0x8c0e, 0x0131, 0x2000 }, { 0x0c0e, 0x0130, 0x0000 }, { 0x0c0e, 0x0132, 0x0000 }, { 0x8c0e, 0x0135, 0x2000 }, { 0x0c0e, 0x0134, 0x0000 }, { 0x0c0e, 0x0136, 0x0000 }, { 0x8c0e, 0x0157, 0x6000 }, { 0x8c0e, 0x0147, 0x5000 }, { 0x8c0e, 0x013f, 0x4000 }, { 0x8c0e, 0x013b, 0x3000 }, { 0x8c0e, 0x0139, 0x2000 }, { 0x0c0e, 0x0138, 0x0000 }, { 0x0c0e, 0x013a, 0x0000 }, { 0x8c0e, 0x013d, 0x2000 }, { 0x0c0e, 0x013c, 0x0000 }, { 0x0c0e, 0x013e, 0x0000 }, { 0x8c0e, 0x0143, 0x3000 }, { 0x8c0e, 0x0141, 0x2000 }, { 0x0c0e, 0x0140, 0x0000 }, { 0x0c0e, 0x0142, 0x0000 }, { 0x8c0e, 0x0145, 0x2000 }, { 0x0c0e, 0x0144, 0x0000 }, { 0x0c0e, 0x0146, 0x0000 }, { 0x8c0e, 0x014f, 0x4000 }, { 0x8c0e, 0x014b, 0x3000 }, { 0x8c0e, 0x0149, 0x2000 }, { 0x0c0e, 0x0148, 0x0000 }, { 0x0c0e, 0x014a, 0x0000 }, { 0x8c0e, 0x014d, 0x2000 }, { 0x0c0e, 0x014c, 0x0000 }, { 0x0c0e, 0x014e, 0x0000 }, { 0x8c0e, 0x0153, 0x3000 }, { 0x8c0e, 0x0151, 0x2000 }, { 0x0c0e, 0x0150, 0x0000 }, { 0x0c0e, 0x0152, 0x0000 }, { 0x8c0e, 0x0155, 0x2000 }, { 0x0c0e, 0x0154, 0x0000 }, { 0x0c0e, 0x0156, 0x0000 }, { 0x8c0e, 0x0167, 0x5000 }, { 0x8c0e, 0x015f, 0x4000 }, { 0x8c0e, 0x015b, 0x3000 }, { 0x8c0e, 0x0159, 0x2000 }, { 0x0c0e, 0x0158, 0x0000 }, { 0x0c0e, 0x015a, 0x0000 }, { 0x8c0e, 0x015d, 0x2000 }, { 0x0c0e, 0x015c, 0x0000 }, { 0x0c0e, 0x015e, 0x0000 }, { 0x8c0e, 0x0163, 0x3000 }, { 0x8c0e, 0x0161, 0x2000 }, { 0x0c0e, 0x0160, 0x0000 }, { 0x0c0e, 0x0162, 0x0000 }, { 0x8c0e, 0x0165, 0x2000 }, { 0x0c0e, 0x0164, 0x0000 }, { 0x0c0e, 0x0166, 0x0000 }, { 0x8c0e, 0x016f, 0x4000 }, { 0x8c0e, 0x016b, 0x3000 }, { 0x8c0e, 0x0169, 0x2000 }, { 0x0c0e, 0x0168, 0x0000 }, { 0x0c0e, 0x016a, 0x0000 }, { 0x8c0e, 0x016d, 0x2000 }, { 0x0c0e, 0x016c, 0x0000 }, { 0x0c0e, 0x016e, 0x0000 }, { 0x8c0e, 0x0173, 0x3000 }, { 0x8c0e, 0x0171, 0x2000 }, { 0x0c0e, 0x0170, 0x0000 }, { 0x0c0e, 0x0172, 0x0000 }, { 0x8c0e, 0x0175, 0x2000 }, { 0x0c0e, 0x0174, 0x0000 }, { 0x0c0e, 0x0176, 0x0000 }, { 0x8c0e, 0x01b7, 0x7000 }, { 0x8c0e, 0x0197, 0x6000 }, { 0x8c0e, 0x0187, 0x5000 }, { 0x8c0e, 0x017f, 0x4000 }, { 0x8c0e, 0x017b, 0x3000 }, { 0x8c0e, 0x0179, 0x2000 }, { 0x0c0e, 0x0178, 0x0000 }, { 0x0c0e, 0x017a, 0x0000 }, { 0x8c0e, 0x017d, 0x2000 }, { 0x0c0e, 0x017c, 0x0000 }, { 0x0c0e, 0x017e, 0x0000 }, { 0x8c0e, 0x0183, 0x3000 }, { 0x8c0e, 0x0181, 0x2000 }, { 0x0c0e, 0x0180, 0x0000 }, { 0x0c0e, 0x0182, 0x0000 }, { 0x8c0e, 0x0185, 0x2000 }, { 0x0c0e, 0x0184, 0x0000 }, { 0x0c0e, 0x0186, 0x0000 }, { 0x8c0e, 0x018f, 0x4000 }, { 0x8c0e, 0x018b, 0x3000 }, { 0x8c0e, 0x0189, 0x2000 }, { 0x0c0e, 0x0188, 0x0000 }, { 0x0c0e, 0x018a, 0x0000 }, { 0x8c0e, 0x018d, 0x2000 }, { 0x0c0e, 0x018c, 0x0000 }, { 0x0c0e, 0x018e, 0x0000 }, { 0x8c0e, 0x0193, 0x3000 }, { 0x8c0e, 0x0191, 0x2000 }, { 0x0c0e, 0x0190, 0x0000 }, { 0x0c0e, 0x0192, 0x0000 }, { 0x8c0e, 0x0195, 0x2000 }, { 0x0c0e, 0x0194, 0x0000 }, { 0x0c0e, 0x0196, 0x0000 }, { 0x8c0e, 0x01a7, 0x5000 }, { 0x8c0e, 0x019f, 0x4000 }, { 0x8c0e, 0x019b, 0x3000 }, { 0x8c0e, 0x0199, 0x2000 }, { 0x0c0e, 0x0198, 0x0000 }, { 0x0c0e, 0x019a, 0x0000 }, { 0x8c0e, 0x019d, 0x2000 }, { 0x0c0e, 0x019c, 0x0000 }, { 0x0c0e, 0x019e, 0x0000 }, { 0x8c0e, 0x01a3, 0x3000 }, { 0x8c0e, 0x01a1, 0x2000 }, { 0x0c0e, 0x01a0, 0x0000 }, { 0x0c0e, 0x01a2, 0x0000 }, { 0x8c0e, 0x01a5, 0x2000 }, { 0x0c0e, 0x01a4, 0x0000 }, { 0x0c0e, 0x01a6, 0x0000 }, { 0x8c0e, 0x01af, 0x4000 }, { 0x8c0e, 0x01ab, 0x3000 }, { 0x8c0e, 0x01a9, 0x2000 }, { 0x0c0e, 0x01a8, 0x0000 }, { 0x0c0e, 0x01aa, 0x0000 }, { 0x8c0e, 0x01ad, 0x2000 }, { 0x0c0e, 0x01ac, 0x0000 }, { 0x0c0e, 0x01ae, 0x0000 }, { 0x8c0e, 0x01b3, 0x3000 }, { 0x8c0e, 0x01b1, 0x2000 }, { 0x0c0e, 0x01b0, 0x0000 }, { 0x0c0e, 0x01b2, 0x0000 }, { 0x8c0e, 0x01b5, 0x2000 }, { 0x0c0e, 0x01b4, 0x0000 }, { 0x0c0e, 0x01b6, 0x0000 }, { 0x8c0e, 0x01d7, 0x6000 }, { 0x8c0e, 0x01c7, 0x5000 }, { 0x8c0e, 0x01bf, 0x4000 }, { 0x8c0e, 0x01bb, 0x3000 }, { 0x8c0e, 0x01b9, 0x2000 }, { 0x0c0e, 0x01b8, 0x0000 }, { 0x0c0e, 0x01ba, 0x0000 }, { 0x8c0e, 0x01bd, 0x2000 }, { 0x0c0e, 0x01bc, 0x0000 }, { 0x0c0e, 0x01be, 0x0000 }, { 0x8c0e, 0x01c3, 0x3000 }, { 0x8c0e, 0x01c1, 0x2000 }, { 0x0c0e, 0x01c0, 0x0000 }, { 0x0c0e, 0x01c2, 0x0000 }, { 0x8c0e, 0x01c5, 0x2000 }, { 0x0c0e, 0x01c4, 0x0000 }, { 0x0c0e, 0x01c6, 0x0000 }, { 0x8c0e, 0x01cf, 0x4000 }, { 0x8c0e, 0x01cb, 0x3000 }, { 0x8c0e, 0x01c9, 0x2000 }, { 0x0c0e, 0x01c8, 0x0000 }, { 0x0c0e, 0x01ca, 0x0000 }, { 0x8c0e, 0x01cd, 0x2000 }, { 0x0c0e, 0x01cc, 0x0000 }, { 0x0c0e, 0x01ce, 0x0000 }, { 0x8c0e, 0x01d3, 0x3000 }, { 0x8c0e, 0x01d1, 0x2000 }, { 0x0c0e, 0x01d0, 0x0000 }, { 0x0c0e, 0x01d2, 0x0000 }, { 0x8c0e, 0x01d5, 0x2000 }, { 0x0c0e, 0x01d4, 0x0000 }, { 0x0c0e, 0x01d6, 0x0000 }, { 0x8c0e, 0x01e7, 0x5000 }, { 0x8c0e, 0x01df, 0x4000 }, { 0x8c0e, 0x01db, 0x3000 }, { 0x8c0e, 0x01d9, 0x2000 }, { 0x0c0e, 0x01d8, 0x0000 }, { 0x0c0e, 0x01da, 0x0000 }, { 0x8c0e, 0x01dd, 0x2000 }, { 0x0c0e, 0x01dc, 0x0000 }, { 0x0c0e, 0x01de, 0x0000 }, { 0x8c0e, 0x01e3, 0x3000 }, { 0x8c0e, 0x01e1, 0x2000 }, { 0x0c0e, 0x01e0, 0x0000 }, { 0x0c0e, 0x01e2, 0x0000 }, { 0x8c0e, 0x01e5, 0x2000 }, { 0x0c0e, 0x01e4, 0x0000 }, { 0x0c0e, 0x01e6, 0x0000 }, { 0x8c0e, 0x01ef, 0x4000 }, { 0x8c0e, 0x01eb, 0x3000 }, { 0x8c0e, 0x01e9, 0x2000 }, { 0x0c0e, 0x01e8, 0x0000 }, { 0x0c0e, 0x01ea, 0x0000 }, { 0x8c0e, 0x01ed, 0x2000 }, { 0x0c0e, 0x01ec, 0x0000 }, { 0x0c0e, 0x01ee, 0x0000 }, { 0x830f, 0xfffd, 0x2000 }, { 0x030f, 0x0000, 0x0000 }, { 0x0310, 0x0000, 0x1000 }, { 0x0310, 0xfffd, 0x0000 }, }; tomcat-connectors-1.2.41-src/native/iis/pcre/pcre.dsp0000644000000000000020000001056311416061212020756 0ustar rootbin# Microsoft Developer Studio Project File - Name="pcre" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=pcre - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "pcre.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 "pcre.mak" CFG="pcre - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "pcre - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "pcre - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "pcre - 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 "LibR" # PROP Intermediate_Dir "LibR" # PROP Target_Dir "" # ADD BASE CPP /nologo /MD /W3 /O2 /D "_WIN32" /D "NDEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /FD /c # ADD CPP /nologo /MD /W3 /Zi /O2 /D "_WIN32" /D "NDEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /Fd"LibR/pcre_src" /FD /c # ADD BASE RSC /l 0x409 # ADD RSC /l 0x409 BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo !ELSEIF "$(CFG)" == "pcre - 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 "LibD" # PROP Intermediate_Dir "LibD" # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "_WIN32" /D "_DEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /FD /c # ADD CPP /nologo /MDd /W3 /EHsc /Zi /Od /D "_WIN32" /D "_DEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /Fd"LibD/pcre_src" /FD /c # ADD BASE RSC /l 0x409 # ADD RSC /l 0x409 BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo !ENDIF # Begin Target # Name "pcre - Win32 Release" # Name "pcre - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "*.c" # Begin Source File SOURCE=.\dftables.exe !IF "$(CFG)" == "pcre - Win32 Release" # Begin Custom Build - Creating pcre chartables.c from dftables InputPath=.\dftables.exe ".\chartables.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" .\dftables.exe chartables.c # End Custom Build !ELSEIF "$(CFG)" == "pcre - Win32 Debug" # Begin Custom Build - Creating pcre chartables.c from dftables InputPath=.\dftables.exe ".\chartables.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" .\dftables.exe chartables.c # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=.\get.c # End Source File # Begin Source File SOURCE=.\maketables.c # End Source File # Begin Source File SOURCE=.\pcre.c # End Source File # Begin Source File SOURCE=.\study.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "*.h" # Begin Source File SOURCE=.\config.hw !IF "$(CFG)" == "pcre - Win32 Release" # Begin Custom Build - Creating pcre config.h from config.hw InputPath=.\config.hw ".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" type .\config.hw > .\config.h # End Custom Build !ELSEIF "$(CFG)" == "pcre - Win32 Debug" # Begin Custom Build - Creating pcre config.h from config.hw InputPath=.\config.hw ".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" type .\config.hw > .\config.h # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=.\internal.h # End Source File # Begin Source File SOURCE=.\pcre.hw !IF "$(CFG)" == "pcre - Win32 Release" # Begin Custom Build - Creating pcre.h from pcre.hw InputPath=.\pcre.hw ".\pcre.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" type .\pcre.hw > .\pcre.h # End Custom Build !ELSEIF "$(CFG)" == "pcre - Win32 Debug" # Begin Custom Build - Creating pcre.h from pcre.hw InputPath=.\pcre.hw ".\pcre.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" type .\pcre.hw > .\pcre.h # End Custom Build !ENDIF # End Source File # End Group # End Target # End Project tomcat-connectors-1.2.41-src/native/iis/pcre/pcreposix.dsp0000644000000000000020000000743411416061212022044 0ustar rootbin# Microsoft Developer Studio Project File - Name="pcreposix" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Static Library" 0x0104 CFG=pcreposix - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "pcreposix.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 "pcreposix.mak" CFG="pcreposix - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "pcreposix - Win32 Release" (based on "Win32 (x86) Static Library") !MESSAGE "pcreposix - Win32 Debug" (based on "Win32 (x86) Static Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe RSC=rc.exe !IF "$(CFG)" == "pcreposix - 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 "LibR" # PROP Intermediate_Dir "LibR" # PROP Target_Dir "" # ADD BASE CPP /nologo /MD /W3 /O2 /D "_WIN32" /D "NDEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /FD /c # ADD CPP /nologo /MD /W3 /Zi /O2 /Oy- /D "_WIN32" /D "NDEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /Fd"LibR/pcreposix_src" /FD /c # ADD BASE RSC /l 0x409 # ADD RSC /l 0x409 BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo !ELSEIF "$(CFG)" == "pcreposix - 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 "LibD" # PROP Intermediate_Dir "LibD" # PROP Target_Dir "" # ADD BASE CPP /nologo /MDd /W3 /Zi /Od /D "_WIN32" /D "_DEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /FD /EHsc /c # ADD CPP /nologo /MDd /W3 /Zi /Od /I "..\..\include" /D "_WIN32" /D "_DEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /Fd"LibD/pcreposix_src" /FD /EHsc /c # ADD BASE RSC /l 0x409 # ADD RSC /l 0x409 BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LIB32=link.exe -lib # ADD BASE LIB32 /nologo # ADD LIB32 /nologo !ENDIF # Begin Target # Name "pcreposix - Win32 Release" # Name "pcreposix - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "*.c" # Begin Source File SOURCE=.\pcreposix.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "*.h" # Begin Source File SOURCE=.\config.hw !IF "$(CFG)" == "pcreposix - Win32 Release" # Begin Custom Build - Creating pcre config.h from config.hw InputPath=.\config.hw ".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" type .\config.hw > .\config.h # End Custom Build !ELSEIF "$(CFG)" == "pcreposix - Win32 Debug" # Begin Custom Build - Creating pcre config.h from config.hw InputPath=.\config.hw ".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" type .\config.hw > .\config.h # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=.\pcre.hw !IF "$(CFG)" == "pcreposix - Win32 Release" # Begin Custom Build - Creating pcre.h from pcre.hw InputPath=.\pcre.hw ".\pcre.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" type .\pcre.hw > .\pcre.h # End Custom Build !ELSEIF "$(CFG)" == "pcreposix - Win32 Debug" # Begin Custom Build - Creating pcre.h from pcre.hw InputPath=.\pcre.hw ".\pcre.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" type .\pcre.hw > .\pcre.h # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\..\include\pcreposix.h # End Source File # End Group # End Target # End Project tomcat-connectors-1.2.41-src/native/iis/pcre/pcredemo.c0000644000000000000020000002667310517277132021303 0ustar rootbin/************************************************* * PCRE DEMONSTRATION PROGRAM * *************************************************/ /* This is a demonstration program to illustrate the most straightforward ways of calling the PCRE regular expression library from a C program. See the pcresample documentation for a short discussion. Compile thuswise: gcc -Wall pcredemo.c -I/usr/local/include -L/usr/local/lib \ -R/usr/local/lib -lpcre Replace "/usr/local/include" and "/usr/local/lib" with wherever the include and library files for PCRE are installed on your system. Only some operating systems (e.g. Solaris) use the -R option. */ #include #include #include #define OVECCOUNT 30 /* should be a multiple of 3 */ int main(int argc, char **argv) { pcre *re; const char *error; char *pattern; char *subject; unsigned char *name_table; int erroffset; int find_all; int namecount; int name_entry_size; int ovector[OVECCOUNT]; int subject_length; int rc, i; /************************************************************************** * First, sort out the command line. There is only one possible option at * * the moment, "-g" to request repeated matching to find all occurrences, * * like Perl's /g option. We set the variable find_all to a non-zero value * * if the -g option is present. Apart from that, there must be exactly two * * arguments. * **************************************************************************/ find_all = 0; for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-g") == 0) find_all = 1; else break; } /* After the options, we require exactly two arguments, which are the pattern, and the subject string. */ if (argc - i != 2) { printf("Two arguments required: a regex and a subject string\n"); return 1; } pattern = argv[i]; subject = argv[i+1]; subject_length = (int)strlen(subject); /************************************************************************* * Now we are going to compile the regular expression pattern, and handle * * and errors that are detected. * *************************************************************************/ re = pcre_compile( pattern, /* the pattern */ 0, /* default options */ &error, /* for error message */ &erroffset, /* for error offset */ NULL); /* use default character tables */ /* Compilation failed: print the error message and exit */ if (re == NULL) { printf("PCRE compilation failed at offset %d: %s\n", erroffset, error); return 1; } /************************************************************************* * If the compilation succeeded, we call PCRE again, in order to do a * * pattern match against the subject string. This does just ONE match. If * * further matching is needed, it will be done below. * *************************************************************************/ rc = pcre_exec( re, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ subject, /* the subject string */ subject_length, /* the length of the subject */ 0, /* start at offset 0 in the subject */ 0, /* default options */ ovector, /* output vector for substring information */ OVECCOUNT); /* number of elements in the output vector */ /* Matching failed: handle error cases */ if (rc < 0) { switch(rc) { case PCRE_ERROR_NOMATCH: printf("No match\n"); break; /* Handle other special cases if you like */ default: printf("Matching error %d\n", rc); break; } free(re); /* Release memory used for the compiled pattern */ return 1; } /* Match succeded */ printf("\nMatch succeeded at offset %d\n", ovector[0]); /************************************************************************* * We have found the first match within the subject string. If the output * * vector wasn't big enough, set its size to the maximum. Then output any * * substrings that were captured. * *************************************************************************/ /* The output vector wasn't big enough */ if (rc == 0) { rc = OVECCOUNT/3; printf("ovector only has room for %d captured substrings\n", rc - 1); } /* Show substrings stored in the output vector by number. Obviously, in a real application you might want to do things other than print them. */ for (i = 0; i < rc; i++) { char *substring_start = subject + ovector[2*i]; int substring_length = ovector[2*i+1] - ovector[2*i]; printf("%2d: %.*s\n", i, substring_length, substring_start); } /************************************************************************** * That concludes the basic part of this demonstration program. We have * * compiled a pattern, and performed a single match. The code that follows * * first shows how to access named substrings, and then how to code for * * repeated matches on the same subject. * **************************************************************************/ /* See if there are any named substrings, and if so, show them by name. First we have to extract the count of named parentheses from the pattern. */ (void)pcre_fullinfo( re, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ PCRE_INFO_NAMECOUNT, /* number of named substrings */ &namecount); /* where to put the answer */ if (namecount <= 0) printf("No named substrings\n"); else { unsigned char *tabptr; printf("Named substrings\n"); /* Before we can access the substrings, we must extract the table for translating names to numbers, and the size of each entry in the table. */ (void)pcre_fullinfo( re, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ PCRE_INFO_NAMETABLE, /* address of the table */ &name_table); /* where to put the answer */ (void)pcre_fullinfo( re, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ PCRE_INFO_NAMEENTRYSIZE, /* size of each entry in the table */ &name_entry_size); /* where to put the answer */ /* Now we can scan the table and, for each entry, print the number, the name, and the substring itself. */ tabptr = name_table; for (i = 0; i < namecount; i++) { int n = (tabptr[0] << 8) | tabptr[1]; printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2, ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]); tabptr += name_entry_size; } } /************************************************************************* * If the "-g" option was given on the command line, we want to continue * * to search for additional matches in the subject string, in a similar * * way to the /g option in Perl. This turns out to be trickier than you * * might think because of the possibility of matching an empty string. * * What happens is as follows: * * * * If the previous match was NOT for an empty string, we can just start * * the next match at the end of the previous one. * * * * If the previous match WAS for an empty string, we can't do that, as it * * would lead to an infinite loop. Instead, a special call of pcre_exec() * * is made with the PCRE_NOTEMPTY and PCRE_ANCHORED flags set. The first * * of these tells PCRE that an empty string is not a valid match; other * * possibilities must be tried. The second flag restricts PCRE to one * * match attempt at the initial string position. If this match succeeds, * * an alternative to the empty string match has been found, and we can * * proceed round the loop. * *************************************************************************/ if (!find_all) { free(re); /* Release the memory used for the compiled pattern */ return 0; /* Finish unless -g was given */ } /* Loop for second and subsequent matches */ for (;;) { int options = 0; /* Normally no options */ int start_offset = ovector[1]; /* Start at end of previous match */ /* If the previous match was for an empty string, we are finished if we are at the end of the subject. Otherwise, arrange to run another match at the same point to see if a non-empty match can be found. */ if (ovector[0] == ovector[1]) { if (ovector[0] == subject_length) break; options = PCRE_NOTEMPTY | PCRE_ANCHORED; } /* Run the next matching operation */ rc = pcre_exec( re, /* the compiled pattern */ NULL, /* no extra data - we didn't study the pattern */ subject, /* the subject string */ subject_length, /* the length of the subject */ start_offset, /* starting offset in the subject */ options, /* options */ ovector, /* output vector for substring information */ OVECCOUNT); /* number of elements in the output vector */ /* This time, a result of NOMATCH isn't an error. If the value in "options" is zero, it just means we have found all possible matches, so the loop ends. Otherwise, it means we have failed to find a non-empty-string match at a point where there was a previous empty-string match. In this case, we do what Perl does: advance the matching position by one, and continue. We do this by setting the "end of previous match" offset, because that is picked up at the top of the loop as the point at which to start again. */ if (rc == PCRE_ERROR_NOMATCH) { if (options == 0) break; ovector[1] = start_offset + 1; continue; /* Go round the loop again */ } /* Other matching errors are not recoverable. */ if (rc < 0) { printf("Matching error %d\n", rc); free(re); /* Release memory used for the compiled pattern */ return 1; } /* Match succeded */ printf("\nMatch succeeded again at offset %d\n", ovector[0]); /* The match succeeded, but the output vector wasn't big enough. */ if (rc == 0) { rc = OVECCOUNT/3; printf("ovector only has room for %d captured substrings\n", rc - 1); } /* As before, show substrings stored in the output vector by number, and then also any named substrings. */ for (i = 0; i < rc; i++) { char *substring_start = subject + ovector[2*i]; int substring_length = ovector[2*i+1] - ovector[2*i]; printf("%2d: %.*s\n", i, substring_length, substring_start); } if (namecount <= 0) printf("No named substrings\n"); else { unsigned char *tabptr = name_table; printf("Named substrings\n"); for (i = 0; i < namecount; i++) { int n = (tabptr[0] << 8) | tabptr[1]; printf("(%d) %*s: %.*s\n", n, name_entry_size - 3, tabptr + 2, ovector[2*n+1] - ovector[2*n], subject + ovector[2*n]); tabptr += name_entry_size; } } } /* End of loop to find second and subsequent matches */ printf("\n"); free(re); /* Release memory used for the compiled pattern */ return 0; } /* End of pcredemo.c */ tomcat-connectors-1.2.41-src/native/iis/pcre/pcre.x860000644000000000000020000000565211726114766020641 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. CPP=cl.exe RSC=rc.exe OUTDIR=.\Release_x86 INTDIR=.\Release_x86 # Begin Custom Macros OutDir=.\Release_x86 # End Custom Macros ALL : "$(OUTDIR)\pcre.lib" CLEAN : -@erase "$(INTDIR)\get.obj" -@erase "$(INTDIR)\maketables.obj" -@erase "$(INTDIR)\pcre.obj" -@erase "$(INTDIR)\pcre_src.idb" -@erase "$(INTDIR)\pcre_src.pdb" -@erase "$(INTDIR)\study.obj" -@erase "$(OUTDIR)\pcre.lib" "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\pcre.bsc" BSC32_SBRS= \ LIB32=link.exe -lib LIB32_FLAGS=kernel32.lib /nologo /out:"$(OUTDIR)\pcre.lib" LIB32_OBJS= \ "$(INTDIR)\get.obj" \ "$(INTDIR)\maketables.obj" \ "$(INTDIR)\pcre.obj" \ "$(INTDIR)\study.obj" "$(OUTDIR)\pcre.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) $(LIB32) @<< $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) << CPP_PROJ=-nologo -MD -W3 -O2 -Ob2 -Oy- -Zi -EHsc /D "_WIN32" /D "NDEBUG" /D "_WINDOWS" /D "PCRE_STATIC" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\pcre_src" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << SOURCE=.\chartables.hw InputPath=.\chartables.hw ".\chartables.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" < .\chartables.c << SOURCE=.\get.c "$(INTDIR)\get.obj" : $(SOURCE) "$(INTDIR)" ".\config.h" ".\pcre.h" SOURCE=.\maketables.c "$(INTDIR)\maketables.obj" : $(SOURCE) "$(INTDIR)" ".\config.h" ".\pcre.h" SOURCE=.\pcre.c "$(INTDIR)\pcre.obj" : $(SOURCE) "$(INTDIR)" ".\chartables.c" ".\config.h" ".\pcre.h" SOURCE=.\study.c "$(INTDIR)\study.obj" : $(SOURCE) "$(INTDIR)" ".\config.h" ".\pcre.h" SOURCE=.\config.hw InputPath=.\config.hw ".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" < .\config.h << SOURCE=.\pcre.hw InputPath=.\pcre.hw ".\pcre.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" < .\pcre.h << tomcat-connectors-1.2.41-src/native/iis/pcre/Makefile.in0000644000000000000020000000072710517277132021376 0ustar rootbinLTLIBRARY_NAME = libpcre.la LTLIBRARY_SOURCES = maketables.c get.c study.c pcre.c CLEAN_TARGETS = dftables chartables.c DISTCLEAN_TARGETS = pcre.h pcre-config config.h config.log config.status $(CLEAN_TARGETS) include $(top_srcdir)/build/ltlib.mk config.h: touch $@ $(LTLIBRARY_OBJECTS) dftables.lo: config.h dftables: dftables.lo $(LINK) $(EXTRA_LDFLAGS) dftables.lo $(EXTRA_LIBS) $(srcdir)/chartables.c: dftables ./dftables $@ pcre.lo: $(srcdir)/chartables.c tomcat-connectors-1.2.41-src/native/iis/pcre/libpcreposix.def0000644000000000000020000000212611446407632022511 0ustar rootbin; Licensed to the Apache Software Foundation (ASF) under one or more ; contributor license agreements. See the NOTICE file distributed with ; this work for additional information regarding copyright ownership. ; The ASF licenses this file to You under the Apache License, Version 2.0 ; (the "License"); you may not use this file except in compliance with ; the License. You may obtain a copy of the License at ; ; http://www.apache.org/licenses/LICENSE-2.0 ; ; Unless required by applicable law or agreed to in writing, software ; distributed under the License is distributed on an "AS IS" BASIS, ; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ; See the License for the specific language governing permissions and ; limitations under the License. ; LIBRARY libpcreposix EXPORTS pcre_malloc pcre_free pcre_config pcre_callout pcre_compile pcre_copy_substring pcre_exec pcre_get_substring pcre_get_stringnumber pcre_get_substring_list pcre_free_substring pcre_free_substring_list pcre_info pcre_fullinfo pcre_maketables pcre_study pcre_version regcomp regexec regerror regfree tomcat-connectors-1.2.41-src/native/iis/pcre/testdata/0000755000000000000020000000000012555256552021143 5ustar rootbintomcat-connectors-1.2.41-src/native/iis/pcre/testdata/testoutput30000644000000000000020000000275110517277132023407 0ustar rootbinPCRE version 5.0 13-Sep-2004 /^[\w]+/ *** Failers No match École No match /^[\w]+/Lfr_FR École 0: École /^[\w]+/ *** Failers No match École No match /^[\W]+/ École 0: \xc9 /^[\W]+/Lfr_FR *** Failers 0: *** École No match /[\b]/ \b 0: \x08 *** Failers No match a No match /[\b]/Lfr_FR \b 0: \x08 *** Failers No match a No match /^\w+/ *** Failers No match École No match /^\w+/Lfr_FR École 0: École /(.+)\b(.+)/ École 0: \xc9cole 1: \xc9 2: cole /(.+)\b(.+)/Lfr_FR *** Failers 0: *** Failers 1: *** 2: Failers École No match /École/i École 0: \xc9cole *** Failers No match école No match /École/iLfr_FR École 0: École école 0: école /\w/IS Capturing subpattern count = 0 No options No first char No need char Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z /\w/ISLfr_FR Capturing subpattern count = 0 No options No first char No need char Starting byte set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z µ À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý þ ÿ /^[\xc8-\xc9]/iLfr_FR École 0: É école 0: é /^[\xc8-\xc9]/Lfr_FR École 0: É *** Failers No match école No match / End of testinput3 / tomcat-connectors-1.2.41-src/native/iis/pcre/testdata/testoutput40000644000000000000020000003462210517277132023412 0ustar rootbinPCRE version 5.0 13-Sep-2004 /-- Do not use the \x{} construct except with patterns that have the --/ /-- /8 option set, because PCRE doesn't recognize them as UTF-8 unless --/ No match /-- that option is set. However, the latest Perls recognize them always. --/ No match /a.b/8 acb 0: acb a\x7fb 0: a\x{7f}b a\x{100}b 0: a\x{100}b *** Failers No match a\nb No match /a(.{3})b/8 a\x{4000}xyb 0: a\x{4000}xyb 1: \x{4000}xy a\x{4000}\x7fyb 0: a\x{4000}\x{7f}yb 1: \x{4000}\x{7f}y a\x{4000}\x{100}yb 0: a\x{4000}\x{100}yb 1: \x{4000}\x{100}y *** Failers No match a\x{4000}b No match ac\ncb No match /a(.*?)(.)/ a\xc0\x88b 0: a\xc0 1: 2: \xc0 /a(.*?)(.)/8 a\x{100}b 0: a\x{100} 1: 2: \x{100} /a(.*)(.)/ a\xc0\x88b 0: a\xc0\x88b 1: \xc0\x88 2: b /a(.*)(.)/8 a\x{100}b 0: a\x{100}b 1: \x{100} 2: b /a(.)(.)/ a\xc0\x92bcd 0: a\xc0\x92 1: \xc0 2: \x92 /a(.)(.)/8 a\x{240}bcd 0: a\x{240}b 1: \x{240} 2: b /a(.?)(.)/ a\xc0\x92bcd 0: a\xc0\x92 1: \xc0 2: \x92 /a(.?)(.)/8 a\x{240}bcd 0: a\x{240}b 1: \x{240} 2: b /a(.??)(.)/ a\xc0\x92bcd 0: a\xc0 1: 2: \xc0 /a(.??)(.)/8 a\x{240}bcd 0: a\x{240} 1: 2: \x{240} /a(.{3})b/8 a\x{1234}xyb 0: a\x{1234}xyb 1: \x{1234}xy a\x{1234}\x{4321}yb 0: a\x{1234}\x{4321}yb 1: \x{1234}\x{4321}y a\x{1234}\x{4321}\x{3412}b 0: a\x{1234}\x{4321}\x{3412}b 1: \x{1234}\x{4321}\x{3412} *** Failers No match a\x{1234}b No match ac\ncb No match /a(.{3,})b/8 a\x{1234}xyb 0: a\x{1234}xyb 1: \x{1234}xy a\x{1234}\x{4321}yb 0: a\x{1234}\x{4321}yb 1: \x{1234}\x{4321}y a\x{1234}\x{4321}\x{3412}b 0: a\x{1234}\x{4321}\x{3412}b 1: \x{1234}\x{4321}\x{3412} axxxxbcdefghijb 0: axxxxbcdefghijb 1: xxxxbcdefghij a\x{1234}\x{4321}\x{3412}\x{3421}b 0: a\x{1234}\x{4321}\x{3412}\x{3421}b 1: \x{1234}\x{4321}\x{3412}\x{3421} *** Failers No match a\x{1234}b No match /a(.{3,}?)b/8 a\x{1234}xyb 0: a\x{1234}xyb 1: \x{1234}xy a\x{1234}\x{4321}yb 0: a\x{1234}\x{4321}yb 1: \x{1234}\x{4321}y a\x{1234}\x{4321}\x{3412}b 0: a\x{1234}\x{4321}\x{3412}b 1: \x{1234}\x{4321}\x{3412} axxxxbcdefghijb 0: axxxxb 1: xxxx a\x{1234}\x{4321}\x{3412}\x{3421}b 0: a\x{1234}\x{4321}\x{3412}\x{3421}b 1: \x{1234}\x{4321}\x{3412}\x{3421} *** Failers No match a\x{1234}b No match /a(.{3,5})b/8 a\x{1234}xyb 0: a\x{1234}xyb 1: \x{1234}xy a\x{1234}\x{4321}yb 0: a\x{1234}\x{4321}yb 1: \x{1234}\x{4321}y a\x{1234}\x{4321}\x{3412}b 0: a\x{1234}\x{4321}\x{3412}b 1: \x{1234}\x{4321}\x{3412} axxxxbcdefghijb 0: axxxxb 1: xxxx a\x{1234}\x{4321}\x{3412}\x{3421}b 0: a\x{1234}\x{4321}\x{3412}\x{3421}b 1: \x{1234}\x{4321}\x{3412}\x{3421} axbxxbcdefghijb 0: axbxxb 1: xbxx axxxxxbcdefghijb 0: axxxxxb 1: xxxxx *** Failers No match a\x{1234}b No match axxxxxxbcdefghijb No match /a(.{3,5}?)b/8 a\x{1234}xyb 0: a\x{1234}xyb 1: \x{1234}xy a\x{1234}\x{4321}yb 0: a\x{1234}\x{4321}yb 1: \x{1234}\x{4321}y a\x{1234}\x{4321}\x{3412}b 0: a\x{1234}\x{4321}\x{3412}b 1: \x{1234}\x{4321}\x{3412} axxxxbcdefghijb 0: axxxxb 1: xxxx a\x{1234}\x{4321}\x{3412}\x{3421}b 0: a\x{1234}\x{4321}\x{3412}\x{3421}b 1: \x{1234}\x{4321}\x{3412}\x{3421} axbxxbcdefghijb 0: axbxxb 1: xbxx axxxxxbcdefghijb 0: axxxxxb 1: xxxxx *** Failers No match a\x{1234}b No match axxxxxxbcdefghijb No match /^[a\x{c0}]/8 *** Failers No match \x{100} No match /(?<=aXb)cd/8 aXbcd 0: cd /(?<=a\x{100}b)cd/8 a\x{100}bcd 0: cd /(?<=a\x{100000}b)cd/8 a\x{100000}bcd 0: cd /(?:\x{100}){3}b/8 \x{100}\x{100}\x{100}b 0: \x{100}\x{100}\x{100}b *** Failers No match \x{100}\x{100}b No match /\x{ab}/8 \x{ab} 0: \x{ab} \xc2\xab 0: \x{ab} *** Failers No match \x00{ab} No match /(?<=(.))X/8 WXYZ 0: X 1: W \x{256}XYZ 0: X 1: \x{256} *** Failers No match XYZ No match /X(\C{3})/8 X\x{1234} 0: X\x{1234} 1: \x{1234} /X(\C{4})/8 X\x{1234}YZ 0: X\x{1234}Y 1: \x{1234}Y /X\C*/8 XYZabcdce 0: XYZabcdce /X\C*?/8 XYZabcde 0: X /X\C{3,5}/8 Xabcdefg 0: Xabcde X\x{1234} 0: X\x{1234} X\x{1234}YZ 0: X\x{1234}YZ X\x{1234}\x{512} 0: X\x{1234}\x{512} X\x{1234}\x{512}YZ 0: X\x{1234}\x{512} /X\C{3,5}?/8 Xabcdefg 0: Xabc X\x{1234} 0: X\x{1234} X\x{1234}YZ 0: X\x{1234} X\x{1234}\x{512} 0: X\x{1234} /[^a]+/8g bcd 0: bcd \x{100}aY\x{256}Z 0: \x{100} 0: Y\x{256}Z /^[^a]{2}/8 \x{100}bc 0: \x{100}b /^[^a]{2,}/8 \x{100}bcAa 0: \x{100}bcA /^[^a]{2,}?/8 \x{100}bca 0: \x{100}b /[^a]+/8ig bcd 0: bcd \x{100}aY\x{256}Z 0: \x{100} 0: Y\x{256}Z /^[^a]{2}/8i \x{100}bc 0: \x{100}b /^[^a]{2,}/8i \x{100}bcAa 0: \x{100}bc /^[^a]{2,}?/8i \x{100}bca 0: \x{100}b /\x{100}{0,0}/8 abcd 0: /\x{100}?/8 abcd 0: \x{100}\x{100} 0: \x{100} /\x{100}{0,3}/8 \x{100}\x{100} 0: \x{100}\x{100} \x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100} /\x{100}*/8 abce 0: \x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100}\x{100} /\x{100}{1,1}/8 abcd\x{100}\x{100}\x{100}\x{100} 0: \x{100} /\x{100}{1,3}/8 abcd\x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100} /\x{100}+/8 abcd\x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100}\x{100} /\x{100}{3}/8 abcd\x{100}\x{100}\x{100}XX 0: \x{100}\x{100}\x{100} /\x{100}{3,5}/8 abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX 0: \x{100}\x{100}\x{100}\x{100}\x{100} /\x{100}{3,}/8 abcd\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}XX 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} /(?<=a\x{100}{2}b)X/8+ Xyyya\x{100}\x{100}bXzzz 0: X 0+ zzz /\D*/8 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /\D*/8 \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} 0: \x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100}\x{100} /\D/8 1X2 0: X 1\x{100}2 0: \x{100} />\S/8 > >X Y 0: >X > >\x{100} Y 0: >\x{100} /\d/8 \x{100}3 0: 3 /\s/8 \x{100} X 0: /\D+/8 12abcd34 0: abcd *** Failers 0: *** Failers 1234 No match /\D{2,3}/8 12abcd34 0: abc 12ab34 0: ab *** Failers 0: *** 1234 No match 12a34 No match /\D{2,3}?/8 12abcd34 0: ab 12ab34 0: ab *** Failers 0: ** 1234 No match 12a34 No match /\d+/8 12abcd34 0: 12 *** Failers No match /\d{2,3}/8 12abcd34 0: 12 1234abcd 0: 123 *** Failers No match 1.4 No match /\d{2,3}?/8 12abcd34 0: 12 1234abcd 0: 12 *** Failers No match 1.4 No match /\S+/8 12abcd34 0: 12abcd34 *** Failers 0: *** \ \ No match /\S{2,3}/8 12abcd34 0: 12a 1234abcd 0: 123 *** Failers 0: *** \ \ No match /\S{2,3}?/8 12abcd34 0: 12 1234abcd 0: 12 *** Failers 0: ** \ \ No match />\s+ <34 0: > < 0+ 34 *** Failers No match />\s{2,3} < 0+ cd ab> < 0+ ce *** Failers No match ab> \s{2,3}? < 0+ cd ab> < 0+ ce *** Failers No match ab> \xff< 0: \xff /[\xff]/8 >\x{ff}< 0: \x{ff} /[^\xFF]/ XYZ 0: X /[^\xff]/8 XYZ 0: X \x{123} 0: \x{123} /^[ac]*b/8 xb No match /^[ac\x{100}]*b/8 xb No match /^[^x]*b/8i xb No match /^[^x]*b/8 xb No match /^\d*b/8 xb No match /(|a)/g8 catac 0: 1: 0: 1: 0: a 1: a 0: 1: 0: 1: 0: a 1: a 0: 1: 0: 1: a\x{256}a 0: 1: 0: a 1: a 0: 1: 0: 1: 0: a 1: a 0: 1: /^\x{85}$/8i \x{85} 0: \x{85} / End of testinput4 / tomcat-connectors-1.2.41-src/native/iis/pcre/testdata/testoutput10000644000000000000020000027777310517277132023427 0ustar rootbinPCRE version 5.0 13-Sep-2004 /the quick brown fox/ the quick brown fox 0: the quick brown fox The quick brown FOX No match What do you know about the quick brown fox? 0: the quick brown fox What do you know about THE QUICK BROWN FOX? No match /The quick brown fox/i the quick brown fox 0: the quick brown fox The quick brown FOX 0: The quick brown FOX What do you know about the quick brown fox? 0: the quick brown fox What do you know about THE QUICK BROWN FOX? 0: THE QUICK BROWN FOX /abcd\t\n\r\f\a\e\071\x3b\$\\\?caxyz/ abcd\t\n\r\f\a\e9;\$\\?caxyz 0: abcd\x09\x0a\x0d\x0c\x07\x1b9;$\?caxyz /a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz/ abxyzpqrrrabbxyyyypqAzz 0: abxyzpqrrrabbxyyyypqAzz abxyzpqrrrabbxyyyypqAzz 0: abxyzpqrrrabbxyyyypqAzz aabxyzpqrrrabbxyyyypqAzz 0: aabxyzpqrrrabbxyyyypqAzz aaabxyzpqrrrabbxyyyypqAzz 0: aaabxyzpqrrrabbxyyyypqAzz aaaabxyzpqrrrabbxyyyypqAzz 0: aaaabxyzpqrrrabbxyyyypqAzz abcxyzpqrrrabbxyyyypqAzz 0: abcxyzpqrrrabbxyyyypqAzz aabcxyzpqrrrabbxyyyypqAzz 0: aabcxyzpqrrrabbxyyyypqAzz aaabcxyzpqrrrabbxyyyypAzz 0: aaabcxyzpqrrrabbxyyyypAzz aaabcxyzpqrrrabbxyyyypqAzz 0: aaabcxyzpqrrrabbxyyyypqAzz aaabcxyzpqrrrabbxyyyypqqAzz 0: aaabcxyzpqrrrabbxyyyypqqAzz aaabcxyzpqrrrabbxyyyypqqqAzz 0: aaabcxyzpqrrrabbxyyyypqqqAzz aaabcxyzpqrrrabbxyyyypqqqqAzz 0: aaabcxyzpqrrrabbxyyyypqqqqAzz aaabcxyzpqrrrabbxyyyypqqqqqAzz 0: aaabcxyzpqrrrabbxyyyypqqqqqAzz aaabcxyzpqrrrabbxyyyypqqqqqqAzz 0: aaabcxyzpqrrrabbxyyyypqqqqqqAzz aaaabcxyzpqrrrabbxyyyypqAzz 0: aaaabcxyzpqrrrabbxyyyypqAzz abxyzzpqrrrabbxyyyypqAzz 0: abxyzzpqrrrabbxyyyypqAzz aabxyzzzpqrrrabbxyyyypqAzz 0: aabxyzzzpqrrrabbxyyyypqAzz aaabxyzzzzpqrrrabbxyyyypqAzz 0: aaabxyzzzzpqrrrabbxyyyypqAzz aaaabxyzzzzpqrrrabbxyyyypqAzz 0: aaaabxyzzzzpqrrrabbxyyyypqAzz abcxyzzpqrrrabbxyyyypqAzz 0: abcxyzzpqrrrabbxyyyypqAzz aabcxyzzzpqrrrabbxyyyypqAzz 0: aabcxyzzzpqrrrabbxyyyypqAzz aaabcxyzzzzpqrrrabbxyyyypqAzz 0: aaabcxyzzzzpqrrrabbxyyyypqAzz aaaabcxyzzzzpqrrrabbxyyyypqAzz 0: aaaabcxyzzzzpqrrrabbxyyyypqAzz aaaabcxyzzzzpqrrrabbbxyyyypqAzz 0: aaaabcxyzzzzpqrrrabbbxyyyypqAzz aaaabcxyzzzzpqrrrabbbxyyyyypqAzz 0: aaaabcxyzzzzpqrrrabbbxyyyyypqAzz aaabcxyzpqrrrabbxyyyypABzz 0: aaabcxyzpqrrrabbxyyyypABzz aaabcxyzpqrrrabbxyyyypABBzz 0: aaabcxyzpqrrrabbxyyyypABBzz >>>aaabxyzpqrrrabbxyyyypqAzz 0: aaabxyzpqrrrabbxyyyypqAzz >aaaabxyzpqrrrabbxyyyypqAzz 0: aaaabxyzpqrrrabbxyyyypqAzz >>>>abcxyzpqrrrabbxyyyypqAzz 0: abcxyzpqrrrabbxyyyypqAzz *** Failers No match abxyzpqrrabbxyyyypqAzz No match abxyzpqrrrrabbxyyyypqAzz No match abxyzpqrrrabxyyyypqAzz No match aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz No match aaaabcxyzzzzpqrrrabbbxyyypqAzz No match aaabcxyzpqrrrabbxyyyypqqqqqqqAzz No match /^(abc){1,2}zz/ abczz 0: abczz 1: abc abcabczz 0: abcabczz 1: abc *** Failers No match zz No match abcabcabczz No match >>abczz No match /^(b+?|a){1,2}?c/ bc 0: bc 1: b bbc 0: bbc 1: b bbbc 0: bbbc 1: bb bac 0: bac 1: a bbac 0: bbac 1: a aac 0: aac 1: a abbbbbbbbbbbc 0: abbbbbbbbbbbc 1: bbbbbbbbbbb bbbbbbbbbbbac 0: bbbbbbbbbbbac 1: a *** Failers No match aaac No match abbbbbbbbbbbac No match /^(b+|a){1,2}c/ bc 0: bc 1: b bbc 0: bbc 1: bb bbbc 0: bbbc 1: bbb bac 0: bac 1: a bbac 0: bbac 1: a aac 0: aac 1: a abbbbbbbbbbbc 0: abbbbbbbbbbbc 1: bbbbbbbbbbb bbbbbbbbbbbac 0: bbbbbbbbbbbac 1: a *** Failers No match aaac No match abbbbbbbbbbbac No match /^(b+|a){1,2}?bc/ bbc 0: bbc 1: b /^(b*|ba){1,2}?bc/ babc 0: babc 1: ba bbabc 0: bbabc 1: ba bababc 0: bababc 1: ba *** Failers No match bababbc No match babababc No match /^(ba|b*){1,2}?bc/ babc 0: babc 1: ba bbabc 0: bbabc 1: ba bababc 0: bababc 1: ba *** Failers No match bababbc No match babababc No match /^\ca\cA\c[\c{\c:/ \x01\x01\e;z 0: \x01\x01\x1b;z /^[ab\]cde]/ athing 0: a bthing 0: b ]thing 0: ] cthing 0: c dthing 0: d ething 0: e *** Failers No match fthing No match [thing No match \\thing No match /^[]cde]/ ]thing 0: ] cthing 0: c dthing 0: d ething 0: e *** Failers No match athing No match fthing No match /^[^ab\]cde]/ fthing 0: f [thing 0: [ \\thing 0: \ *** Failers 0: * athing No match bthing No match ]thing No match cthing No match dthing No match ething No match /^[^]cde]/ athing 0: a fthing 0: f *** Failers 0: * ]thing No match cthing No match dthing No match ething No match /^\/ 0: \x81 /^ÿ/ ÿ 0: \xff /^[0-9]+$/ 0 0: 0 1 0: 1 2 0: 2 3 0: 3 4 0: 4 5 0: 5 6 0: 6 7 0: 7 8 0: 8 9 0: 9 10 0: 10 100 0: 100 *** Failers No match abc No match /^.*nter/ enter 0: enter inter 0: inter uponter 0: uponter /^xxx[0-9]+$/ xxx0 0: xxx0 xxx1234 0: xxx1234 *** Failers No match xxx No match /^.+[0-9][0-9][0-9]$/ x123 0: x123 xx123 0: xx123 123456 0: 123456 *** Failers No match 123 No match x1234 0: x1234 /^.+?[0-9][0-9][0-9]$/ x123 0: x123 xx123 0: xx123 123456 0: 123456 *** Failers No match 123 No match x1234 0: x1234 /^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ abc!pqr=apquxz.ixr.zzz.ac.uk 0: abc!pqr=apquxz.ixr.zzz.ac.uk 1: abc 2: pqr *** Failers No match !pqr=apquxz.ixr.zzz.ac.uk No match abc!=apquxz.ixr.zzz.ac.uk No match abc!pqr=apquxz:ixr.zzz.ac.uk No match abc!pqr=apquxz.ixr.zzz.ac.ukk No match /:/ Well, we need a colon: somewhere 0: : *** Fail if we don't No match /([\da-f:]+)$/i 0abc 0: 0abc 1: 0abc abc 0: abc 1: abc fed 0: fed 1: fed E 0: E 1: E :: 0: :: 1: :: 5f03:12C0::932e 0: 5f03:12C0::932e 1: 5f03:12C0::932e fed def 0: def 1: def Any old stuff 0: ff 1: ff *** Failers No match 0zzz No match gzzz No match fed\x20 No match Any old rubbish No match /^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ .1.2.3 0: .1.2.3 1: 1 2: 2 3: 3 A.12.123.0 0: A.12.123.0 1: 12 2: 123 3: 0 *** Failers No match .1.2.3333 No match 1.2.3 No match 1234.2.3 No match /^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ 1 IN SOA non-sp1 non-sp2( 0: 1 IN SOA non-sp1 non-sp2( 1: 1 2: non-sp1 3: non-sp2 1 IN SOA non-sp1 non-sp2 ( 0: 1 IN SOA non-sp1 non-sp2 ( 1: 1 2: non-sp1 3: non-sp2 *** Failers No match 1IN SOA non-sp1 non-sp2( No match /^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ a. 0: a. Z. 0: Z. 2. 0: 2. ab-c.pq-r. 0: ab-c.pq-r. 1: .pq-r sxk.zzz.ac.uk. 0: sxk.zzz.ac.uk. 1: .uk x-.y-. 0: x-.y-. 1: .y- *** Failers No match -abc.peq. No match /^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ *.a 0: *.a *.b0-a 0: *.b0-a 1: 0-a *.c3-b.c 0: *.c3-b.c 1: 3-b 2: .c *.c-a.b-c 0: *.c-a.b-c 1: -a 2: .b-c 3: -c *** Failers No match *.0 No match *.a- No match *.a-b.c- No match *.c-a.0-c No match /^(?=ab(de))(abd)(e)/ abde 0: abde 1: de 2: abd 3: e /^(?!(ab)de|x)(abd)(f)/ abdf 0: abdf 1: 2: abd 3: f /^(?=(ab(cd)))(ab)/ abcd 0: ab 1: abcd 2: cd 3: ab /^[\da-f](\.[\da-f])*$/i a.b.c.d 0: a.b.c.d 1: .d A.B.C.D 0: A.B.C.D 1: .D a.b.c.1.2.3.C 0: a.b.c.1.2.3.C 1: .C /^\".*\"\s*(;.*)?$/ \"1234\" 0: "1234" \"abcd\" ; 0: "abcd" ; 1: ; \"\" ; rhubarb 0: "" ; rhubarb 1: ; rhubarb *** Failers No match \"1234\" : things No match /^$/ \ 0: *** Failers No match / ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x ab c 0: ab c *** Failers No match abc No match ab cde No match /(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ ab c 0: ab c *** Failers No match abc No match ab cde No match /^ a\ b[c ]d $/x a bcd 0: a bcd a b d 0: a b d *** Failers No match abcd No match ab d No match /^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ abcdefhijklm 0: abcdefhijklm 1: abc 2: bc 3: c 4: def 5: ef 6: f 7: hij 8: ij 9: j 10: klm 11: lm 12: m /^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ abcdefhijklm 0: abcdefhijklm 1: bc 2: c 3: ef 4: f 5: ij 6: j 7: lm 8: m /^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ a+ Z0+\x08\n\x1d\x12 0: a+ Z0+\x08\x0a\x1d\x12 /^[.^$|()*+?{,}]+/ .^\$(*+)|{?,?} 0: .^$(*+)|{?,?} /^a*\w/ z 0: z az 0: az aaaz 0: aaaz a 0: a aa 0: aa aaaa 0: aaaa a+ 0: a aa+ 0: aa /^a*?\w/ z 0: z az 0: a aaaz 0: a a 0: a aa 0: a aaaa 0: a a+ 0: a aa+ 0: a /^a+\w/ az 0: az aaaz 0: aaaz aa 0: aa aaaa 0: aaaa aa+ 0: aa /^a+?\w/ az 0: az aaaz 0: aa aa 0: aa aaaa 0: aa aa+ 0: aa /^\d{8}\w{2,}/ 1234567890 0: 1234567890 12345678ab 0: 12345678ab 12345678__ 0: 12345678__ *** Failers No match 1234567 No match /^[aeiou\d]{4,5}$/ uoie 0: uoie 1234 0: 1234 12345 0: 12345 aaaaa 0: aaaaa *** Failers No match 123456 No match /^[aeiou\d]{4,5}?/ uoie 0: uoie 1234 0: 1234 12345 0: 1234 aaaaa 0: aaaa 123456 0: 1234 /\A(abc|def)=(\1){2,3}\Z/ abc=abcabc 0: abc=abcabc 1: abc 2: abc def=defdefdef 0: def=defdefdef 1: def 2: def *** Failers No match abc=defdef No match /^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\11*(\3\4)\1(?#)2$/ abcdefghijkcda2 0: abcdefghijkcda2 1: a 2: b 3: c 4: d 5: e 6: f 7: g 8: h 9: i 10: j 11: k 12: cd abcdefghijkkkkcda2 0: abcdefghijkkkkcda2 1: a 2: b 3: c 4: d 5: e 6: f 7: g 8: h 9: i 10: j 11: k 12: cd /(cat(a(ract|tonic)|erpillar)) \1()2(3)/ cataract cataract23 0: cataract cataract23 1: cataract 2: aract 3: ract 4: 5: 3 catatonic catatonic23 0: catatonic catatonic23 1: catatonic 2: atonic 3: tonic 4: 5: 3 caterpillar caterpillar23 0: caterpillar caterpillar23 1: caterpillar 2: erpillar 3: 4: 5: 3 /^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ From abcd Mon Sep 01 12:33:02 1997 0: From abcd Mon Sep 01 12:33 1: abcd /^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ From abcd Mon Sep 01 12:33:02 1997 0: From abcd Mon Sep 01 12:33 1: Sep From abcd Mon Sep 1 12:33:02 1997 0: From abcd Mon Sep 1 12:33 1: Sep *** Failers No match From abcd Sep 01 12:33:02 1997 No match /^12.34/s 12\n34 0: 12\x0a34 12\r34 0: 12\x0d34 /\w+(?=\t)/ the quick brown\t fox 0: brown /foo(?!bar)(.*)/ foobar is foolish see? 0: foolish see? 1: lish see? /(?:(?!foo)...|^.{0,2})bar(.*)/ foobar crowbar etc 0: rowbar etc 1: etc barrel 0: barrel 1: rel 2barrel 0: 2barrel 1: rel A barrel 0: A barrel 1: rel /^(\D*)(?=\d)(?!123)/ abc456 0: abc 1: abc *** Failers No match abc123 No match /^1234(?# test newlines inside)/ 1234 0: 1234 /^1234 #comment in extended re /x 1234 0: 1234 /#rhubarb abcd/x abcd 0: abcd /^abcd#rhubarb/x abcd 0: abcd /^(a)\1{2,3}(.)/ aaab 0: aaab 1: a 2: b aaaab 0: aaaab 1: a 2: b aaaaab 0: aaaaa 1: a 2: a aaaaaab 0: aaaaa 1: a 2: a /(?!^)abc/ the abc 0: abc *** Failers No match abc No match /(?=^)abc/ abc 0: abc *** Failers No match the abc No match /^[ab]{1,3}(ab*|b)/ aabbbbb 0: aabb 1: b /^[ab]{1,3}?(ab*|b)/ aabbbbb 0: aabbbbb 1: abbbbb /^[ab]{1,3}?(ab*?|b)/ aabbbbb 0: aa 1: a /^[ab]{1,3}(ab*?|b)/ aabbbbb 0: aabb 1: b / (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional leading comment (?: (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address | # or (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # one word, optionally followed by.... (?: [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) | # comments, or... " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote # quoted strings )* < (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # leading < (?: @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* , (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* )* # further okay, if led by comma : # closing colon (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* )? # optional route (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address spec (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* > # trailing > # name and address ) (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional trailing comment /x Alan Other 0: Alan Other 0: user@dom.ain user\@dom.ain 0: user@dom.ain \"A. Other\" (a comment) 0: "A. Other" (a comment) A. Other (a comment) 0: Other (a comment) \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay A missing angle @,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # additional words )* @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* # address | # or (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) # leading word [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces (?: (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) | " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " ) # "special" comment or quoted string [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" )* < [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # < (?: @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* (?: , [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* )* # additional domains : [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )? # optional route (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # additional words )* @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* # address spec > # > # name and address ) /x Alan Other 0: Alan Other 0: user@dom.ain user\@dom.ain 0: user@dom.ain \"A. Other\" (a comment) 0: "A. Other" A. Other (a comment) 0: Other \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay A missing angle ?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff /P[^*]TAIRE[^*]{1,6}?LL/ xxxxxxxxxxxPSTAIREISLLxxxxxxxxx 0: PSTAIREISLL /P[^*]TAIRE[^*]{1,}?LL/ xxxxxxxxxxxPSTAIREISLLxxxxxxxxx 0: PSTAIREISLL /(\.\d\d[1-9]?)\d+/ 1.230003938 0: .230003938 1: .23 1.875000282 0: .875000282 1: .875 1.235 0: .235 1: .23 /(\.\d\d((?=0)|\d(?=\d)))/ 1.230003938 0: .23 1: .23 2: 1.875000282 0: .875 1: .875 2: 5 *** Failers No match 1.235 No match /a(?)b/ ab 0: ab /\b(foo)\s+(\w+)/i Food is on the foo table 0: foo table 1: foo 2: table /foo(.*)bar/ The food is under the bar in the barn. 0: food is under the bar in the bar 1: d is under the bar in the /foo(.*?)bar/ The food is under the bar in the barn. 0: food is under the bar 1: d is under the /(.*)(\d*)/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 1: I have 2 numbers: 53147 2: /(.*)(\d+)/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 1: I have 2 numbers: 5314 2: 7 /(.*?)(\d*)/ I have 2 numbers: 53147 0: 1: 2: /(.*?)(\d+)/ I have 2 numbers: 53147 0: I have 2 1: I have 2: 2 /(.*)(\d+)$/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 1: I have 2 numbers: 5314 2: 7 /(.*?)(\d+)$/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 1: I have 2 numbers: 2: 53147 /(.*)\b(\d+)$/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 1: I have 2 numbers: 2: 53147 /(.*\D)(\d+)$/ I have 2 numbers: 53147 0: I have 2 numbers: 53147 1: I have 2 numbers: 2: 53147 /^\D*(?!123)/ ABC123 0: AB /^(\D*)(?=\d)(?!123)/ ABC445 0: ABC 1: ABC *** Failers No match ABC123 No match /^[W-]46]/ W46]789 0: W46] -46]789 0: -46] *** Failers No match Wall No match Zebra No match 42 No match [abcd] No match ]abcd[ No match /^[W-\]46]/ W46]789 0: W Wall 0: W Zebra 0: Z Xylophone 0: X 42 0: 4 [abcd] 0: [ ]abcd[ 0: ] \\backslash 0: \ *** Failers No match -46]789 No match well No match /\d\d\/\d\d\/\d\d\d\d/ 01/01/2000 0: 01/01/2000 /word (?:[a-zA-Z0-9]+ ){0,10}otherword/ word cat dog elephant mussel cow horse canary baboon snake shark otherword 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword word cat dog elephant mussel cow horse canary baboon snake shark No match /word (?:[a-zA-Z0-9]+ ){0,300}otherword/ word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope No match /^(a){0,0}/ bcd 0: abc 0: aab 0: /^(a){0,1}/ bcd 0: abc 0: a 1: a aab 0: a 1: a /^(a){0,2}/ bcd 0: abc 0: a 1: a aab 0: aa 1: a /^(a){0,3}/ bcd 0: abc 0: a 1: a aab 0: aa 1: a aaa 0: aaa 1: a /^(a){0,}/ bcd 0: abc 0: a 1: a aab 0: aa 1: a aaa 0: aaa 1: a aaaaaaaa 0: aaaaaaaa 1: a /^(a){1,1}/ bcd No match abc 0: a 1: a aab 0: a 1: a /^(a){1,2}/ bcd No match abc 0: a 1: a aab 0: aa 1: a /^(a){1,3}/ bcd No match abc 0: a 1: a aab 0: aa 1: a aaa 0: aaa 1: a /^(a){1,}/ bcd No match abc 0: a 1: a aab 0: aa 1: a aaa 0: aaa 1: a aaaaaaaa 0: aaaaaaaa 1: a /.*\.gif/ borfle\nbib.gif\nno 0: bib.gif /.{0,}\.gif/ borfle\nbib.gif\nno 0: bib.gif /.*\.gif/m borfle\nbib.gif\nno 0: bib.gif /.*\.gif/s borfle\nbib.gif\nno 0: borfle\x0abib.gif /.*\.gif/ms borfle\nbib.gif\nno 0: borfle\x0abib.gif /.*$/ borfle\nbib.gif\nno 0: no /.*$/m borfle\nbib.gif\nno 0: borfle /.*$/s borfle\nbib.gif\nno 0: borfle\x0abib.gif\x0ano /.*$/ms borfle\nbib.gif\nno 0: borfle\x0abib.gif\x0ano /.*$/ borfle\nbib.gif\nno\n 0: no /.*$/m borfle\nbib.gif\nno\n 0: borfle /.*$/s borfle\nbib.gif\nno\n 0: borfle\x0abib.gif\x0ano\x0a /.*$/ms borfle\nbib.gif\nno\n 0: borfle\x0abib.gif\x0ano\x0a /(.*X|^B)/ abcde\n1234Xyz 0: 1234X 1: 1234X BarFoo 0: B 1: B *** Failers No match abcde\nBar No match /(.*X|^B)/m abcde\n1234Xyz 0: 1234X 1: 1234X BarFoo 0: B 1: B abcde\nBar 0: B 1: B /(.*X|^B)/s abcde\n1234Xyz 0: abcde\x0a1234X 1: abcde\x0a1234X BarFoo 0: B 1: B *** Failers No match abcde\nBar No match /(.*X|^B)/ms abcde\n1234Xyz 0: abcde\x0a1234X 1: abcde\x0a1234X BarFoo 0: B 1: B abcde\nBar 0: B 1: B /(?s)(.*X|^B)/ abcde\n1234Xyz 0: abcde\x0a1234X 1: abcde\x0a1234X BarFoo 0: B 1: B *** Failers No match abcde\nBar No match /(?s:.*X|^B)/ abcde\n1234Xyz 0: abcde\x0a1234X BarFoo 0: B *** Failers No match abcde\nBar No match /^.*B/ **** Failers No match abc\nB No match /(?s)^.*B/ abc\nB 0: abc\x0aB /(?m)^.*B/ abc\nB 0: B /(?ms)^.*B/ abc\nB 0: abc\x0aB /(?ms)^B/ abc\nB 0: B /(?s)B$/ B\n 0: B /^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/ 123456654321 0: 123456654321 /^\d\d\d\d\d\d\d\d\d\d\d\d/ 123456654321 0: 123456654321 /^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/ 123456654321 0: 123456654321 /^[abc]{12}/ abcabcabcabc 0: abcabcabcabc /^[a-c]{12}/ abcabcabcabc 0: abcabcabcabc /^(a|b|c){12}/ abcabcabcabc 0: abcabcabcabc 1: c /^[abcdefghijklmnopqrstuvwxy0123456789]/ n 0: n *** Failers No match z No match /abcde{0,0}/ abcd 0: abcd *** Failers No match abce No match /ab[cd]{0,0}e/ abe 0: abe *** Failers No match abcde No match /ab(c){0,0}d/ abd 0: abd *** Failers No match abcd No match /a(b*)/ a 0: a 1: ab 0: ab 1: b abbbb 0: abbbb 1: bbbb *** Failers 0: a 1: bbbbb No match /ab\d{0}e/ abe 0: abe *** Failers No match ab1e No match /"([^\\"]+|\\.)*"/ the \"quick\" brown fox 0: "quick" 1: quick \"the \\\"quick\\\" brown fox\" 0: "the \"quick\" brown fox" 1: brown fox /.*?/g+ abc 0: 0+ abc 0: a 0+ bc 0: 0+ bc 0: b 0+ c 0: 0+ c 0: c 0+ 0: 0+ /\b/g+ abc 0: 0+ abc 0: 0+ /\b/+g abc 0: 0+ abc 0: 0+ //g abc 0: 0: 0: 0: /]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is 43.Word Processor
(N-1286)
Lega lstaff.comCA - Statewide 0: 43.Word Processor
(N-1286)
Lega lstaff.comCA - Statewide 1: BGCOLOR='#DBE9E9' 2: align=left valign=top 3: 43. 4: Word Processor
(N-1286) 5: 6: 7: 8: align=left valign=top 9: Lega lstaff.com 10: align=left valign=top 11: CA - Statewide /a[^a]b/ acb 0: acb a\nb 0: a\x0ab /a.b/ acb 0: acb *** Failers No match a\nb No match /a[^a]b/s acb 0: acb a\nb 0: a\x0ab /a.b/s acb 0: acb a\nb 0: a\x0ab /^(b+?|a){1,2}?c/ bac 0: bac 1: a bbac 0: bbac 1: a bbbac 0: bbbac 1: a bbbbac 0: bbbbac 1: a bbbbbac 0: bbbbbac 1: a /^(b+|a){1,2}?c/ bac 0: bac 1: a bbac 0: bbac 1: a bbbac 0: bbbac 1: a bbbbac 0: bbbbac 1: a bbbbbac 0: bbbbbac 1: a /(?!\A)x/m x\nb\n No match a\bx\n 0: x /\x0{ab}/ \0{ab} 0: \x00{ab} /(A|B)*?CD/ CD 0: CD /(A|B)*CD/ CD 0: CD /(AB)*?\1/ ABABAB 0: ABAB 1: AB /(AB)*\1/ ABABAB 0: ABABAB 1: AB /(?.*/)foo" /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ No match "(?>.*/)foo" /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo 0: /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo /(?>(\.\d\d[1-9]?))\d+/ 1.230003938 0: .230003938 1: .23 1.875000282 0: .875000282 1: .875 *** Failers No match 1.235 No match /^((?>\w+)|(?>\s+))*$/ now is the time for all good men to come to the aid of the party 0: now is the time for all good men to come to the aid of the party 1: party *** Failers No match this is not a line with only words and spaces! No match /(\d+)(\w)/ 12345a 0: 12345a 1: 12345 2: a 12345+ 0: 12345 1: 1234 2: 5 /((?>\d+))(\w)/ 12345a 0: 12345a 1: 12345 2: a *** Failers No match 12345+ No match /(?>a+)b/ aaab 0: aaab /((?>a+)b)/ aaab 0: aaab 1: aaab /(?>(a+))b/ aaab 0: aaab 1: aaa /(?>b)+/ aaabbbccc 0: bbb /(?>a+|b+|c+)*c/ aaabbbbccccd 0: aaabbbbc /((?>[^()]+)|\([^()]*\))+/ ((abc(ade)ufh()()x 0: abc(ade)ufh()()x 1: x /\(((?>[^()]+)|\([^()]+\))+\)/ (abc) 0: (abc) 1: abc (abc(def)xyz) 0: (abc(def)xyz) 1: xyz *** Failers No match ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match /a(?-i)b/i ab 0: ab Ab 0: Ab *** Failers No match aB No match AB No match /(a (?x)b c)d e/ a bcd e 0: a bcd e 1: a bc *** Failers No match a b cd e No match abcd e No match a bcde No match /(a b(?x)c d (?-x)e f)/ a bcde f 0: a bcde f 1: a bcde f *** Failers No match abcdef No match /(a(?i)b)c/ abc 0: abc 1: ab aBc 0: aBc 1: aB *** Failers No match abC No match aBC No match Abc No match ABc No match ABC No match AbC No match /a(?i:b)c/ abc 0: abc aBc 0: aBc *** Failers No match ABC No match abC No match aBC No match /a(?i:b)*c/ aBc 0: aBc aBBc 0: aBBc *** Failers No match aBC No match aBBC No match /a(?=b(?i)c)\w\wd/ abcd 0: abcd abCd 0: abCd *** Failers No match aBCd No match abcD No match /(?s-i:more.*than).*million/i more than million 0: more than million more than MILLION 0: more than MILLION more \n than Million 0: more \x0a than Million *** Failers No match MORE THAN MILLION No match more \n than \n million No match /(?:(?s-i)more.*than).*million/i more than million 0: more than million more than MILLION 0: more than MILLION more \n than Million 0: more \x0a than Million *** Failers No match MORE THAN MILLION No match more \n than \n million No match /(?>a(?i)b+)+c/ abc 0: abc aBbc 0: aBbc aBBc 0: aBBc *** Failers No match Abc No match abAb No match abbC No match /(?=a(?i)b)\w\wc/ abc 0: abc aBc 0: aBc *** Failers No match Ab No match abC No match aBC No match /(?<=a(?i)b)(\w\w)c/ abxxc 0: xxc 1: xx aBxxc 0: xxc 1: xx *** Failers No match Abxxc No match ABxxc No match abxxC No match /(?:(a)|b)(?(1)A|B)/ aA 0: aA 1: a bB 0: bB *** Failers No match aB No match bA No match /^(a)?(?(1)a|b)+$/ aa 0: aa 1: a b 0: b bb 0: bb *** Failers No match ab No match /^(?(?=abc)\w{3}:|\d\d)$/ abc: 0: abc: 12 0: 12 *** Failers No match 123 No match xyz No match /^(?(?!abc)\d\d|\w{3}:)$/ abc: 0: abc: 12 0: 12 *** Failers No match 123 No match xyz No match /(?(?<=foo)bar|cat)/ foobar 0: bar cat 0: cat fcat 0: cat focat 0: cat *** Failers No match foocat No match /(?(?a*)*/ a 0: a aa 0: aa aaaa 0: aaaa /(abc|)+/ abc 0: abc 1: abcabc 0: abcabc 1: abcabcabc 0: abcabcabc 1: xyz 0: 1: /([a]*)*/ a 0: a 1: aaaaa 0: aaaaa 1: /([ab]*)*/ a 0: a 1: b 0: b 1: ababab 0: ababab 1: aaaabcde 0: aaaab 1: bbbb 0: bbbb 1: /([^a]*)*/ b 0: b 1: bbbb 0: bbbb 1: aaa 0: 1: /([^ab]*)*/ cccc 0: cccc 1: abab 0: 1: /([a]*?)*/ a 0: 1: aaaa 0: 1: /([ab]*?)*/ a 0: 1: b 0: 1: abab 0: 1: baba 0: 1: /([^a]*?)*/ b 0: 1: bbbb 0: 1: aaa 0: 1: /([^ab]*?)*/ c 0: 1: cccc 0: 1: baba 0: 1: /(?>a*)*/ a 0: a aaabcde 0: aaa /((?>a*))*/ aaaaa 0: aaaaa 1: aabbaa 0: aa 1: /((?>a*?))*/ aaaaa 0: 1: aabbaa 0: 1: /(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x 12-sep-98 0: 12-sep-98 12-09-98 0: 12-09-98 *** Failers No match sep-12-98 No match /(?<=(foo))bar\1/ foobarfoo 0: barfoo 1: foo foobarfootling 0: barfoo 1: foo *** Failers No match foobar No match barfoo No match /(?i:saturday|sunday)/ saturday 0: saturday sunday 0: sunday Saturday 0: Saturday Sunday 0: Sunday SATURDAY 0: SATURDAY SUNDAY 0: SUNDAY SunDay 0: SunDay /(a(?i)bc|BB)x/ abcx 0: abcx 1: abc aBCx 0: aBCx 1: aBC bbx 0: bbx 1: bb BBx 0: BBx 1: BB *** Failers No match abcX No match aBCX No match bbX No match BBX No match /^([ab](?i)[cd]|[ef])/ ac 0: ac 1: ac aC 0: aC 1: aC bD 0: bD 1: bD elephant 0: e 1: e Europe 0: E 1: E frog 0: f 1: f France 0: F 1: F *** Failers No match Africa No match /^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ ab 0: ab 1: ab aBd 0: aBd 1: aBd xy 0: xy 1: xy xY 0: xY 1: xY zebra 0: z 1: z Zambesi 0: Z 1: Z *** Failers No match aCD No match XY No match /(?<=foo\n)^bar/m foo\nbar 0: bar *** Failers No match bar No match baz\nbar No match /(?<=(?]&/ <&OUT 0: <& /^(a\1?){4}$/ aaaaaaaaaa 0: aaaaaaaaaa 1: aaaa *** Failers No match AB No match aaaaaaaaa No match aaaaaaaaaaa No match /^(a(?(1)\1)){4}$/ aaaaaaaaaa 0: aaaaaaaaaa 1: aaaa *** Failers No match aaaaaaaaa No match aaaaaaaaaaa No match /(?:(f)(o)(o)|(b)(a)(r))*/ foobar 0: foobar 1: f 2: o 3: o 4: b 5: a 6: r /(?<=a)b/ ab 0: b *** Failers No match cb No match b No match /(? 2: abcd xy:z:::abcd 0: xy:z:::abcd 1: xy:z::: 2: abcd /^[^bcd]*(c+)/ aexycd 0: aexyc 1: c /(a*)b+/ caab 0: aab 1: aa /([\w:]+::)?(\w+)$/ abcd 0: abcd 1: 2: abcd xy:z:::abcd 0: xy:z:::abcd 1: xy:z::: 2: abcd *** Failers 0: Failers 1: 2: Failers abcd: No match abcd: No match /^[^bcd]*(c+)/ aexycd 0: aexyc 1: c /(>a+)ab/ /(?>a+)b/ aaab 0: aaab /([[:]+)/ a:[b]: 0: :[ 1: :[ /([[=]+)/ a=[b]= 0: =[ 1: =[ /([[.]+)/ a.[b]. 0: .[ 1: .[ /((?>a+)b)/ aaab 0: aaab 1: aaab /(?>(a+))b/ aaab 0: aaab 1: aaa /((?>[^()]+)|\([^()]*\))+/ ((abc(ade)ufh()()x 0: abc(ade)ufh()()x 1: x /a\Z/ *** Failers No match aaab No match a\nb\n No match /b\Z/ a\nb\n 0: b /b\z/ /b\Z/ a\nb 0: b /b\z/ a\nb 0: b *** Failers No match /^(?>(?(1)\.|())[^\W_](?>[a-z0-9-]*[^\W_])?)+$/ a 0: a 1: abc 0: abc 1: a-b 0: a-b 1: 0-9 0: 0-9 1: a.b 0: a.b 1: 5.6.7 0: 5.6.7 1: the.quick.brown.fox 0: the.quick.brown.fox 1: a100.b200.300c 0: a100.b200.300c 1: 12-ab.1245 0: 12-ab.1245 1: *** Failers No match \ No match .a No match -a No match a- No match a. No match a_b No match a.- No match a.. No match ab..bc No match the.quick.brown.fox- No match the.quick.brown.fox. No match the.quick.brown.fox_ No match the.quick.brown.fox+ No match /(?>.*)(?<=(abcd|wxyz))/ alphabetabcd 0: alphabetabcd 1: abcd endingwxyz 0: endingwxyz 1: wxyz *** Failers No match a rather long string that doesn't end with one of them No match /word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ word cat dog elephant mussel cow horse canary baboon snake shark otherword 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword word cat dog elephant mussel cow horse canary baboon snake shark No match /word (?>[a-zA-Z0-9]+ ){0,30}otherword/ word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope No match /(?<=\d{3}(?!999))foo/ 999foo 0: foo 123999foo 0: foo *** Failers No match 123abcfoo No match /(?<=(?!...999)\d{3})foo/ 999foo 0: foo 123999foo 0: foo *** Failers No match 123abcfoo No match /(?<=\d{3}(?!999)...)foo/ 123abcfoo 0: foo 123456foo 0: foo *** Failers No match 123999foo No match /(?<=\d{3}...)(? 2: 3: abcd
2: 3: abcd \s*)=(?>\s*) # find 2: 3: abcd Z)+|A)*/ ZABCDEFG 0: ZA 1: A /((?>)+|A)*/ ZABCDEFG 0: 1: /a*/g abbab 0: a 0: 0: 0: a 0: 0: /^[a-\d]/ abcde 0: a -things 0: - 0digit 0: 0 *** Failers No match bcdef No match /^[\d-a]/ abcde 0: a -things 0: - 0digit 0: 0 *** Failers No match bcdef No match /[[:space:]]+/ > \x09\x0a\x0c\x0d\x0b< 0: \x09\x0a\x0c\x0d\x0b /[[:blank:]]+/ > \x09\x0a\x0c\x0d\x0b< 0: \x09 /[\s]+/ > \x09\x0a\x0c\x0d\x0b< 0: \x09\x0a\x0c\x0d /\s+/ > \x09\x0a\x0c\x0d\x0b< 0: \x09\x0a\x0c\x0d /a b/x ab No match /(?!\A)x/m a\nxb\n 0: x /(?!^)x/m a\nxb\n No match /abc\Qabc\Eabc/ abcabcabc 0: abcabcabc /abc\Q(*+|\Eabc/ abc(*+|abc 0: abc(*+|abc / abc\Q abc\Eabc/x abc abcabc 0: abc abcabc *** Failers No match abcabcabc No match /abc#comment \Q#not comment literal\E/x abc#not comment\n literal 0: abc#not comment\x0a literal /abc#comment \Q#not comment literal/x abc#not comment\n literal 0: abc#not comment\x0a literal /abc#comment \Q#not comment literal\E #more comment /x abc#not comment\n literal 0: abc#not comment\x0a literal /abc#comment \Q#not comment literal\E #more comment/x abc#not comment\n literal 0: abc#not comment\x0a literal /\Qabc\$xyz\E/ abc\\\$xyz 0: abc\$xyz /\Qabc\E\$\Qxyz\E/ abc\$xyz 0: abc$xyz /\Gabc/ abc 0: abc *** Failers No match xyzabc No match /\Gabc./g abc1abc2xyzabc3 0: abc1 0: abc2 /abc./g abc1abc2xyzabc3 0: abc1 0: abc2 0: abc3 /a(?x: b c )d/ XabcdY 0: abcd *** Failers No match Xa b c d Y No match /((?x)x y z | a b c)/ XabcY 0: abc 1: abc AxyzB 0: xyz 1: xyz /(?i)AB(?-i)C/ XabCY 0: abC *** Failers No match XabcY No match /((?i)AB(?-i)C|D)E/ abCE 0: abCE 1: abC DE 0: DE 1: D *** Failers No match abcE No match abCe No match dE No match De No match /(.*)\d+\1/ abc123abc 0: abc123abc 1: abc abc123bc 0: bc123bc 1: bc /(.*)\d+\1/s abc123abc 0: abc123abc 1: abc abc123bc 0: bc123bc 1: bc /((.*))\d+\1/ abc123abc 0: abc123abc 1: abc 2: abc abc123bc 0: bc123bc 1: bc 2: bc /-- This tests for an IPv6 address in the form where it can have up to --/ /-- eight components, one and only one of which is empty. This must be --/ No match /-- an internal component. --/ No match /^(?!:) # colon disallowed at start (?: # start of item (?: [0-9a-f]{1,4} | # 1-4 hex digits or (?(1)0 | () ) ) # if null previously matched, fail; else null : # followed by colon ){1,7} # end item; 1-7 of them required [0-9a-f]{1,4} $ # final hex number at end of string (?(1)|.) # check that there was an empty component /xi a123::a123 0: a123::a123 1: a123:b342::abcd 0: a123:b342::abcd 1: a123:b342::324e:abcd 0: a123:b342::324e:abcd 1: a123:ddde:b342::324e:abcd 0: a123:ddde:b342::324e:abcd 1: a123:ddde:b342::324e:dcba:abcd 0: a123:ddde:b342::324e:dcba:abcd 1: a123:ddde:9999:b342::324e:dcba:abcd 0: a123:ddde:9999:b342::324e:dcba:abcd 1: *** Failers No match 1:2:3:4:5:6:7:8 No match a123:bce:ddde:9999:b342::324e:dcba:abcd No match a123::9999:b342::324e:dcba:abcd No match abcde:2:3:4:5:6:7:8 No match ::1 No match abcd:fee0:123:: No match :1 No match 1: No match /[z\Qa-d]\E]/ z 0: z a 0: a - 0: - d 0: d ] 0: ] *** Failers 0: a b No match /[\z\C]/ z 0: z C 0: C /\M/ M 0: M /(a+)*b/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match /(?i)reg(?:ul(?:[aä]|ae)r|ex)/ REGular 0: REGular regulaer 0: regulaer Regex 0: Regex regulär 0: regul\xe4r /Åæåä[à-ÿÀ-ß]+/ Åæåäà 0: \xc5\xe6\xe5\xe4\xe0 Åæåäÿ 0: \xc5\xe6\xe5\xe4\xff ÅæåäÀ 0: \xc5\xe6\xe5\xe4\xc0 Åæåäß 0: \xc5\xe6\xe5\xe4\xdf /(?<=Z)X./ \x84XAZXB 0: XB / End of testinput1 / tomcat-connectors-1.2.41-src/native/iis/pcre/testdata/testinput10000644000000000000020000022032410517277132023202 0ustar rootbin/the quick brown fox/ the quick brown fox The quick brown FOX What do you know about the quick brown fox? What do you know about THE QUICK BROWN FOX? /The quick brown fox/i the quick brown fox The quick brown FOX What do you know about the quick brown fox? What do you know about THE QUICK BROWN FOX? /abcd\t\n\r\f\a\e\071\x3b\$\\\?caxyz/ abcd\t\n\r\f\a\e9;\$\\?caxyz /a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz/ abxyzpqrrrabbxyyyypqAzz abxyzpqrrrabbxyyyypqAzz aabxyzpqrrrabbxyyyypqAzz aaabxyzpqrrrabbxyyyypqAzz aaaabxyzpqrrrabbxyyyypqAzz abcxyzpqrrrabbxyyyypqAzz aabcxyzpqrrrabbxyyyypqAzz aaabcxyzpqrrrabbxyyyypAzz aaabcxyzpqrrrabbxyyyypqAzz aaabcxyzpqrrrabbxyyyypqqAzz aaabcxyzpqrrrabbxyyyypqqqAzz aaabcxyzpqrrrabbxyyyypqqqqAzz aaabcxyzpqrrrabbxyyyypqqqqqAzz aaabcxyzpqrrrabbxyyyypqqqqqqAzz aaaabcxyzpqrrrabbxyyyypqAzz abxyzzpqrrrabbxyyyypqAzz aabxyzzzpqrrrabbxyyyypqAzz aaabxyzzzzpqrrrabbxyyyypqAzz aaaabxyzzzzpqrrrabbxyyyypqAzz abcxyzzpqrrrabbxyyyypqAzz aabcxyzzzpqrrrabbxyyyypqAzz aaabcxyzzzzpqrrrabbxyyyypqAzz aaaabcxyzzzzpqrrrabbxyyyypqAzz aaaabcxyzzzzpqrrrabbbxyyyypqAzz aaaabcxyzzzzpqrrrabbbxyyyyypqAzz aaabcxyzpqrrrabbxyyyypABzz aaabcxyzpqrrrabbxyyyypABBzz >>>aaabxyzpqrrrabbxyyyypqAzz >aaaabxyzpqrrrabbxyyyypqAzz >>>>abcxyzpqrrrabbxyyyypqAzz *** Failers abxyzpqrrabbxyyyypqAzz abxyzpqrrrrabbxyyyypqAzz abxyzpqrrrabxyyyypqAzz aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz aaaabcxyzzzzpqrrrabbbxyyypqAzz aaabcxyzpqrrrabbxyyyypqqqqqqqAzz /^(abc){1,2}zz/ abczz abcabczz *** Failers zz abcabcabczz >>abczz /^(b+?|a){1,2}?c/ bc bbc bbbc bac bbac aac abbbbbbbbbbbc bbbbbbbbbbbac *** Failers aaac abbbbbbbbbbbac /^(b+|a){1,2}c/ bc bbc bbbc bac bbac aac abbbbbbbbbbbc bbbbbbbbbbbac *** Failers aaac abbbbbbbbbbbac /^(b+|a){1,2}?bc/ bbc /^(b*|ba){1,2}?bc/ babc bbabc bababc *** Failers bababbc babababc /^(ba|b*){1,2}?bc/ babc bbabc bababc *** Failers bababbc babababc /^\ca\cA\c[\c{\c:/ \x01\x01\e;z /^[ab\]cde]/ athing bthing ]thing cthing dthing ething *** Failers fthing [thing \\thing /^[]cde]/ ]thing cthing dthing ething *** Failers athing fthing /^[^ab\]cde]/ fthing [thing \\thing *** Failers athing bthing ]thing cthing dthing ething /^[^]cde]/ athing fthing *** Failers ]thing cthing dthing ething /^\/ /^ÿ/ ÿ /^[0-9]+$/ 0 1 2 3 4 5 6 7 8 9 10 100 *** Failers abc /^.*nter/ enter inter uponter /^xxx[0-9]+$/ xxx0 xxx1234 *** Failers xxx /^.+[0-9][0-9][0-9]$/ x123 xx123 123456 *** Failers 123 x1234 /^.+?[0-9][0-9][0-9]$/ x123 xx123 123456 *** Failers 123 x1234 /^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/ abc!pqr=apquxz.ixr.zzz.ac.uk *** Failers !pqr=apquxz.ixr.zzz.ac.uk abc!=apquxz.ixr.zzz.ac.uk abc!pqr=apquxz:ixr.zzz.ac.uk abc!pqr=apquxz.ixr.zzz.ac.ukk /:/ Well, we need a colon: somewhere *** Fail if we don't /([\da-f:]+)$/i 0abc abc fed E :: 5f03:12C0::932e fed def Any old stuff *** Failers 0zzz gzzz fed\x20 Any old rubbish /^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ .1.2.3 A.12.123.0 *** Failers .1.2.3333 1.2.3 1234.2.3 /^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/ 1 IN SOA non-sp1 non-sp2( 1 IN SOA non-sp1 non-sp2 ( *** Failers 1IN SOA non-sp1 non-sp2( /^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/ a. Z. 2. ab-c.pq-r. sxk.zzz.ac.uk. x-.y-. *** Failers -abc.peq. /^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/ *.a *.b0-a *.c3-b.c *.c-a.b-c *** Failers *.0 *.a- *.a-b.c- *.c-a.0-c /^(?=ab(de))(abd)(e)/ abde /^(?!(ab)de|x)(abd)(f)/ abdf /^(?=(ab(cd)))(ab)/ abcd /^[\da-f](\.[\da-f])*$/i a.b.c.d A.B.C.D a.b.c.1.2.3.C /^\".*\"\s*(;.*)?$/ \"1234\" \"abcd\" ; \"\" ; rhubarb *** Failers \"1234\" : things /^$/ \ *** Failers / ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/x ab c *** Failers abc ab cde /(?x) ^ a (?# begins with a) b\sc (?# then b c) $ (?# then end)/ ab c *** Failers abc ab cde /^ a\ b[c ]d $/x a bcd a b d *** Failers abcd ab d /^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/ abcdefhijklm /^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/ abcdefhijklm /^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/ a+ Z0+\x08\n\x1d\x12 /^[.^$|()*+?{,}]+/ .^\$(*+)|{?,?} /^a*\w/ z az aaaz a aa aaaa a+ aa+ /^a*?\w/ z az aaaz a aa aaaa a+ aa+ /^a+\w/ az aaaz aa aaaa aa+ /^a+?\w/ az aaaz aa aaaa aa+ /^\d{8}\w{2,}/ 1234567890 12345678ab 12345678__ *** Failers 1234567 /^[aeiou\d]{4,5}$/ uoie 1234 12345 aaaaa *** Failers 123456 /^[aeiou\d]{4,5}?/ uoie 1234 12345 aaaaa 123456 /\A(abc|def)=(\1){2,3}\Z/ abc=abcabc def=defdefdef *** Failers abc=defdef /^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\11*(\3\4)\1(?#)2$/ abcdefghijkcda2 abcdefghijkkkkcda2 /(cat(a(ract|tonic)|erpillar)) \1()2(3)/ cataract cataract23 catatonic catatonic23 caterpillar caterpillar23 /^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/ From abcd Mon Sep 01 12:33:02 1997 /^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/ From abcd Mon Sep 01 12:33:02 1997 From abcd Mon Sep 1 12:33:02 1997 *** Failers From abcd Sep 01 12:33:02 1997 /^12.34/s 12\n34 12\r34 /\w+(?=\t)/ the quick brown\t fox /foo(?!bar)(.*)/ foobar is foolish see? /(?:(?!foo)...|^.{0,2})bar(.*)/ foobar crowbar etc barrel 2barrel A barrel /^(\D*)(?=\d)(?!123)/ abc456 *** Failers abc123 /^1234(?# test newlines inside)/ 1234 /^1234 #comment in extended re /x 1234 /#rhubarb abcd/x abcd /^abcd#rhubarb/x abcd /^(a)\1{2,3}(.)/ aaab aaaab aaaaab aaaaaab /(?!^)abc/ the abc *** Failers abc /(?=^)abc/ abc *** Failers the abc /^[ab]{1,3}(ab*|b)/ aabbbbb /^[ab]{1,3}?(ab*|b)/ aabbbbb /^[ab]{1,3}?(ab*?|b)/ aabbbbb /^[ab]{1,3}(ab*?|b)/ aabbbbb / (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional leading comment (?: (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address | # or (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # one word, optionally followed by.... (?: [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] | # atom and space parts, or... \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) | # comments, or... " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote # quoted strings )* < (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # leading < (?: @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* , (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* )* # further okay, if led by comma : # closing colon (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* )? # optional route (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) # initial word (?: (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | " (?: # opening quote... [^\\\x80-\xff\n\015"] # Anything except backslash and quote | # or \\ [^\x80-\xff] # Escaped something (something != CR) )* " # closing quote ) )* # further okay, if led by a period (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* @ (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # initial subdomain (?: # (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* \. # if led by a period... (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) # ...further okay )* # address spec (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* > # trailing > # name and address ) (?: [\040\t] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] | \( (?: [^\\\x80-\xff\n\015()] | \\ [^\x80-\xff] )* \) )* \) )* # optional trailing comment /x Alan Other user\@dom.ain \"A. Other\" (a comment) A. Other (a comment) \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay A missing angle @,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # additional words )* @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* # address | # or (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) # leading word [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # "normal" atoms and or spaces (?: (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) | " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " ) # "special" comment or quoted string [^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] * # more "normal" )* < [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # < (?: @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* (?: , [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* )* # additional domains : [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )? # optional route (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom # Atom | # or " # " [^\\\x80-\xff\n\015"] * # normal (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015"] * )* # ( special normal* )* " # " # Quoted string ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # additional words )* @ [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments (?: \. [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. (?: [^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+ # some number of atom characters... (?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom | \[ # [ (?: [^\\\x80-\xff\n\015\[\]] | \\ [^\x80-\xff] )* # stuff \] # ] ) [\040\t]* # Nab whitespace. (?: \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: # ( (?: \\ [^\x80-\xff] | \( # ( [^\\\x80-\xff\n\015()] * # normal* (?: \\ [^\x80-\xff] [^\\\x80-\xff\n\015()] * )* # (special normal*)* \) # ) ) # special [^\\\x80-\xff\n\015()] * # normal* )* # )* \) # ) [\040\t]* )* # If comment found, allow more spaces. # optional trailing comments )* # address spec > # > # name and address ) /x Alan Other user\@dom.ain \"A. Other\" (a comment) A. Other (a comment) \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay A missing angle ]{0,})>]{0,})>([\d]{0,}\.)(.*)((
([\w\W\s\d][^<>]{0,})|[\s]{0,}))<\/a><\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD>]{0,})>([\w\W\s\d][^<>]{0,})<\/TD><\/TR>/is 43.
Word Processor
(N-1286)
Lega lstaff.comCA - Statewide /a[^a]b/ acb a\nb /a.b/ acb *** Failers a\nb /a[^a]b/s acb a\nb /a.b/s acb a\nb /^(b+?|a){1,2}?c/ bac bbac bbbac bbbbac bbbbbac /^(b+|a){1,2}?c/ bac bbac bbbac bbbbac bbbbbac /(?!\A)x/m x\nb\n a\bx\n /\x0{ab}/ \0{ab} /(A|B)*?CD/ CD /(A|B)*CD/ CD /(AB)*?\1/ ABABAB /(AB)*\1/ ABABAB /(?.*/)foo" /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/ "(?>.*/)foo" /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo /(?>(\.\d\d[1-9]?))\d+/ 1.230003938 1.875000282 *** Failers 1.235 /^((?>\w+)|(?>\s+))*$/ now is the time for all good men to come to the aid of the party *** Failers this is not a line with only words and spaces! /(\d+)(\w)/ 12345a 12345+ /((?>\d+))(\w)/ 12345a *** Failers 12345+ /(?>a+)b/ aaab /((?>a+)b)/ aaab /(?>(a+))b/ aaab /(?>b)+/ aaabbbccc /(?>a+|b+|c+)*c/ aaabbbbccccd /((?>[^()]+)|\([^()]*\))+/ ((abc(ade)ufh()()x /\(((?>[^()]+)|\([^()]+\))+\)/ (abc) (abc(def)xyz) *** Failers ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /a(?-i)b/i ab Ab *** Failers aB AB /(a (?x)b c)d e/ a bcd e *** Failers a b cd e abcd e a bcde /(a b(?x)c d (?-x)e f)/ a bcde f *** Failers abcdef /(a(?i)b)c/ abc aBc *** Failers abC aBC Abc ABc ABC AbC /a(?i:b)c/ abc aBc *** Failers ABC abC aBC /a(?i:b)*c/ aBc aBBc *** Failers aBC aBBC /a(?=b(?i)c)\w\wd/ abcd abCd *** Failers aBCd abcD /(?s-i:more.*than).*million/i more than million more than MILLION more \n than Million *** Failers MORE THAN MILLION more \n than \n million /(?:(?s-i)more.*than).*million/i more than million more than MILLION more \n than Million *** Failers MORE THAN MILLION more \n than \n million /(?>a(?i)b+)+c/ abc aBbc aBBc *** Failers Abc abAb abbC /(?=a(?i)b)\w\wc/ abc aBc *** Failers Ab abC aBC /(?<=a(?i)b)(\w\w)c/ abxxc aBxxc *** Failers Abxxc ABxxc abxxC /(?:(a)|b)(?(1)A|B)/ aA bB *** Failers aB bA /^(a)?(?(1)a|b)+$/ aa b bb *** Failers ab /^(?(?=abc)\w{3}:|\d\d)$/ abc: 12 *** Failers 123 xyz /^(?(?!abc)\d\d|\w{3}:)$/ abc: 12 *** Failers 123 xyz /(?(?<=foo)bar|cat)/ foobar cat fcat focat *** Failers foocat /(?(?a*)*/ a aa aaaa /(abc|)+/ abc abcabc abcabcabc xyz /([a]*)*/ a aaaaa /([ab]*)*/ a b ababab aaaabcde bbbb /([^a]*)*/ b bbbb aaa /([^ab]*)*/ cccc abab /([a]*?)*/ a aaaa /([ab]*?)*/ a b abab baba /([^a]*?)*/ b bbbb aaa /([^ab]*?)*/ c cccc baba /(?>a*)*/ a aaabcde /((?>a*))*/ aaaaa aabbaa /((?>a*?))*/ aaaaa aabbaa /(?(?=[^a-z]+[a-z]) \d{2}-[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) /x 12-sep-98 12-09-98 *** Failers sep-12-98 /(?<=(foo))bar\1/ foobarfoo foobarfootling *** Failers foobar barfoo /(?i:saturday|sunday)/ saturday sunday Saturday Sunday SATURDAY SUNDAY SunDay /(a(?i)bc|BB)x/ abcx aBCx bbx BBx *** Failers abcX aBCX bbX BBX /^([ab](?i)[cd]|[ef])/ ac aC bD elephant Europe frog France *** Failers Africa /^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/ ab aBd xy xY zebra Zambesi *** Failers aCD XY /(?<=foo\n)^bar/m foo\nbar *** Failers bar baz\nbar /(?<=(?]&/ <&OUT /^(a\1?){4}$/ aaaaaaaaaa *** Failers AB aaaaaaaaa aaaaaaaaaaa /^(a(?(1)\1)){4}$/ aaaaaaaaaa *** Failers aaaaaaaaa aaaaaaaaaaa /(?:(f)(o)(o)|(b)(a)(r))*/ foobar /(?<=a)b/ ab *** Failers cb b /(?a+)ab/ /(?>a+)b/ aaab /([[:]+)/ a:[b]: /([[=]+)/ a=[b]= /([[.]+)/ a.[b]. /((?>a+)b)/ aaab /(?>(a+))b/ aaab /((?>[^()]+)|\([^()]*\))+/ ((abc(ade)ufh()()x /a\Z/ *** Failers aaab a\nb\n /b\Z/ a\nb\n /b\z/ /b\Z/ a\nb /b\z/ a\nb *** Failers /^(?>(?(1)\.|())[^\W_](?>[a-z0-9-]*[^\W_])?)+$/ a abc a-b 0-9 a.b 5.6.7 the.quick.brown.fox a100.b200.300c 12-ab.1245 *** Failers \ .a -a a- a. a_b a.- a.. ab..bc the.quick.brown.fox- the.quick.brown.fox. the.quick.brown.fox_ the.quick.brown.fox+ /(?>.*)(?<=(abcd|wxyz))/ alphabetabcd endingwxyz *** Failers a rather long string that doesn't end with one of them /word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/ word cat dog elephant mussel cow horse canary baboon snake shark otherword word cat dog elephant mussel cow horse canary baboon snake shark /word (?>[a-zA-Z0-9]+ ){0,30}otherword/ word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope /(?<=\d{3}(?!999))foo/ 999foo 123999foo *** Failers 123abcfoo /(?<=(?!...999)\d{3})foo/ 999foo 123999foo *** Failers 123abcfoo /(?<=\d{3}(?!999)...)foo/ 123abcfoo 123456foo *** Failers 123999foo /(?<=\d{3}...)(?\s*)=(?>\s*) # find Z)+|A)*/ ZABCDEFG /((?>)+|A)*/ ZABCDEFG /a*/g abbab /^[a-\d]/ abcde -things 0digit *** Failers bcdef /^[\d-a]/ abcde -things 0digit *** Failers bcdef /[[:space:]]+/ > \x09\x0a\x0c\x0d\x0b< /[[:blank:]]+/ > \x09\x0a\x0c\x0d\x0b< /[\s]+/ > \x09\x0a\x0c\x0d\x0b< /\s+/ > \x09\x0a\x0c\x0d\x0b< /a b/x ab /(?!\A)x/m a\nxb\n /(?!^)x/m a\nxb\n /abc\Qabc\Eabc/ abcabcabc /abc\Q(*+|\Eabc/ abc(*+|abc / abc\Q abc\Eabc/x abc abcabc *** Failers abcabcabc /abc#comment \Q#not comment literal\E/x abc#not comment\n literal /abc#comment \Q#not comment literal/x abc#not comment\n literal /abc#comment \Q#not comment literal\E #more comment /x abc#not comment\n literal /abc#comment \Q#not comment literal\E #more comment/x abc#not comment\n literal /\Qabc\$xyz\E/ abc\\\$xyz /\Qabc\E\$\Qxyz\E/ abc\$xyz /\Gabc/ abc *** Failers xyzabc /\Gabc./g abc1abc2xyzabc3 /abc./g abc1abc2xyzabc3 /a(?x: b c )d/ XabcdY *** Failers Xa b c d Y /((?x)x y z | a b c)/ XabcY AxyzB /(?i)AB(?-i)C/ XabCY *** Failers XabcY /((?i)AB(?-i)C|D)E/ abCE DE *** Failers abcE abCe dE De /(.*)\d+\1/ abc123abc abc123bc /(.*)\d+\1/s abc123abc abc123bc /((.*))\d+\1/ abc123abc abc123bc /-- This tests for an IPv6 address in the form where it can have up to --/ /-- eight components, one and only one of which is empty. This must be --/ /-- an internal component. --/ /^(?!:) # colon disallowed at start (?: # start of item (?: [0-9a-f]{1,4} | # 1-4 hex digits or (?(1)0 | () ) ) # if null previously matched, fail; else null : # followed by colon ){1,7} # end item; 1-7 of them required [0-9a-f]{1,4} $ # final hex number at end of string (?(1)|.) # check that there was an empty component /xi a123::a123 a123:b342::abcd a123:b342::324e:abcd a123:ddde:b342::324e:abcd a123:ddde:b342::324e:dcba:abcd a123:ddde:9999:b342::324e:dcba:abcd *** Failers 1:2:3:4:5:6:7:8 a123:bce:ddde:9999:b342::324e:dcba:abcd a123::9999:b342::324e:dcba:abcd abcde:2:3:4:5:6:7:8 ::1 abcd:fee0:123:: :1 1: /[z\Qa-d]\E]/ z a - d ] *** Failers b /[\z\C]/ z C /\M/ M /(a+)*b/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /(?i)reg(?:ul(?:[aä]|ae)r|ex)/ REGular regulaer Regex regulär /Åæåä[à-ÿÀ-ß]+/ Åæåäà Åæåäÿ ÅæåäÀ Åæåäß /(?<=Z)X./ \x84XAZXB / End of testinput1 / tomcat-connectors-1.2.41-src/native/iis/pcre/testdata/testinput30000644000000000000020000000112410517277132023177 0ustar rootbin/^[\w]+/ *** Failers École /^[\w]+/Lfr_FR École /^[\w]+/ *** Failers École /^[\W]+/ École /^[\W]+/Lfr_FR *** Failers École /[\b]/ \b *** Failers a /[\b]/Lfr_FR \b *** Failers a /^\w+/ *** Failers École /^\w+/Lfr_FR École /(.+)\b(.+)/ École /(.+)\b(.+)/Lfr_FR *** Failers École /École/i École *** Failers école /École/iLfr_FR École école /\w/IS /\w/ISLfr_FR /^[\xc8-\xc9]/iLfr_FR École école /^[\xc8-\xc9]/Lfr_FR École *** Failers école / End of testinput3 / tomcat-connectors-1.2.41-src/native/iis/pcre/testdata/testinput50000644000000000000020000000667410517277132023220 0ustar rootbin/\x{100}/8DM /\x{1000}/8DM /\x{10000}/8DM /\x{100000}/8DM /\x{1000000}/8DM /\x{4000000}/8DM /\x{7fffFFFF}/8DM /[\x{ff}]/8DM /[\x{100}]/8DM /\x{ffffffff}/8 /\x{100000000}/8 /^\x{100}a\x{1234}/8 \x{100}a\x{1234}bcd /\x80/8D /\xff/8D /\x{0041}\x{2262}\x{0391}\x{002e}/D8 \x{0041}\x{2262}\x{0391}\x{002e} /\x{D55c}\x{ad6d}\x{C5B4}/D8 \x{D55c}\x{ad6d}\x{C5B4} /\x{65e5}\x{672c}\x{8a9e}/D8 \x{65e5}\x{672c}\x{8a9e} /\x{80}/D8 /\x{084}/D8 /\x{104}/D8 /\x{861}/D8 /\x{212ab}/D8 /.{3,5}X/D8 \x{212ab}\x{212ab}\x{212ab}\x{861}X /.{3,5}?/D8 \x{212ab}\x{212ab}\x{212ab}\x{861} /-- These tests are here rather than in testinput4 because Perl 5.6 has --/ /-- some problems with UTF-8 support, in the area of \x{..} where the --/ /-- value is < 255. It grumbles about invalid UTF-8 strings. --/ /^[a\x{c0}]b/8 \x{c0}b /^([a\x{c0}]*?)aa/8 a\x{c0}aaaa/ /^([a\x{c0}]*?)aa/8 a\x{c0}aaaa/ a\x{c0}a\x{c0}aaa/ /^([a\x{c0}]*)aa/8 a\x{c0}aaaa/ a\x{c0}a\x{c0}aaa/ /^([a\x{c0}]*)a\x{c0}/8 a\x{c0}aaaa/ a\x{c0}a\x{c0}aaa/ /-- --/ /(?<=\C)X/8 Should produce an error diagnostic /-- This one is here not because it's different to Perl, but because the --/ /-- way the captured single-byte is displayed. (In Perl it becomes a --/ /-- character, and you can't tell the difference.) --/ /X(\C)(.*)/8 X\x{1234} X\nabc /^[ab]/8D bar *** Failers c \x{ff} \x{100} /^[^ab]/8D c \x{ff} \x{100} *** Failers aaa /[^ab\xC0-\xF0]/8SD \x{f1} \x{bf} \x{100} \x{1000} *** Failers \x{c0} \x{f0} /Ä€{3,4}/8SD \x{100}\x{100}\x{100}\x{100\x{100} /(\x{100}+|x)/8SD /(\x{100}*a|x)/8SD /(\x{100}{0,2}a|x)/8SD /(\x{100}{1,2}a|x)/8SD /\x{100}*(\d+|"(?1)")/8 1234 "1234" \x{100}1234 "\x{100}1234" \x{100}\x{100}12ab \x{100}\x{100}"12" *** Failers \x{100}\x{100}abcd /\x{100}/8D /\x{100}*/8D /a\x{100}*/8D /ab\x{100}*/8D /a\x{100}\x{101}*/8D /a\x{100}\x{101}+/8D /\x{100}*A/8D A /\x{100}*\d(?R)/8D /[^\x{c4}]/D /[^\x{c4}]/8D /[\x{100}]/8DM \x{100} Z\x{100} \x{100}Z *** Failers /[Z\x{100}]/8DM Z\x{100} \x{100} \x{100}Z *** Failers /[\x{200}-\x{100}]/8 /[Ä€-Ä„]/8 \x{100} \x{104} *** Failers \x{105} \x{ff} /[z-\x{100}]/8D /[z\Qa-d]Ä€\E]/8D \x{100} Ä€ /[\xFF]/D >\xff< /[\xff]/D8 >\x{ff}< /[^\xFF]/D /[^\xff]/8D /[Ä-Ü]/8 Ö # Matches without Study \x{d6} /[Ä-Ü]/8S Ö <-- Same with Study \x{d6} /[\x{c4}-\x{dc}]/8 Ö # Matches without Study \x{d6} /[\x{c4}-\x{dc}]/8S Ö <-- Same with Study \x{d6} /[Ã]/8 /Ã/8 /ÃÃÃxxx/8 /ÃÃÃxxx/8?D /abc/8 Ã] à ÃÃà ÃÃÃ\? /anything/8 \xc0\x80 \xc1\x8f \xe0\x9f\x80 \xf0\x8f\x80\x80 \xf8\x87\x80\x80\x80 \xfc\x83\x80\x80\x80\x80 \xfe\x80\x80\x80\x80\x80 \xff\x80\x80\x80\x80\x80 \xc3\x8f \xe0\xaf\x80 \xe1\x80\x80 \xf0\x9f\x80\x80 \xf1\x8f\x80\x80 \xf8\x88\x80\x80\x80 \xf9\x87\x80\x80\x80 \xfc\x84\x80\x80\x80\x80 \xfd\x83\x80\x80\x80\x80 /\x{100}abc(xyz(?1))/8D /[^\x{100}]abc(xyz(?1))/8D /[ab\x{100}]abc(xyz(?1))/8D /(\x{100}(b(?2)c))?/D8 /(\x{100}(b(?2)c)){0,2}/D8 /(\x{100}(b(?1)c))?/D8 /(\x{100}(b(?1)c)){0,2}/D8 /\W/8 A.B A\x{100}B /\w/8 \x{100}X / End of testinput5 / tomcat-connectors-1.2.41-src/native/iis/pcre/testdata/testoutput60000644000000000000020000003754210517277132023420 0ustar rootbinPCRE version 5.0 13-Sep-2004 /^\pC\pL\pM\pN\pP\pS\pZ ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff \x{f1} 0: \x{f1} \x{bf} 0: \x{bf} \x{100} 0: \x{100} \x{1000} 0: \x{1000} *** Failers 0: * \x{c0} No match \x{f0} No match /Ä€{3,4}/8SD ------------------------------------------------------------------ 0 13 Bra 0 3 \x{100}{3} 8 \x{100}{,1} 13 13 Ket 16 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported Options: utf8 First char = 196 Need char = 128 Study returned NULL \x{100}\x{100}\x{100}\x{100\x{100} 0: \x{100}\x{100}\x{100} /(\x{100}+|x)/8SD ------------------------------------------------------------------ 0 17 Bra 0 3 6 Bra 1 6 \x{100}+ 9 5 Alt 12 x 14 11 Ket 17 17 Ket 20 End ------------------------------------------------------------------ Capturing subpattern count = 1 Partial matching not supported Options: utf8 No first char No need char Starting byte set: x \xc4 /(\x{100}*a|x)/8SD ------------------------------------------------------------------ 0 19 Bra 0 3 8 Bra 1 6 \x{100}* 9 a 11 5 Alt 14 x 16 13 Ket 19 19 Ket 22 End ------------------------------------------------------------------ Capturing subpattern count = 1 Partial matching not supported Options: utf8 No first char No need char Starting byte set: a x \xc4 /(\x{100}{0,2}a|x)/8SD ------------------------------------------------------------------ 0 21 Bra 0 3 10 Bra 1 6 \x{100}{,2} 11 a 13 5 Alt 16 x 18 15 Ket 21 21 Ket 24 End ------------------------------------------------------------------ Capturing subpattern count = 1 Partial matching not supported Options: utf8 No first char No need char Starting byte set: a x \xc4 /(\x{100}{1,2}a|x)/8SD ------------------------------------------------------------------ 0 24 Bra 0 3 13 Bra 1 6 \x{100} 9 \x{100}{,1} 14 a 16 5 Alt 19 x 21 18 Ket 24 24 Ket 27 End ------------------------------------------------------------------ Capturing subpattern count = 1 Partial matching not supported Options: utf8 No first char No need char Starting byte set: x \xc4 /\x{100}*(\d+|"(?1)")/8 1234 0: 1234 1: 1234 "1234" 0: "1234" 1: "1234" \x{100}1234 0: \x{100}1234 1: 1234 "\x{100}1234" 0: \x{100}1234 1: 1234 \x{100}\x{100}12ab 0: \x{100}\x{100}12 1: 12 \x{100}\x{100}"12" 0: \x{100}\x{100}"12" 1: "12" *** Failers No match \x{100}\x{100}abcd No match /\x{100}/8D ------------------------------------------------------------------ 0 6 Bra 0 3 \x{100} 6 6 Ket 9 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf8 First char = 196 Need char = 128 /\x{100}*/8D ------------------------------------------------------------------ 0 6 Bra 0 3 \x{100}* 6 6 Ket 9 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported Options: utf8 No first char No need char /a\x{100}*/8D ------------------------------------------------------------------ 0 8 Bra 0 3 a 5 \x{100}* 8 8 Ket 11 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported Options: utf8 First char = 'a' No need char /ab\x{100}*/8D ------------------------------------------------------------------ 0 10 Bra 0 3 ab 7 \x{100}* 10 10 Ket 13 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported Options: utf8 First char = 'a' Need char = 'b' /a\x{100}\x{101}*/8D ------------------------------------------------------------------ 0 11 Bra 0 3 a\x{100} 8 \x{101}* 11 11 Ket 14 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported Options: utf8 First char = 'a' Need char = 128 /a\x{100}\x{101}+/8D ------------------------------------------------------------------ 0 11 Bra 0 3 a\x{100} 8 \x{101}+ 11 11 Ket 14 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported Options: utf8 First char = 'a' Need char = 129 /\x{100}*A/8D ------------------------------------------------------------------ 0 8 Bra 0 3 \x{100}* 6 A 8 8 Ket 11 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported Options: utf8 No first char Need char = 'A' A 0: A /\x{100}*\d(?R)/8D ------------------------------------------------------------------ 0 10 Bra 0 3 \x{100}* 6 \d 7 0 Recurse 10 10 Ket 13 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported Options: utf8 No first char No need char /[^\x{c4}]/D ------------------------------------------------------------------ 0 36 Bra 0 3 [\x01-35-bd-z|~-\xff] (neg) 36 36 Ket 39 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[^\x{c4}]/8D ------------------------------------------------------------------ 0 36 Bra 0 3 [\x00-\xc3\xc5-\xff] (neg) 36 36 Ket 39 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf8 No first char No need char /[\x{100}]/8DM Memory allocation (code space): 47 ------------------------------------------------------------------ 0 11 Bra 0 3 [\x{100}] 11 11 Ket 14 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf8 No first char No need char \x{100} 0: \x{100} Z\x{100} 0: \x{100} \x{100}Z 0: \x{100} *** Failers No match /[Z\x{100}]/8DM Memory allocation (code space): 47 ------------------------------------------------------------------ 0 43 Bra 0 3 [Z\x{100}] 43 43 Ket 46 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf8 No first char No need char Z\x{100} 0: Z \x{100} 0: \x{100} \x{100}Z 0: \x{100} *** Failers No match /[\x{200}-\x{100}]/8 Failed: range out of order in character class at offset 15 /[Ä€-Ä„]/8 \x{100} 0: \x{100} \x{104} 0: \x{104} *** Failers No match \x{105} No match \x{ff} No match /[z-\x{100}]/8D ------------------------------------------------------------------ 0 12 Bra 0 3 [z-\x{100}] 12 12 Ket 15 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf8 No first char No need char /[z\Qa-d]Ä€\E]/8D ------------------------------------------------------------------ 0 43 Bra 0 3 [\-\]adz\x{100}] 43 43 Ket 46 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf8 No first char No need char \x{100} 0: \x{100} Ä€ 0: \x{100} /[\xFF]/D ------------------------------------------------------------------ 0 5 Bra 0 3 \xff 5 5 Ket 8 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = 255 No need char >\xff< 0: \xff /[\xff]/D8 ------------------------------------------------------------------ 0 6 Bra 0 3 \x{ff} 6 6 Ket 9 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf8 First char = 195 Need char = 191 >\x{ff}< 0: \x{ff} /[^\xFF]/D ------------------------------------------------------------------ 0 5 Bra 0 3 [^\xff] 5 5 Ket 8 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[^\xff]/8D ------------------------------------------------------------------ 0 36 Bra 0 3 [\x00-\xfe] (neg) 36 36 Ket 39 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf8 No first char No need char /[Ä-Ü]/8 Ö # Matches without Study 0: \x{d6} \x{d6} 0: \x{d6} /[Ä-Ü]/8S Ö <-- Same with Study 0: \x{d6} \x{d6} 0: \x{d6} /[\x{c4}-\x{dc}]/8 Ö # Matches without Study 0: \x{d6} \x{d6} 0: \x{d6} /[\x{c4}-\x{dc}]/8S Ö <-- Same with Study 0: \x{d6} \x{d6} 0: \x{d6} /[Ã]/8 Failed: invalid UTF-8 string at offset 2 /Ã/8 Failed: invalid UTF-8 string at offset 0 /ÃÃÃxxx/8 Failed: invalid UTF-8 string at offset 1 /ÃÃÃxxx/8?D ------------------------------------------------------------------ 0 15 Bra 0 3 \X{c0}\X{c0}\X{c0}xxx 15 15 Ket 18 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: utf8 no_utf8_check First char = 195 Need char = 'x' /abc/8 Ã] Error -10 à Error -10 ÃÃà Error -10 ÃÃÃ\? No match /anything/8 \xc0\x80 Error -10 \xc1\x8f Error -10 \xe0\x9f\x80 Error -10 \xf0\x8f\x80\x80 Error -10 \xf8\x87\x80\x80\x80 Error -10 \xfc\x83\x80\x80\x80\x80 Error -10 \xfe\x80\x80\x80\x80\x80 Error -10 \xff\x80\x80\x80\x80\x80 Error -10 \xc3\x8f No match \xe0\xaf\x80 No match \xe1\x80\x80 No match \xf0\x9f\x80\x80 No match \xf1\x8f\x80\x80 No match \xf8\x88\x80\x80\x80 No match \xf9\x87\x80\x80\x80 No match \xfc\x84\x80\x80\x80\x80 No match \xfd\x83\x80\x80\x80\x80 No match /\x{100}abc(xyz(?1))/8D ------------------------------------------------------------------ 0 27 Bra 0 3 \x{100}abc 12 12 Bra 1 15 xyz 21 12 Recurse 24 12 Ket 27 27 Ket 30 End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: utf8 First char = 196 Need char = 'z' /[^\x{100}]abc(xyz(?1))/8D ------------------------------------------------------------------ 0 32 Bra 0 3 [^\x{100}] 11 abc 17 12 Bra 1 20 xyz 26 17 Recurse 29 12 Ket 32 32 Ket 35 End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: utf8 No first char Need char = 'z' /[ab\x{100}]abc(xyz(?1))/8D ------------------------------------------------------------------ 0 64 Bra 0 3 [ab\x{100}] 43 abc 49 12 Bra 1 52 xyz 58 49 Recurse 61 12 Ket 64 64 Ket 67 End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: utf8 No first char Need char = 'z' /(\x{100}(b(?2)c))?/D8 ------------------------------------------------------------------ 0 26 Bra 0 3 Brazero 4 19 Bra 1 7 \x{100} 10 10 Bra 2 13 b 15 10 Recurse 18 c 20 10 Ket 23 19 Ket 26 26 Ket 29 End ------------------------------------------------------------------ Capturing subpattern count = 2 Options: utf8 No first char No need char /(\x{100}(b(?2)c)){0,2}/D8 ------------------------------------------------------------------ 0 55 Bra 0 3 Brazero 4 48 Bra 0 7 19 Bra 1 10 \x{100} 13 10 Bra 2 16 b 18 13 Recurse 21 c 23 10 Ket 26 19 Ket 29 Brazero 30 19 Bra 1 33 \x{100} 36 10 Bra 2 39 b 41 13 Recurse 44 c 46 10 Ket 49 19 Ket 52 48 Ket 55 55 Ket 58 End ------------------------------------------------------------------ Capturing subpattern count = 2 Options: utf8 No first char No need char /(\x{100}(b(?1)c))?/D8 ------------------------------------------------------------------ 0 26 Bra 0 3 Brazero 4 19 Bra 1 7 \x{100} 10 10 Bra 2 13 b 15 4 Recurse 18 c 20 10 Ket 23 19 Ket 26 26 Ket 29 End ------------------------------------------------------------------ Capturing subpattern count = 2 Options: utf8 No first char No need char /(\x{100}(b(?1)c)){0,2}/D8 ------------------------------------------------------------------ 0 55 Bra 0 3 Brazero 4 48 Bra 0 7 19 Bra 1 10 \x{100} 13 10 Bra 2 16 b 18 7 Recurse 21 c 23 10 Ket 26 19 Ket 29 Brazero 30 19 Bra 1 33 \x{100} 36 10 Bra 2 39 b 41 7 Recurse 44 c 46 10 Ket 49 19 Ket 52 48 Ket 55 55 Ket 58 End ------------------------------------------------------------------ Capturing subpattern count = 2 Options: utf8 No first char No need char /\W/8 A.B 0: . A\x{100}B 0: \x{100} /\w/8 \x{100}X 0: X / End of testinput5 / tomcat-connectors-1.2.41-src/native/iis/pcre/testdata/testinput60000644000000000000020000001641010517277132023206 0ustar rootbin/^\pC\pL\pM\pN\pP\pS\pZ\S/8 > >X Y > >\x{100} Y /\d/8 \x{100}3 /\s/8 \x{100} X /\D+/8 12abcd34 *** Failers 1234 /\D{2,3}/8 12abcd34 12ab34 *** Failers 1234 12a34 /\D{2,3}?/8 12abcd34 12ab34 *** Failers 1234 12a34 /\d+/8 12abcd34 *** Failers /\d{2,3}/8 12abcd34 1234abcd *** Failers 1.4 /\d{2,3}?/8 12abcd34 1234abcd *** Failers 1.4 /\S+/8 12abcd34 *** Failers \ \ /\S{2,3}/8 12abcd34 1234abcd *** Failers \ \ /\S{2,3}?/8 12abcd34 1234abcd *** Failers \ \ />\s+ <34 *** Failers />\s{2,3} \s{2,3}? \xff< /[\xff]/8 >\x{ff}< /[^\xFF]/ XYZ /[^\xff]/8 XYZ \x{123} /^[ac]*b/8 xb /^[ac\x{100}]*b/8 xb /^[^x]*b/8i xb /^[^x]*b/8 xb /^\d*b/8 xb /(|a)/g8 catac a\x{256}a /^\x{85}$/8i \x{85} / End of testinput4 / tomcat-connectors-1.2.41-src/native/iis/pcre/testdata/testinput20000644000000000000020000005720310517277132023207 0ustar rootbin/(a)b|/ /abc/ abc defabc \Aabc *** Failers \Adefabc ABC /^abc/ abc \Aabc *** Failers defabc \Adefabc /a+bc/ /a*bc/ /a{3}bc/ /(abc|a+z)/ /^abc$/ abc *** Failers def\nabc /ab\gdef/X /(?X)ab\gdef/X /x{5,4}/ /z{65536}/ /[abcd/ /(?X)[\B]/ /[z-a]/ /^*/ /(abc/ /(?# abc/ /(?z)abc/ /.*b/ /.*?b/ /cat|dog|elephant/ this sentence eventually mentions a cat this sentences rambles on and on for a while and then reaches elephant /cat|dog|elephant/S this sentence eventually mentions a cat this sentences rambles on and on for a while and then reaches elephant /cat|dog|elephant/iS this sentence eventually mentions a CAT cat this sentences rambles on and on for a while to elephant ElePhant /a|[bcd]/S /(a|[^\dZ])/S /(a|b)*[\s]/S /(ab\2)/ /{4,5}abc/ /(a)(b)(c)\2/ abcb \O0abcb \O3abcb \O6abcb \O9abcb \O12abcb /(a)bc|(a)(b)\2/ abc \O0abc \O3abc \O6abc aba \O0aba \O3aba \O6aba \O9aba \O12aba /abc$/E abc *** Failers abc\n abc\ndef /(a)(b)(c)(d)(e)\6/ /the quick brown fox/ the quick brown fox this is a line with the quick brown fox /the quick brown fox/A the quick brown fox *** Failers this is a line with the quick brown fox /ab(?z)cd/ /^abc|def/ abcdef abcdef\B /.*((abc)$|(def))/ defabc \Zdefabc /abc/P abc *** Failers /^abc|def/P abcdef abcdef\B /.*((abc)$|(def))/P defabc \Zdefabc /the quick brown fox/P the quick brown fox *** Failers The Quick Brown Fox /the quick brown fox/Pi the quick brown fox The Quick Brown Fox /abc.def/P *** Failers abc\ndef /abc$/P abc abc\n /(abc)\2/P /(abc\1)/P abc /)/ /a[]b/ /[^aeiou ]{3,}/ co-processors, and for /<.*>/ abcghinop /<.*?>/ abcghinop /<.*>/U abcghinop /(?U)<.*>/ abcghinop /<.*?>/U abcghinop /={3,}/U abc========def /(?U)={3,}?/ abc========def /(?^abc)/m abc def\nabc *** Failers defabc /(?<=ab(c+)d)ef/ /(?<=ab(?<=c+)d)ef/ /(?<=ab(c|de)f)g/ /The next three are in testinput2 because they have variable length branches/ /(?<=bullock|donkey)-cart/ the bullock-cart a donkey-cart race *** Failers cart horse-and-cart /(?<=ab(?i)x|y|z)/ /(?>.*)(?<=(abcd)|(xyz))/ alphabetabcd endingxyz /(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ/ abxyZZ abXyZZ ZZZ zZZ bZZ BZZ *** Failers ZZ abXYZZ zzz bzz /(?[^()]+) # Either a sequence of non-brackets (no backtracking) | # Or (?R) # Recurse - i.e. nested bracketed string )* # Zero or more contents \) # Closing ) /x (abcd) (abcd)xyz xyz(abcd) (ab(xy)cd)pqr (ab(xycd)pqr () abc () 12(abcde(fsh)xyz(foo(bar))lmno)89 *** Failers abcd abcd) (abcd /\( ( (?>[^()]+) | (?R) )* \) /xg (ab(xy)cd)pqr 1(abcd)(x(y)z)pqr /\( (?: (?>[^()]+) | (?R) ) \) /x (abcd) (ab(xy)cd) (a(b(c)d)e) ((ab)) *** Failers () /\( (?: (?>[^()]+) | (?R) )? \) /x () 12(abcde(fsh)xyz(foo(bar))lmno)89 /\( ( (?>[^()]+) | (?R) )* \) /x (ab(xy)cd) /\( ( ( (?>[^()]+) | (?R) )* ) \) /x (ab(xy)cd) /\( (123)? ( ( (?>[^()]+) | (?R) )* ) \) /x (ab(xy)cd) (123ab(xy)cd) /\( ( (123)? ( (?>[^()]+) | (?R) )* ) \) /x (ab(xy)cd) (123ab(xy)cd) /\( (((((((((( ( (?>[^()]+) | (?R) )* )))))))))) \) /x (ab(xy)cd) /\( ( ( (?>[^()<>]+) | ((?>[^()]+)) | (?R) )* ) \) /x (abcd(xyz

qrs)123) /\( ( ( (?>[^()]+) | ((?R)) )* ) \) /x (ab(cd)ef) (ab(cd(ef)gh)ij) /^[[:alnum:]]/D /^[[:^alnum:]]/D /^[[:alpha:]]/D /^[[:^alpha:]]/D /^[[:ascii:]]/D /^[[:^ascii:]]/D /^[[:blank:]]/D /^[[:cntrl:]]/D /^[[:digit:]]/D /^[[:graph:]]/D /^[[:lower:]]/D /^[[:print:]]/D /^[[:punct:]]/D /^[[:space:]]/D /^[[:upper:]]/D /^[[:xdigit:]]/D /^[[:word:]]/D /^[[:^cntrl:]]/D /^[12[:^digit:]]/D /^[[:^blank:]]/D /[01[:alpha:]%]/D /[[.ch.]]/ /[[=ch=]]/ /[[:rhubarb:]]/ /[[:upper:]]/i A a /[[:lower:]]/i A a /((?-i)[[:lower:]])[[:lower:]]/i ab aB *** Failers Ab AB /[\200-\410]/ /^(?(0)f|b)oo/ /This one's here because of the large output vector needed/ /(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\w+)\s+(\270)/ \O900 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 ABC ABC /This one's here because Perl does this differently and PCRE can't at present/ /(main(O)?)+/ mainmain mainOmain /These are all cases where Perl does it differently (nested captures)/ /^(a(b)?)+$/ aba /^(aa(bb)?)+$/ aabbaa /^(aa|aa(bb))+$/ aabbaa /^(aa(bb)??)+$/ aabbaa /^(?:aa(bb)?)+$/ aabbaa /^(aa(b(b))?)+$/ aabbaa /^(?:aa(b(b))?)+$/ aabbaa /^(?:aa(b(?:b))?)+$/ aabbaa /^(?:aa(bb(?:b))?)+$/ aabbbaa /^(?:aa(b(?:bb))?)+$/ aabbbaa /^(?:aa(?:b(b))?)+$/ aabbaa /^(?:aa(?:b(bb))?)+$/ aabbbaa /^(aa(b(bb))?)+$/ aabbbaa /^(aa(bb(bb))?)+$/ aabbbbaa /--------------------------------------------------------------------/ /#/xMD /a#/xMD /[\s]/D /[\S]/D /a(?i)b/D ab aB *** Failers AB /(a(?i)b)/D ab aB *** Failers AB / (?i)abc/xD /#this is a comment (?i)abc/xD /123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/D /\Q123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/D /\Q\E/D \ /\Q\Ex/D / \Q\E/D /a\Q\E/D abc bca bac /a\Q\Eb/D abc /\Q\Eabc/D /x*+\w/D *** Failers xxxxx /x?+/D /x++/D /x{1,3}+/D /(x)*+/D /^(\w++|\s++)*$/ now is the time for all good men to come to the aid of the party *** Failers this is not a line with only words and spaces! /(\d++)(\w)/ 12345a *** Failers 12345+ /a++b/ aaab /(a++b)/ aaab /(a++)b/ aaab /([^()]++|\([^()]*\))+/ ((abc(ade)ufh()()x /\(([^()]++|\([^()]+\))+\)/ (abc) (abc(def)xyz) *** Failers ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa /(abc){1,3}+/D /a+?+/ /a{2,3}?+b/ /(?U)a+?+/ /a{2,3}?+b/U /x(?U)a++b/D xaaaab /(?U)xa++b/D xaaaab /^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/D /^x(?U)a+b/D /^x(?U)(a+)b/D /[.x.]/ /[=x=]/ /[:x:]/ /\l/ /\L/ /\N{name}/ /\u/ /\U/ /[/ /[a-/ /[[:space:]/ /[\s]/DM /[[:space:]]/DM /[[:space:]abcde]/DM /< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/x <> hij> hij> def> *** Failers iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|DM |\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|DM /(.*)\d+\1/I /(.*)\d+/I /(.*)\d+\1/Is /(.*)\d+/Is /(.*(xyz))\d+\2/I /((.*))\d+\1/I abc123bc /a[b]/I /(?=a).*/I /(?=abc).xyz/iI /(?=abc)(?i).xyz/I /(?=a)(?=b)/I /(?=.)a/I /((?=abcda)a)/I /((?=abcda)ab)/I /()a/I /(?(1)ab|ac)/I /(?(1)abz|acz)/I /(?(1)abz)/I /(?(1)abz)123/I /(a)+/I /(a){2,3}/I /(a)*/I /[a]/I /[ab]/I /[ab]/IS /[^a]/I /\d456/I /\d456/IS /a^b/I /^a/mI abcde xy\nabc *** Failers xyabc /c|abc/I /(?i)[ab]/IS /[ab](?i)cd/IS /abc(?C)def/ abcdef 1234abcdef *** Failers abcxyz abcxyzf /abc(?C)de(?C1)f/ 123abcdef /(?C1)\dabc(?C2)def/ 1234abcdef *** Failers abcdef /(?C255)ab/ /(?C256)ab/ /(?Cab)xx/ /(?C12vr)x/ /abc(?C)def/ *** Failers \x83\x0\x61bcdef /(abc)(?C)de(?C1)f/ 123abcdef 123abcdef\C+ 123abcdef\C- *** Failers 123abcdef\C!1 /(?C0)(abc(?C1))*/ abcabcabc abcabc\C!1!3 *** Failers abcabcabc\C!1!3 /(\d{3}(?C))*/ 123\C+ 123456\C+ 123456789\C+ /((xyz)(?C)p|(?C1)xyzabc)/ xyzabc\C+ /(X)((xyz)(?C)p|(?C1)xyzabc)/ Xxyzabc\C+ /(?=(abc))(?C)abcdef/ abcdef\C+ /(?!(abc)(?C1)d)(?C2)abcxyz/ abcxyz\C+ /(?<=(abc)(?C))xyz/ abcxyz\C+ /(?C)abc/ /(?C)^abc/ /(?C)a|b/S /(?R)/ /(a|(?R))/ /(ab|(bc|(de|(?R))))/ /x(ab|(bc|(de|(?R))))/ xab xbc xde xxab xxxab *** Failers xyab /(ab|(bc|(de|(?1))))/ /x(ab|(bc|(de|(?1)x)x)x)/ /^([^()]|\((?1)*\))*$/ abc a(b)c a(b(c))d *** Failers) a(b(c)d /^>abc>([^()]|\((?1)*\))*abc>123abc>1(2)3abc>(1(2)3)]*+) | (?2)) * >))/x <> hij> hij> def> *** Failers b|c)d(?Pe)/D abde acde /(?:a(?Pc(?Pd)))(?Pa)/D /(?Pa)...(?P=a)bbb(?P>a)d/D /^\W*(?:(?P(?P.)\W*(?P>one)\W*(?P=two)|)|(?P(?P.)\W*(?P>three)\W*(?P=four)|\W*.\W*))\W*$/i 1221 Satan, oscillate my metallic sonatas! A man, a plan, a canal: Panama! Able was I ere I saw Elba. *** Failers The quick brown fox /((?(R)a|b))\1(?1)?/ bb bbaa /(.*)a/sI /(.*)a\1/sI /(.*)a(b)\2/sI /((.*)a|(.*)b)z/sI /((.*)a|(.*)b)z\1/sI /((.*)a|(.*)b)z\2/sI /((.*)a|(.*)b)z\3/sI /((.*)a|^(.*)b)z\3/sI /(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a/sI /(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\31/sI /(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\32/sI /(a)(bc)/ND abc /(?Pa)(bc)/ND abc /(a)(?Pbc)/ND /(a+)*zz/ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzbbbbbb\M aaaaaaaaaaaaaz\M /(aaa(?C1)bbb|ab)/ aaabbb aaabbb\C*0 aaabbb\C*1 aaabbb\C*-1 /ab(?Pcd)ef(?Pgh)/ abcdefgh abcdefgh\C1\Gtwo abcdefgh\Cone\Ctwo abcdefgh\Cthree /(?P)(?P)/D /(?P)(?P)/D /(?Pzz)(?Paa)/ zzaa\CZ zzaa\CA /(?Peks)(?Peccs)/ /(?Pabc(?Pdef)(?Pxyz))/ "\[((?P\d+)(,(?P>elem))*)\]" [10,20,30,5,5,4,4,2,43,23,4234] *** Failers [] "\[((?P\d+)(,(?P>elem))*)?\]" [10,20,30,5,5,4,4,2,43,23,4234] [] /(a(b(?2)c))?/D /(a(b(?2)c))*/D /(a(b(?2)c)){0,2}/D /[ab]{1}+/D /((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)/i Baby Bjorn Active Carrier - With free SHIPPING!! /((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)/iS Baby Bjorn Active Carrier - With free SHIPPING!! /a*.*b/SD /(a|b)*.?c/SD /abc(?C255)de(?C)f/D /abcde/CD abcde abcdfe /a*b/CD ab aaaab aaaacb /a+b/CD ab aaaab aaaacb /(abc|def)x/CD abcx defx abcdefzx /(ab|cd){3,4}/C ababab abcdabcd abcdcdcdcdcd /([ab]{,4}c|xy)/CD Note: that { does NOT introduce a quantifier /([ab]{1,4}c|xy){4,5}?123/CD aacaacaacaacaac123 /\b.*/I ab cd\>1 /\b.*/Is ab cd\>1 /(?!.bcd).*/I Xbcd12345 /abcde/ ab\P abc\P abcd\P abcde\P the quick brown abc\P ** Failers\P the quick brown abxyz fox\P "^(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/(20)?\d\d$" 13/05/04\P 13/5/2004\P 02/05/09\P 1\P 1/2\P 1/2/0\P 1/2/04\P 0\P 02/\P 02/0\P 02/1\P ** Failers\P \P 123\P 33/4/04\P 3/13/04\P 0/1/2003\P 0/\P 02/0/\P 02/13\P /0{0,2}ABC/I /\d{3,}ABC/I /\d*ABC/I /[abc]+DE/I /[abc]?123/ 123\P a\P b\P c\P c12\P c123\P /^(?:\d){3,5}X/ 1\P 123\P 123X 1234\P 1234X 12345\P 12345X *** Failers 1X 123456\P /abc/>testsavedregex testsavedregex testsavedregex testsavedregex (.)*~smg \n\n\nPartner der LCO\nde\nPartner der LINEAS Consulting\nGmbH\nLINEAS Consulting GmbH Hamburg\nPartnerfirmen\n30 days\nindex,follow\n\nja\n3\nPartner\n\n\nLCO\nLINEAS Consulting\n15.10.2003\n\n\n\n\nDie Partnerfirmen der LINEAS Consulting\nGmbH\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n /^a/IF / End of testinput2 / tomcat-connectors-1.2.41-src/native/iis/pcre/testdata/testoutput20000644000000000000020000034166710517277132023422 0ustar rootbinPCRE version 5.0 13-Sep-2004 /(a)b|/ Capturing subpattern count = 1 No options No first char No need char /abc/ Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' abc 0: abc defabc 0: abc \Aabc 0: abc *** Failers No match \Adefabc No match ABC No match /^abc/ Capturing subpattern count = 0 Options: anchored No first char No need char abc 0: abc \Aabc 0: abc *** Failers No match defabc No match \Adefabc No match /a+bc/ Capturing subpattern count = 0 Partial matching not supported No options First char = 'a' Need char = 'c' /a*bc/ Capturing subpattern count = 0 Partial matching not supported No options No first char Need char = 'c' /a{3}bc/ Capturing subpattern count = 0 Partial matching not supported No options First char = 'a' Need char = 'c' /(abc|a+z)/ Capturing subpattern count = 1 Partial matching not supported No options First char = 'a' No need char /^abc$/ Capturing subpattern count = 0 Options: anchored No first char No need char abc 0: abc *** Failers No match def\nabc No match /ab\gdef/X Failed: unrecognized character follows \ at offset 3 /(?X)ab\gdef/X Failed: unrecognized character follows \ at offset 7 /x{5,4}/ Failed: numbers out of order in {} quantifier at offset 5 /z{65536}/ Failed: number too big in {} quantifier at offset 7 /[abcd/ Failed: missing terminating ] for character class at offset 5 /(?X)[\B]/ Failed: invalid escape sequence in character class at offset 6 /[z-a]/ Failed: range out of order in character class at offset 3 /^*/ Failed: nothing to repeat at offset 1 /(abc/ Failed: missing ) at offset 4 /(?# abc/ Failed: missing ) after comment at offset 7 /(?z)abc/ Failed: unrecognized character after (? at offset 2 /.*b/ Capturing subpattern count = 0 Partial matching not supported No options First char at start or follows \n Need char = 'b' /.*?b/ Capturing subpattern count = 0 Partial matching not supported No options First char at start or follows \n Need char = 'b' /cat|dog|elephant/ Capturing subpattern count = 0 No options No first char No need char this sentence eventually mentions a cat 0: cat this sentences rambles on and on for a while and then reaches elephant 0: elephant /cat|dog|elephant/S Capturing subpattern count = 0 No options No first char No need char Starting byte set: c d e this sentence eventually mentions a cat 0: cat this sentences rambles on and on for a while and then reaches elephant 0: elephant /cat|dog|elephant/iS Capturing subpattern count = 0 Options: caseless No first char No need char Starting byte set: C D E c d e this sentence eventually mentions a CAT cat 0: CAT this sentences rambles on and on for a while to elephant ElePhant 0: elephant /a|[bcd]/S Capturing subpattern count = 0 No options No first char No need char Starting byte set: a b c d /(a|[^\dZ])/S Capturing subpattern count = 1 No options No first char No need char Starting byte set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y [ \ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80 \x81 \x82 \x83 \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92 \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa0 \xa1 \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf \xb0 \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb \xfc \xfd \xfe \xff /(a|b)*[\s]/S Capturing subpattern count = 1 No options No first char No need char Starting byte set: \x09 \x0a \x0c \x0d \x20 a b /(ab\2)/ Failed: reference to non-existent subpattern at offset 6 /{4,5}abc/ Failed: nothing to repeat at offset 4 /(a)(b)(c)\2/ Capturing subpattern count = 3 Max back reference = 2 No options First char = 'a' Need char = 'c' abcb 0: abcb 1: a 2: b 3: c \O0abcb Matched, but too many substrings \O3abcb Matched, but too many substrings 0: abcb \O6abcb Matched, but too many substrings 0: abcb 1: a \O9abcb Matched, but too many substrings 0: abcb 1: a 2: b \O12abcb 0: abcb 1: a 2: b 3: c /(a)bc|(a)(b)\2/ Capturing subpattern count = 3 Max back reference = 2 No options First char = 'a' No need char abc 0: abc 1: a \O0abc Matched, but too many substrings \O3abc Matched, but too many substrings 0: abc \O6abc 0: abc 1: a aba 0: aba 1: 2: a 3: b \O0aba Matched, but too many substrings \O3aba Matched, but too many substrings 0: aba \O6aba Matched, but too many substrings 0: aba 1: \O9aba Matched, but too many substrings 0: aba 1: 2: a \O12aba 0: aba 1: 2: a 3: b /abc$/E Capturing subpattern count = 0 Options: dollar_endonly First char = 'a' Need char = 'c' abc 0: abc *** Failers No match abc\n No match abc\ndef No match /(a)(b)(c)(d)(e)\6/ Failed: reference to non-existent subpattern at offset 17 /the quick brown fox/ Capturing subpattern count = 0 No options First char = 't' Need char = 'x' the quick brown fox 0: the quick brown fox this is a line with the quick brown fox 0: the quick brown fox /the quick brown fox/A Capturing subpattern count = 0 Options: anchored No first char No need char the quick brown fox 0: the quick brown fox *** Failers No match this is a line with the quick brown fox No match /ab(?z)cd/ Failed: unrecognized character after (? at offset 4 /^abc|def/ Capturing subpattern count = 0 No options No first char No need char abcdef 0: abc abcdef\B 0: def /.*((abc)$|(def))/ Capturing subpattern count = 3 Partial matching not supported No options First char at start or follows \n No need char defabc 0: defabc 1: abc 2: abc \Zdefabc 0: def 1: def 2: 3: def /abc/P abc 0: abc *** Failers No match: POSIX code 17: match failed /^abc|def/P abcdef 0: abc abcdef\B 0: def /.*((abc)$|(def))/P defabc 0: defabc 1: abc 2: abc \Zdefabc 0: def 1: def 3: def /the quick brown fox/P the quick brown fox 0: the quick brown fox *** Failers No match: POSIX code 17: match failed The Quick Brown Fox No match: POSIX code 17: match failed /the quick brown fox/Pi the quick brown fox 0: the quick brown fox The Quick Brown Fox 0: The Quick Brown Fox /abc.def/P *** Failers No match: POSIX code 17: match failed abc\ndef No match: POSIX code 17: match failed /abc$/P abc 0: abc abc\n 0: abc /(abc)\2/P Failed: POSIX code 15: bad back reference at offset 7 /(abc\1)/P abc No match: POSIX code 17: match failed /)/ Failed: unmatched parentheses at offset 0 /a[]b/ Failed: missing terminating ] for character class at offset 4 /[^aeiou ]{3,}/ Capturing subpattern count = 0 Partial matching not supported No options No first char No need char co-processors, and for 0: -pr /<.*>/ Capturing subpattern count = 0 Partial matching not supported No options First char = '<' Need char = '>' abcghinop 0: ghi /<.*?>/ Capturing subpattern count = 0 Partial matching not supported No options First char = '<' Need char = '>' abcghinop 0: /<.*>/U Capturing subpattern count = 0 Partial matching not supported Options: ungreedy First char = '<' Need char = '>' abcghinop 0: /(?U)<.*>/ Capturing subpattern count = 0 Partial matching not supported Options: ungreedy First char = '<' Need char = '>' abcghinop 0: /<.*?>/U Capturing subpattern count = 0 Partial matching not supported Options: ungreedy First char = '<' Need char = '>' abcghinop 0: ghi /={3,}/U Capturing subpattern count = 0 Partial matching not supported Options: ungreedy First char = '=' Need char = '=' abc========def 0: === /(?U)={3,}?/ Capturing subpattern count = 0 Partial matching not supported Options: ungreedy First char = '=' Need char = '=' abc========def 0: ======== /(?^abc)/m Capturing subpattern count = 0 Options: multiline First char at start or follows \n Need char = 'c' abc 0: abc def\nabc 0: abc *** Failers No match defabc No match /(?<=ab(c+)d)ef/ Failed: lookbehind assertion is not fixed length at offset 11 /(?<=ab(?<=c+)d)ef/ Failed: lookbehind assertion is not fixed length at offset 12 /(?<=ab(c|de)f)g/ Failed: lookbehind assertion is not fixed length at offset 13 /The next three are in testinput2 because they have variable length branches/ Capturing subpattern count = 0 No options First char = 'T' Need char = 's' /(?<=bullock|donkey)-cart/ Capturing subpattern count = 0 No options First char = '-' Need char = 't' the bullock-cart 0: -cart a donkey-cart race 0: -cart *** Failers No match cart No match horse-and-cart No match /(?<=ab(?i)x|y|z)/ Capturing subpattern count = 0 No options Case state changes No first char No need char /(?>.*)(?<=(abcd)|(xyz))/ Capturing subpattern count = 2 Partial matching not supported No options First char at start or follows \n No need char alphabetabcd 0: alphabetabcd 1: abcd endingxyz 0: endingxyz 1: 2: xyz /(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ/ Capturing subpattern count = 0 No options Case state changes First char = 'Z' Need char = 'Z' abxyZZ 0: ZZ abXyZZ 0: ZZ ZZZ 0: ZZ zZZ 0: ZZ bZZ 0: ZZ BZZ 0: ZZ *** Failers No match ZZ No match abXYZZ No match zzz No match bzz No match /(? 3: f 1G a (1) 2G (0) 3G f (1) get substring 4 failed -7 0L adef 1L a 2L 3L f bcdef\G1\G2\G3\G4\L 0: bcdef 1: bc 2: bc 3: f 1G bc (2) 2G bc (2) 3G f (1) get substring 4 failed -7 0L bcdef 1L bc 2L bc 3L f adefghijk\C0 0: adef 1: a 2: 3: f 0C adef (4) /^abc\00def/ Capturing subpattern count = 0 Options: anchored No first char No need char abc\00def\L\C0 0: abc\x00def 0C abc (7) 0L abc /word ((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )?)?)?)?)?)?)?)?)?otherword/M Memory allocation (code space): 432 Capturing subpattern count = 8 Partial matching not supported No options First char = 'w' Need char = 'd' /.*X/D ------------------------------------------------------------------ 0 7 Bra 0 3 Any* 5 X 7 7 Ket 10 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported No options First char at start or follows \n Need char = 'X' /.*X/Ds ------------------------------------------------------------------ 0 7 Bra 0 3 Any* 5 X 7 7 Ket 10 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported Options: anchored dotall No first char Need char = 'X' /(.*X|^B)/D ------------------------------------------------------------------ 0 19 Bra 0 3 7 Bra 1 6 Any* 8 X 10 6 Alt 13 ^ 14 B 16 13 Ket 19 19 Ket 22 End ------------------------------------------------------------------ Capturing subpattern count = 1 Partial matching not supported No options First char at start or follows \n No need char /(.*X|^B)/Ds ------------------------------------------------------------------ 0 19 Bra 0 3 7 Bra 1 6 Any* 8 X 10 6 Alt 13 ^ 14 B 16 13 Ket 19 19 Ket 22 End ------------------------------------------------------------------ Capturing subpattern count = 1 Partial matching not supported Options: anchored dotall No first char No need char /(?s)(.*X|^B)/D ------------------------------------------------------------------ 0 19 Bra 0 3 7 Bra 1 6 Any* 8 X 10 6 Alt 13 ^ 14 B 16 13 Ket 19 19 Ket 22 End ------------------------------------------------------------------ Capturing subpattern count = 1 Partial matching not supported Options: anchored dotall No first char No need char /(?s:.*X|^B)/D ------------------------------------------------------------------ 0 25 Bra 0 3 9 Bra 0 6 04 Opt 8 Any* 10 X 12 8 Alt 15 04 Opt 17 ^ 18 B 20 17 Ket 23 00 Opt 25 25 Ket 28 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported No options First char at start or follows \n No need char /\Biss\B/+ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' Mississippi 0: iss 0+ issippi /\Biss\B/+P Mississippi 0: iss 0+ issippi /iss/G+ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' Mississippi 0: iss 0+ issippi 0: iss 0+ ippi /\Biss\B/G+ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' Mississippi 0: iss 0+ issippi /\Biss\B/g+ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' Mississippi 0: iss 0+ issippi 0: iss 0+ ippi *** Failers No match Mississippi\A No match /(?<=[Ms])iss/g+ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' Mississippi 0: iss 0+ issippi 0: iss 0+ ippi /(?<=[Ms])iss/G+ Capturing subpattern count = 0 No options First char = 'i' Need char = 's' Mississippi 0: iss 0+ issippi /^iss/g+ Capturing subpattern count = 0 Options: anchored No first char No need char ississippi 0: iss 0+ issippi /.*iss/g+ Capturing subpattern count = 0 Partial matching not supported No options First char at start or follows \n Need char = 's' abciss\nxyzisspqr 0: abciss 0+ \x0axyzisspqr 0: xyziss 0+ pqr /.i./+g Capturing subpattern count = 0 No options No first char Need char = 'i' Mississippi 0: Mis 0+ sissippi 0: sis 0+ sippi 0: sip 0+ pi Mississippi\A 0: Mis 0+ sissippi 0: sis 0+ sippi 0: sip 0+ pi Missouri river 0: Mis 0+ souri river 0: ri 0+ river 0: riv 0+ er Missouri river\A 0: Mis 0+ souri river /^.is/+g Capturing subpattern count = 0 Options: anchored No first char No need char Mississippi 0: Mis 0+ sissippi /^ab\n/g+ Capturing subpattern count = 0 Options: anchored No first char No need char ab\nab\ncd 0: ab\x0a 0+ ab\x0acd /^ab\n/mg+ Capturing subpattern count = 0 Options: multiline First char at start or follows \n Need char = 10 ab\nab\ncd 0: ab\x0a 0+ ab\x0acd 0: ab\x0a 0+ cd /abc/ Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' /abc|bac/ Capturing subpattern count = 0 No options No first char Need char = 'c' /(abc|bac)/ Capturing subpattern count = 1 No options No first char Need char = 'c' /(abc|(c|dc))/ Capturing subpattern count = 2 No options No first char Need char = 'c' /(abc|(d|de)c)/ Capturing subpattern count = 2 No options No first char Need char = 'c' /a*/ Capturing subpattern count = 0 Partial matching not supported No options No first char No need char /a+/ Capturing subpattern count = 0 Partial matching not supported No options First char = 'a' No need char /(baa|a+)/ Capturing subpattern count = 1 Partial matching not supported No options No first char Need char = 'a' /a{0,3}/ Capturing subpattern count = 0 Partial matching not supported No options No first char No need char /baa{3,}/ Capturing subpattern count = 0 Partial matching not supported No options First char = 'b' Need char = 'a' /"([^\\"]+|\\.)*"/ Capturing subpattern count = 1 Partial matching not supported No options First char = '"' Need char = '"' /(abc|ab[cd])/ Capturing subpattern count = 1 No options First char = 'a' No need char /(a|.)/ Capturing subpattern count = 1 No options No first char No need char /a|ba|\w/ Capturing subpattern count = 0 No options No first char No need char /abc(?=pqr)/ Capturing subpattern count = 0 No options First char = 'a' Need char = 'r' /...(?<=abc)/ Capturing subpattern count = 0 No options No first char No need char /abc(?!pqr)/ Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' /ab./ Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' /ab[xyz]/ Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' /abc*/ Capturing subpattern count = 0 Partial matching not supported No options First char = 'a' Need char = 'b' /ab.c*/ Capturing subpattern count = 0 Partial matching not supported No options First char = 'a' Need char = 'b' /a.c*/ Capturing subpattern count = 0 Partial matching not supported No options First char = 'a' No need char /.c*/ Capturing subpattern count = 0 Partial matching not supported No options No first char No need char /ac*/ Capturing subpattern count = 0 Partial matching not supported No options First char = 'a' No need char /(a.c*|b.c*)/ Capturing subpattern count = 1 Partial matching not supported No options No first char No need char /a.c*|aba/ Capturing subpattern count = 0 Partial matching not supported No options First char = 'a' No need char /.+a/ Capturing subpattern count = 0 Partial matching not supported No options No first char Need char = 'a' /(?=abcda)a.*/ Capturing subpattern count = 0 Partial matching not supported No options First char = 'a' Need char = 'a' /(?=a)a.*/ Capturing subpattern count = 0 Partial matching not supported No options First char = 'a' No need char /a(b)*/ Capturing subpattern count = 1 No options First char = 'a' No need char /a\d*/ Capturing subpattern count = 0 Partial matching not supported No options First char = 'a' No need char /ab\d*/ Capturing subpattern count = 0 Partial matching not supported No options First char = 'a' Need char = 'b' /a(\d)*/ Capturing subpattern count = 1 No options First char = 'a' No need char /abcde{0,0}/ Capturing subpattern count = 0 No options First char = 'a' Need char = 'd' /ab\d+/ Capturing subpattern count = 0 Partial matching not supported No options First char = 'a' Need char = 'b' /a(?(1)b)/ Capturing subpattern count = 0 No options First char = 'a' No need char /a(?(1)bag|big)/ Capturing subpattern count = 0 No options First char = 'a' Need char = 'g' /a(?(1)bag|big)*/ Capturing subpattern count = 0 No options First char = 'a' No need char /a(?(1)bag|big)+/ Capturing subpattern count = 0 No options First char = 'a' Need char = 'g' /a(?(1)b..|b..)/ Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' /ab\d{0}e/ Capturing subpattern count = 0 No options First char = 'a' Need char = 'e' /a?b?/ Capturing subpattern count = 0 No options No first char No need char a 0: a b 0: b ab 0: ab \ 0: *** Failers 0: \N No match /|-/ Capturing subpattern count = 0 No options No first char No need char abcd 0: -abc 0: \Nab-c 0: - *** Failers 0: \Nabc No match /a*(b+)(z)(z)/P aaaabbbbzzzz 0: aaaabbbbzz 1: bbbb 2: z 3: z aaaabbbbzzzz\O0 aaaabbbbzzzz\O1 0: aaaabbbbzz aaaabbbbzzzz\O2 0: aaaabbbbzz 1: bbbb aaaabbbbzzzz\O3 0: aaaabbbbzz 1: bbbb 2: z aaaabbbbzzzz\O4 0: aaaabbbbzz 1: bbbb 2: z 3: z aaaabbbbzzzz\O5 0: aaaabbbbzz 1: bbbb 2: z 3: z /^.?abcd/S Capturing subpattern count = 0 Options: anchored No first char Need char = 'd' Study returned NULL /\( # ( at start (?: # Non-capturing bracket (?>[^()]+) # Either a sequence of non-brackets (no backtracking) | # Or (?R) # Recurse - i.e. nested bracketed string )* # Zero or more contents \) # Closing ) /x Capturing subpattern count = 0 Partial matching not supported Options: extended First char = '(' Need char = ')' (abcd) 0: (abcd) (abcd)xyz 0: (abcd) xyz(abcd) 0: (abcd) (ab(xy)cd)pqr 0: (ab(xy)cd) (ab(xycd)pqr 0: (xycd) () abc () 0: () 12(abcde(fsh)xyz(foo(bar))lmno)89 0: (abcde(fsh)xyz(foo(bar))lmno) *** Failers No match abcd No match abcd) No match (abcd No match /\( ( (?>[^()]+) | (?R) )* \) /xg Capturing subpattern count = 1 Partial matching not supported Options: extended First char = '(' Need char = ')' (ab(xy)cd)pqr 0: (ab(xy)cd) 1: cd 1(abcd)(x(y)z)pqr 0: (abcd) 1: abcd 0: (x(y)z) 1: z /\( (?: (?>[^()]+) | (?R) ) \) /x Capturing subpattern count = 0 Partial matching not supported Options: extended First char = '(' Need char = ')' (abcd) 0: (abcd) (ab(xy)cd) 0: (xy) (a(b(c)d)e) 0: (c) ((ab)) 0: ((ab)) *** Failers No match () No match /\( (?: (?>[^()]+) | (?R) )? \) /x Capturing subpattern count = 0 Partial matching not supported Options: extended First char = '(' Need char = ')' () 0: () 12(abcde(fsh)xyz(foo(bar))lmno)89 0: (fsh) /\( ( (?>[^()]+) | (?R) )* \) /x Capturing subpattern count = 1 Partial matching not supported Options: extended First char = '(' Need char = ')' (ab(xy)cd) 0: (ab(xy)cd) 1: cd /\( ( ( (?>[^()]+) | (?R) )* ) \) /x Capturing subpattern count = 2 Partial matching not supported Options: extended First char = '(' Need char = ')' (ab(xy)cd) 0: (ab(xy)cd) 1: ab(xy)cd 2: cd /\( (123)? ( ( (?>[^()]+) | (?R) )* ) \) /x Capturing subpattern count = 3 Partial matching not supported Options: extended First char = '(' Need char = ')' (ab(xy)cd) 0: (ab(xy)cd) 1: 2: ab(xy)cd 3: cd (123ab(xy)cd) 0: (123ab(xy)cd) 1: 123 2: ab(xy)cd 3: cd /\( ( (123)? ( (?>[^()]+) | (?R) )* ) \) /x Capturing subpattern count = 3 Partial matching not supported Options: extended First char = '(' Need char = ')' (ab(xy)cd) 0: (ab(xy)cd) 1: ab(xy)cd 2: 3: cd (123ab(xy)cd) 0: (123ab(xy)cd) 1: 123ab(xy)cd 2: 123 3: cd /\( (((((((((( ( (?>[^()]+) | (?R) )* )))))))))) \) /x Capturing subpattern count = 11 Partial matching not supported Options: extended First char = '(' Need char = ')' (ab(xy)cd) 0: (ab(xy)cd) 1: ab(xy)cd 2: ab(xy)cd 3: ab(xy)cd 4: ab(xy)cd 5: ab(xy)cd 6: ab(xy)cd 7: ab(xy)cd 8: ab(xy)cd 9: ab(xy)cd 10: ab(xy)cd 11: cd /\( ( ( (?>[^()<>]+) | ((?>[^()]+)) | (?R) )* ) \) /x Capturing subpattern count = 3 Partial matching not supported Options: extended First char = '(' Need char = ')' (abcd(xyz

qrs)123) 0: (abcd(xyz

qrs)123) 1: abcd(xyz

qrs)123 2: 123 3: /\( ( ( (?>[^()]+) | ((?R)) )* ) \) /x Capturing subpattern count = 3 Partial matching not supported Options: extended First char = '(' Need char = ')' (ab(cd)ef) 0: (ab(cd)ef) 1: ab(cd)ef 2: ef 3: (cd) (ab(cd(ef)gh)ij) 0: (ab(cd(ef)gh)ij) 1: ab(cd(ef)gh)ij 2: ij 3: (cd(ef)gh) /^[[:alnum:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [0-9A-Za-z] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:^alnum:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [\x00-/:-@[-`{-\xff] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:alpha:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [A-Za-z] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:^alpha:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [\x00-@[-`{-\xff] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:ascii:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [\x00-\x7f] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:^ascii:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [\x80-\xff] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:blank:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [\x09 ] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:cntrl:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [\x00-\x1f\x7f] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:digit:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [0-9] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:graph:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [!-~] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:lower:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [a-z] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:print:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [ -~] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:punct:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [!-/:-@[-`{-~] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:space:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [\x09-\x0d ] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:upper:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [A-Z] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:xdigit:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [0-9A-Fa-f] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:word:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [0-9A-Z_a-z] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:^cntrl:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [ -~\x80-\xff] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[12[:^digit:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [\x00-/12:-\xff] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /^[[:^blank:]]/D ------------------------------------------------------------------ 0 37 Bra 0 3 ^ 4 [\x00-\x08\x0a-\x1f!-\xff] 37 37 Ket 40 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: anchored No first char No need char /[01[:alpha:]%]/D ------------------------------------------------------------------ 0 36 Bra 0 3 [%01A-Za-z] 36 36 Ket 39 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[[.ch.]]/ Failed: POSIX collating elements are not supported at offset 1 /[[=ch=]]/ Failed: POSIX collating elements are not supported at offset 1 /[[:rhubarb:]]/ Failed: unknown POSIX class name at offset 3 /[[:upper:]]/i Capturing subpattern count = 0 Options: caseless No first char No need char A 0: A a 0: a /[[:lower:]]/i Capturing subpattern count = 0 Options: caseless No first char No need char A 0: A a 0: a /((?-i)[[:lower:]])[[:lower:]]/i Capturing subpattern count = 1 Options: caseless Case state changes No first char No need char ab 0: ab 1: a aB 0: aB 1: a *** Failers 0: ai 1: a Ab No match AB No match /[\200-\410]/ Failed: range out of order in character class at offset 9 /^(?(0)f|b)oo/ Failed: invalid condition (?(0) at offset 5 /This one's here because of the large output vector needed/ Capturing subpattern count = 0 No options First char = 'T' Need char = 'd' /(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\d+(?:\s|$))(\w+)\s+(\270)/ Capturing subpattern count = 271 Max back reference = 270 Partial matching not supported No options No first char No need char \O900 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 ABC ABC 0: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 ABC ABC 1: 1 2: 2 3: 3 4: 4 5: 5 6: 6 7: 7 8: 8 9: 9 10: 10 11: 11 12: 12 13: 13 14: 14 15: 15 16: 16 17: 17 18: 18 19: 19 20: 20 21: 21 22: 22 23: 23 24: 24 25: 25 26: 26 27: 27 28: 28 29: 29 30: 30 31: 31 32: 32 33: 33 34: 34 35: 35 36: 36 37: 37 38: 38 39: 39 40: 40 41: 41 42: 42 43: 43 44: 44 45: 45 46: 46 47: 47 48: 48 49: 49 50: 50 51: 51 52: 52 53: 53 54: 54 55: 55 56: 56 57: 57 58: 58 59: 59 60: 60 61: 61 62: 62 63: 63 64: 64 65: 65 66: 66 67: 67 68: 68 69: 69 70: 70 71: 71 72: 72 73: 73 74: 74 75: 75 76: 76 77: 77 78: 78 79: 79 80: 80 81: 81 82: 82 83: 83 84: 84 85: 85 86: 86 87: 87 88: 88 89: 89 90: 90 91: 91 92: 92 93: 93 94: 94 95: 95 96: 96 97: 97 98: 98 99: 99 100: 100 101: 101 102: 102 103: 103 104: 104 105: 105 106: 106 107: 107 108: 108 109: 109 110: 110 111: 111 112: 112 113: 113 114: 114 115: 115 116: 116 117: 117 118: 118 119: 119 120: 120 121: 121 122: 122 123: 123 124: 124 125: 125 126: 126 127: 127 128: 128 129: 129 130: 130 131: 131 132: 132 133: 133 134: 134 135: 135 136: 136 137: 137 138: 138 139: 139 140: 140 141: 141 142: 142 143: 143 144: 144 145: 145 146: 146 147: 147 148: 148 149: 149 150: 150 151: 151 152: 152 153: 153 154: 154 155: 155 156: 156 157: 157 158: 158 159: 159 160: 160 161: 161 162: 162 163: 163 164: 164 165: 165 166: 166 167: 167 168: 168 169: 169 170: 170 171: 171 172: 172 173: 173 174: 174 175: 175 176: 176 177: 177 178: 178 179: 179 180: 180 181: 181 182: 182 183: 183 184: 184 185: 185 186: 186 187: 187 188: 188 189: 189 190: 190 191: 191 192: 192 193: 193 194: 194 195: 195 196: 196 197: 197 198: 198 199: 199 200: 200 201: 201 202: 202 203: 203 204: 204 205: 205 206: 206 207: 207 208: 208 209: 209 210: 210 211: 211 212: 212 213: 213 214: 214 215: 215 216: 216 217: 217 218: 218 219: 219 220: 220 221: 221 222: 222 223: 223 224: 224 225: 225 226: 226 227: 227 228: 228 229: 229 230: 230 231: 231 232: 232 233: 233 234: 234 235: 235 236: 236 237: 237 238: 238 239: 239 240: 240 241: 241 242: 242 243: 243 244: 244 245: 245 246: 246 247: 247 248: 248 249: 249 250: 250 251: 251 252: 252 253: 253 254: 254 255: 255 256: 256 257: 257 258: 258 259: 259 260: 260 261: 261 262: 262 263: 263 264: 264 265: 265 266: 266 267: 267 268: 268 269: 269 270: ABC 271: ABC /This one's here because Perl does this differently and PCRE can't at present/ Capturing subpattern count = 0 No options First char = 'T' Need char = 't' /(main(O)?)+/ Capturing subpattern count = 2 No options First char = 'm' Need char = 'n' mainmain 0: mainmain 1: main mainOmain 0: mainOmain 1: main 2: O /These are all cases where Perl does it differently (nested captures)/ Capturing subpattern count = 1 No options First char = 'T' Need char = 's' /^(a(b)?)+$/ Capturing subpattern count = 2 Options: anchored No first char No need char aba 0: aba 1: a 2: b /^(aa(bb)?)+$/ Capturing subpattern count = 2 Options: anchored No first char No need char aabbaa 0: aabbaa 1: aa 2: bb /^(aa|aa(bb))+$/ Capturing subpattern count = 2 Options: anchored No first char No need char aabbaa 0: aabbaa 1: aa 2: bb /^(aa(bb)??)+$/ Capturing subpattern count = 2 Options: anchored No first char No need char aabbaa 0: aabbaa 1: aa 2: bb /^(?:aa(bb)?)+$/ Capturing subpattern count = 1 Options: anchored No first char No need char aabbaa 0: aabbaa 1: bb /^(aa(b(b))?)+$/ Capturing subpattern count = 3 Options: anchored No first char No need char aabbaa 0: aabbaa 1: aa 2: bb 3: b /^(?:aa(b(b))?)+$/ Capturing subpattern count = 2 Options: anchored No first char No need char aabbaa 0: aabbaa 1: bb 2: b /^(?:aa(b(?:b))?)+$/ Capturing subpattern count = 1 Options: anchored No first char No need char aabbaa 0: aabbaa 1: bb /^(?:aa(bb(?:b))?)+$/ Capturing subpattern count = 1 Options: anchored No first char No need char aabbbaa 0: aabbbaa 1: bbb /^(?:aa(b(?:bb))?)+$/ Capturing subpattern count = 1 Options: anchored No first char No need char aabbbaa 0: aabbbaa 1: bbb /^(?:aa(?:b(b))?)+$/ Capturing subpattern count = 1 Options: anchored No first char No need char aabbaa 0: aabbaa 1: b /^(?:aa(?:b(bb))?)+$/ Capturing subpattern count = 1 Options: anchored No first char No need char aabbbaa 0: aabbbaa 1: bb /^(aa(b(bb))?)+$/ Capturing subpattern count = 3 Options: anchored No first char No need char aabbbaa 0: aabbbaa 1: aa 2: bbb 3: bb /^(aa(bb(bb))?)+$/ Capturing subpattern count = 3 Options: anchored No first char No need char aabbbbaa 0: aabbbbaa 1: aa 2: bbbb 3: bb /--------------------------------------------------------------------/ Capturing subpattern count = 0 No options First char = '-' Need char = '-' /#/xMD Memory allocation (code space): 7 ------------------------------------------------------------------ 0 3 Bra 0 3 3 Ket 6 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: extended No first char No need char /a#/xMD Memory allocation (code space): 9 ------------------------------------------------------------------ 0 5 Bra 0 3 a 5 5 Ket 8 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: extended First char = 'a' No need char /[\s]/D ------------------------------------------------------------------ 0 36 Bra 0 3 [\x09\x0a\x0c\x0d ] 36 36 Ket 39 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[\S]/D ------------------------------------------------------------------ 0 36 Bra 0 3 [\x00-\x08\x0b\x0e-\x1f!-\xff] 36 36 Ket 39 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /a(?i)b/D ------------------------------------------------------------------ 0 9 Bra 0 3 a 5 01 Opt 7 NC b 9 9 Ket 12 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options Case state changes First char = 'a' Need char = 'b' (caseless) ab 0: ab aB 0: aB *** Failers No match AB No match /(a(?i)b)/D ------------------------------------------------------------------ 0 17 Bra 0 3 9 Bra 1 6 a 8 01 Opt 10 NC b 12 9 Ket 15 00 Opt 17 17 Ket 20 End ------------------------------------------------------------------ Capturing subpattern count = 1 No options Case state changes First char = 'a' Need char = 'b' (caseless) ab 0: ab 1: ab aB 0: aB 1: aB *** Failers No match AB No match / (?i)abc/xD ------------------------------------------------------------------ 0 9 Bra 0 3 NC abc 9 9 Ket 12 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: caseless extended First char = 'a' (caseless) Need char = 'c' (caseless) /#this is a comment (?i)abc/xD ------------------------------------------------------------------ 0 9 Bra 0 3 NC abc 9 9 Ket 12 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: caseless extended First char = 'a' (caseless) Need char = 'c' (caseless) /123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/D ------------------------------------------------------------------ 0 603 Bra 0 3 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 603 603 Ket 606 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = '1' Need char = '0' /\Q123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890/D ------------------------------------------------------------------ 0 603 Bra 0 3 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 603 603 Ket 606 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = '1' Need char = '0' /\Q\E/D ------------------------------------------------------------------ 0 3 Bra 0 3 3 Ket 6 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char \ 0: /\Q\Ex/D ------------------------------------------------------------------ 0 5 Bra 0 3 x 5 5 Ket 8 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = 'x' No need char / \Q\E/D ------------------------------------------------------------------ 0 5 Bra 0 3 5 5 Ket 8 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = ' ' No need char /a\Q\E/D ------------------------------------------------------------------ 0 5 Bra 0 3 a 5 5 Ket 8 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = 'a' No need char abc 0: a bca 0: a bac 0: a /a\Q\Eb/D ------------------------------------------------------------------ 0 7 Bra 0 3 ab 7 7 Ket 10 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' abc 0: ab /\Q\Eabc/D ------------------------------------------------------------------ 0 9 Bra 0 3 abc 9 9 Ket 12 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' /x*+\w/D ------------------------------------------------------------------ 0 12 Bra 0 3 5 Once 6 x* 8 5 Ket 11 \w 12 12 Ket 15 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported No options No first char No need char *** Failers 0: F xxxxx No match /x?+/D ------------------------------------------------------------------ 0 11 Bra 0 3 5 Once 6 x? 8 5 Ket 11 11 Ket 14 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /x++/D ------------------------------------------------------------------ 0 11 Bra 0 3 5 Once 6 x+ 8 5 Ket 11 11 Ket 14 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported No options First char = 'x' No need char /x{1,3}+/D ------------------------------------------------------------------ 0 15 Bra 0 3 9 Once 6 x 8 x{,2} 12 9 Ket 15 15 Ket 18 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported No options First char = 'x' No need char /(x)*+/D ------------------------------------------------------------------ 0 18 Bra 0 3 12 Once 6 Brazero 7 5 Bra 1 10 x 12 5 KetRmax 15 12 Ket 18 18 Ket 21 End ------------------------------------------------------------------ Capturing subpattern count = 1 No options No first char No need char /^(\w++|\s++)*$/ Capturing subpattern count = 1 Partial matching not supported Options: anchored No first char No need char now is the time for all good men to come to the aid of the party 0: now is the time for all good men to come to the aid of the party 1: party *** Failers No match this is not a line with only words and spaces! No match /(\d++)(\w)/ Capturing subpattern count = 2 Partial matching not supported No options No first char No need char 12345a 0: 12345a 1: 12345 2: a *** Failers No match 12345+ No match /a++b/ Capturing subpattern count = 0 Partial matching not supported No options First char = 'a' Need char = 'b' aaab 0: aaab /(a++b)/ Capturing subpattern count = 1 Partial matching not supported No options First char = 'a' Need char = 'b' aaab 0: aaab 1: aaab /(a++)b/ Capturing subpattern count = 1 Partial matching not supported No options First char = 'a' Need char = 'b' aaab 0: aaab 1: aaa /([^()]++|\([^()]*\))+/ Capturing subpattern count = 1 Partial matching not supported No options No first char No need char ((abc(ade)ufh()()x 0: abc(ade)ufh()()x 1: x /\(([^()]++|\([^()]+\))+\)/ Capturing subpattern count = 1 Partial matching not supported No options First char = '(' Need char = ')' (abc) 0: (abc) 1: abc (abc(def)xyz) 0: (abc(def)xyz) 1: xyz *** Failers No match ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa No match /(abc){1,3}+/D ------------------------------------------------------------------ 0 53 Bra 0 3 47 Once 6 9 Bra 1 9 abc 15 9 Ket 18 Brazero 19 28 Bra 0 22 9 Bra 1 25 abc 31 9 Ket 34 Brazero 35 9 Bra 1 38 abc 44 9 Ket 47 28 Ket 50 47 Ket 53 53 Ket 56 End ------------------------------------------------------------------ Capturing subpattern count = 1 No options First char = 'a' Need char = 'c' /a+?+/ Failed: nothing to repeat at offset 3 /a{2,3}?+b/ Failed: nothing to repeat at offset 7 /(?U)a+?+/ Failed: nothing to repeat at offset 7 /a{2,3}?+b/U Failed: nothing to repeat at offset 7 /x(?U)a++b/D ------------------------------------------------------------------ 0 15 Bra 0 3 x 5 5 Once 8 a+ 10 5 Ket 13 b 15 15 Ket 18 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported No options First char = 'x' Need char = 'b' xaaaab 0: xaaaab /(?U)xa++b/D ------------------------------------------------------------------ 0 15 Bra 0 3 x 5 5 Once 8 a+ 10 5 Ket 13 b 15 15 Ket 18 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported Options: ungreedy First char = 'x' Need char = 'b' xaaaab 0: xaaaab /^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/D ------------------------------------------------------------------ 0 106 Bra 0 3 ^ 4 99 Bra 1 7 5 Bra 2 10 a+ 12 5 Ket 15 37 Bra 3 18 [ab]+? 52 37 Ket 55 37 Bra 4 58 [bc]+ 92 37 Ket 95 5 Bra 5 98 \w* 100 5 Ket 103 99 Ket 106 106 Ket 109 End ------------------------------------------------------------------ Capturing subpattern count = 5 Partial matching not supported Options: anchored No first char No need char /^x(?U)a+b/D ------------------------------------------------------------------ 0 10 Bra 0 3 ^ 4 x 6 a+? 8 b 10 10 Ket 13 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported Options: anchored No first char Need char = 'b' /^x(?U)(a+)b/D ------------------------------------------------------------------ 0 16 Bra 0 3 ^ 4 x 6 5 Bra 1 9 a+? 11 5 Ket 14 b 16 16 Ket 19 End ------------------------------------------------------------------ Capturing subpattern count = 1 Partial matching not supported Options: anchored No first char Need char = 'b' /[.x.]/ Failed: POSIX collating elements are not supported at offset 0 /[=x=]/ Failed: POSIX collating elements are not supported at offset 0 /[:x:]/ Failed: POSIX named classes are supported only within a class at offset 0 /\l/ Failed: PCRE does not support \L, \l, \N, \U, or \u at offset 1 /\L/ Failed: PCRE does not support \L, \l, \N, \U, or \u at offset 1 /\N{name}/ Failed: PCRE does not support \L, \l, \N, \U, or \u at offset 1 /\u/ Failed: PCRE does not support \L, \l, \N, \U, or \u at offset 1 /\U/ Failed: PCRE does not support \L, \l, \N, \U, or \u at offset 1 /[/ Failed: missing terminating ] for character class at offset 1 /[a-/ Failed: missing terminating ] for character class at offset 3 /[[:space:]/ Failed: missing terminating ] for character class at offset 10 /[\s]/DM Memory allocation (code space): 40 ------------------------------------------------------------------ 0 36 Bra 0 3 [\x09\x0a\x0c\x0d ] 36 36 Ket 39 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[[:space:]]/DM Memory allocation (code space): 40 ------------------------------------------------------------------ 0 36 Bra 0 3 [\x09-\x0d ] 36 36 Ket 39 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /[[:space:]abcde]/DM Memory allocation (code space): 40 ------------------------------------------------------------------ 0 36 Bra 0 3 [\x09-\x0d a-e] 36 36 Ket 39 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /< (?: (?(R) \d++ | [^<>]*+) | (?R)) * >/x Capturing subpattern count = 0 Partial matching not supported Options: extended First char = '<' Need char = '>' <> 0: <> 0: hij> 0: hij> hij> 0: def> 0: def> 0: <> *** Failers No match iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|DM Memory allocation (code space): 826 ------------------------------------------------------------------ 0 822 Bra 0 3 8J$WE<.rX+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDDqmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X 821 \b 822 822 Ket 825 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = '8' Need char = 'X' |\$\<\.X\+ix\[d1b\!H\#\?vV0vrK\:ZH1\=2M\>iV\;\?aPhFB\<\*vW\@QW\@sO9\}cfZA\-i\'w\%hKd6gt1UJP\,15_\#QY\$M\^Mss_U\/\]\&LK9\[5vQub\^w\[KDD\qmj\;2\}YWFdYx\.Ap\]hjCPTP\(n28k\+3\;o\&WXqs\/gOXdr\$\:r\'do0\;b4c\(f_Gr\=\"\\4\)\[01T7ajQJvL\$W\~mL_sS\/4h\:x\*\[ZN\=KLs\&L5zX\/\/\>it\,o\:aU\(\;Z\>pW\&T7oP\'2K\^E\:x9\'c\[\%z\-\,64JQ5AeH_G\#KijUKghQw\^\\vea3a\?kka_G\$8\#\`\*kynsxzBLru\'\]k_\[7FrVx\}\^\=\$blx\>s\-N\%j\;D\*aZDnsw\:YKZ\%Q\.Kne9\#hP\?\+b3\(SOvL\,\^\;\&u5\@\?5C5Bhb\=m\-vEh_L15Jl\]U\)0RP6\{q\%L\^_z5E\'Dw6X\b|DM Memory allocation (code space): 816 ------------------------------------------------------------------ 0 812 Bra 0 3 $<.X+ix[d1b!H#?vV0vrK:ZH1=2M>iV;?aPhFB<*vW@QW@sO9}cfZA-i'w%hKd6gt1UJP,15_#QY$M^Mss_U/]&LK9[5vQub^w[KDDqmj;2}YWFdYx.Ap]hjCPTP(n28k+3;o&WXqs/gOXdr$:r'do0;b4c(f_Gr="\4)[01T7ajQJvL$W~mL_sS/4h:x*[ZN=KLs&L5zX//>it,o:aU(;Z>pW&T7oP'2K^E:x9'c[%z-,64JQ5AeH_G#KijUKghQw^\vea3a?kka_G$8#`*kynsxzBLru']k_[7FrVx}^=$blx>s-N%j;D*aZDnsw:YKZ%Q.Kne9#hP?+b3(SOvL,^;&u5@?5C5Bhb=m-vEh_L15Jl]U)0RP6{q%L^_z5E'Dw6X 811 \b 812 812 Ket 815 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = '$' Need char = 'X' /(.*)\d+\1/I Capturing subpattern count = 1 Max back reference = 1 Partial matching not supported No options No first char No need char /(.*)\d+/I Capturing subpattern count = 1 Partial matching not supported No options First char at start or follows \n No need char /(.*)\d+\1/Is Capturing subpattern count = 1 Max back reference = 1 Partial matching not supported Options: dotall No first char No need char /(.*)\d+/Is Capturing subpattern count = 1 Partial matching not supported Options: anchored dotall No first char No need char /(.*(xyz))\d+\2/I Capturing subpattern count = 2 Max back reference = 2 Partial matching not supported No options First char at start or follows \n Need char = 'z' /((.*))\d+\1/I Capturing subpattern count = 2 Max back reference = 1 Partial matching not supported No options No first char No need char abc123bc 0: bc123bc 1: bc 2: bc /a[b]/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' /(?=a).*/I Capturing subpattern count = 0 Partial matching not supported No options First char = 'a' No need char /(?=abc).xyz/iI Capturing subpattern count = 0 Options: caseless First char = 'a' (caseless) Need char = 'z' (caseless) /(?=abc)(?i).xyz/I Capturing subpattern count = 0 No options Case state changes First char = 'a' Need char = 'z' (caseless) /(?=a)(?=b)/I Capturing subpattern count = 0 No options First char = 'a' No need char /(?=.)a/I Capturing subpattern count = 0 No options First char = 'a' No need char /((?=abcda)a)/I Capturing subpattern count = 1 No options First char = 'a' Need char = 'a' /((?=abcda)ab)/I Capturing subpattern count = 1 No options First char = 'a' Need char = 'b' /()a/I Capturing subpattern count = 1 No options No first char Need char = 'a' /(?(1)ab|ac)/I Capturing subpattern count = 0 No options First char = 'a' No need char /(?(1)abz|acz)/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'z' /(?(1)abz)/I Capturing subpattern count = 0 No options No first char No need char /(?(1)abz)123/I Capturing subpattern count = 0 No options No first char Need char = '3' /(a)+/I Capturing subpattern count = 1 No options First char = 'a' No need char /(a){2,3}/I Capturing subpattern count = 1 No options First char = 'a' Need char = 'a' /(a)*/I Capturing subpattern count = 1 No options No first char No need char /[a]/I Capturing subpattern count = 0 No options First char = 'a' No need char /[ab]/I Capturing subpattern count = 0 No options No first char No need char /[ab]/IS Capturing subpattern count = 0 No options No first char No need char Starting byte set: a b /[^a]/I Capturing subpattern count = 0 No options No first char No need char /\d456/I Capturing subpattern count = 0 No options No first char Need char = '6' /\d456/IS Capturing subpattern count = 0 No options No first char Need char = '6' Starting byte set: 0 1 2 3 4 5 6 7 8 9 /a^b/I Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' /^a/mI Capturing subpattern count = 0 Options: multiline First char at start or follows \n Need char = 'a' abcde 0: a xy\nabc 0: a *** Failers No match xyabc No match /c|abc/I Capturing subpattern count = 0 No options No first char Need char = 'c' /(?i)[ab]/IS Capturing subpattern count = 0 Options: caseless No first char No need char Starting byte set: A B a b /[ab](?i)cd/IS Capturing subpattern count = 0 No options Case state changes No first char Need char = 'd' (caseless) Starting byte set: a b /abc(?C)def/ Capturing subpattern count = 0 No options First char = 'a' Need char = 'f' abcdef --->abcdef 0 ^ ^ d 0: abcdef 1234abcdef --->1234abcdef 0 ^ ^ d 0: abcdef *** Failers No match abcxyz No match abcxyzf --->abcxyzf 0 ^ ^ d No match /abc(?C)de(?C1)f/ Capturing subpattern count = 0 No options First char = 'a' Need char = 'f' 123abcdef --->123abcdef 0 ^ ^ d 1 ^ ^ f 0: abcdef /(?C1)\dabc(?C2)def/ Capturing subpattern count = 0 No options No first char Need char = 'f' 1234abcdef --->1234abcdef 1 ^ \d 1 ^ \d 1 ^ \d 1 ^ \d 2 ^ ^ d 0: 4abcdef *** Failers No match abcdef --->abcdef 1 ^ \d 1 ^ \d 1 ^ \d 1 ^ \d 1 ^ \d 1 ^ \d No match /(?C255)ab/ Capturing subpattern count = 0 No options First char = 'a' Need char = 'b' /(?C256)ab/ Failed: number after (?C is > 255 at offset 6 /(?Cab)xx/ Failed: closing ) for (?C expected at offset 3 /(?C12vr)x/ Failed: closing ) for (?C expected at offset 5 /abc(?C)def/ Capturing subpattern count = 0 No options First char = 'a' Need char = 'f' *** Failers No match \x83\x0\x61bcdef --->\x83\x00abcdef 0 ^ ^ d 0: abcdef /(abc)(?C)de(?C1)f/ Capturing subpattern count = 1 No options First char = 'a' Need char = 'f' 123abcdef --->123abcdef 0 ^ ^ d 1 ^ ^ f 0: abcdef 1: abc 123abcdef\C+ Callout 0: last capture = 1 0: 1: abc --->123abcdef ^ ^ d Callout 1: last capture = 1 0: 1: abc --->123abcdef ^ ^ f 0: abcdef 1: abc 123abcdef\C- 0: abcdef 1: abc *** Failers No match 123abcdef\C!1 --->123abcdef 0 ^ ^ d 1 ^ ^ f No match /(?C0)(abc(?C1))*/ Capturing subpattern count = 1 No options No first char No need char abcabcabc --->abcabcabc 0 ^ (abc(?C1))* 1 ^ ^ ) 1 ^ ^ ) 1 ^ ^ ) 0: abcabcabc 1: abc abcabc\C!1!3 --->abcabc 0 ^ (abc(?C1))* 1 ^ ^ ) 1 ^ ^ ) 0: abcabc 1: abc *** Failers --->*** Failers 0 ^ (abc(?C1))* 0: abcabcabc\C!1!3 --->abcabcabc 0 ^ (abc(?C1))* 1 ^ ^ ) 1 ^ ^ ) 1 ^ ^ ) 0: abcabc 1: abc /(\d{3}(?C))*/ Capturing subpattern count = 1 Partial matching not supported No options No first char No need char 123\C+ Callout 0: last capture = -1 0: --->123 ^ ^ ) 0: 123 1: 123 123456\C+ Callout 0: last capture = -1 0: --->123456 ^ ^ ) Callout 0: last capture = 1 0: 1: 123 --->123456 ^ ^ ) 0: 123456 1: 456 123456789\C+ Callout 0: last capture = -1 0: --->123456789 ^ ^ ) Callout 0: last capture = 1 0: 1: 123 --->123456789 ^ ^ ) Callout 0: last capture = 1 0: 1: 456 --->123456789 ^ ^ ) 0: 123456789 1: 789 /((xyz)(?C)p|(?C1)xyzabc)/ Capturing subpattern count = 2 No options First char = 'x' No need char xyzabc\C+ Callout 0: last capture = 2 0: 1: 2: xyz --->xyzabc ^ ^ p Callout 1: last capture = -1 0: --->xyzabc ^ x 0: xyzabc 1: xyzabc /(X)((xyz)(?C)p|(?C1)xyzabc)/ Capturing subpattern count = 3 No options First char = 'X' Need char = 'x' Xxyzabc\C+ Callout 0: last capture = 3 0: 1: X 2: 3: xyz --->Xxyzabc ^ ^ p Callout 1: last capture = 1 0: 1: X --->Xxyzabc ^^ x 0: Xxyzabc 1: X 2: xyzabc /(?=(abc))(?C)abcdef/ Capturing subpattern count = 1 No options First char = 'a' Need char = 'f' abcdef\C+ Callout 0: last capture = 1 0: 1: abc --->abcdef ^ a 0: abcdef 1: abc /(?!(abc)(?C1)d)(?C2)abcxyz/ Capturing subpattern count = 1 No options First char = 'a' Need char = 'z' abcxyz\C+ Callout 1: last capture = 1 0: 1: abc --->abcxyz ^ ^ d Callout 2: last capture = -1 0: --->abcxyz ^ a 0: abcxyz /(?<=(abc)(?C))xyz/ Capturing subpattern count = 1 No options First char = 'x' Need char = 'z' abcxyz\C+ Callout 0: last capture = 1 0: 1: abc --->abcxyz ^ ) 0: xyz 1: abc /(?C)abc/ Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' /(?C)^abc/ Capturing subpattern count = 0 Options: anchored No first char No need char /(?C)a|b/S Capturing subpattern count = 0 No options No first char No need char Starting byte set: a b /(?R)/ Failed: recursive call could loop indefinitely at offset 3 /(a|(?R))/ Failed: recursive call could loop indefinitely at offset 6 /(ab|(bc|(de|(?R))))/ Failed: recursive call could loop indefinitely at offset 15 /x(ab|(bc|(de|(?R))))/ Capturing subpattern count = 3 No options First char = 'x' No need char xab 0: xab 1: ab xbc 0: xbc 1: bc 2: bc xde 0: xde 1: de 2: de 3: de xxab 0: xxab 1: xab 2: xab 3: xab xxxab 0: xxxab 1: xxab 2: xxab 3: xxab *** Failers No match xyab No match /(ab|(bc|(de|(?1))))/ Failed: recursive call could loop indefinitely at offset 15 /x(ab|(bc|(de|(?1)x)x)x)/ Failed: recursive call could loop indefinitely at offset 16 /^([^()]|\((?1)*\))*$/ Capturing subpattern count = 1 Options: anchored No first char No need char abc 0: abc 1: c a(b)c 0: a(b)c 1: c a(b(c))d 0: a(b(c))d 1: d *** Failers) No match a(b(c)d No match /^>abc>([^()]|\((?1)*\))*abc>123abc>123abc>1(2)3abc>1(2)3abc>(1(2)3)abc>(1(2)3) 2: 3: Satan, oscillate my metallic sonatas 4: S A man, a plan, a canal: Panama! 0: A man, a plan, a canal: Panama! 1: 2: 3: A man, a plan, a canal: Panama 4: A Able was I ere I saw Elba. 0: Able was I ere I saw Elba. 1: 2: 3: Able was I ere I saw Elba 4: A *** Failers No match The quick brown fox No match /^(\d+|\((?1)([+*-])(?1)\)|-(?1))$/ Capturing subpattern count = 2 Partial matching not supported Options: anchored No first char No need char 12 0: 12 1: 12 (((2+2)*-3)-7) 0: (((2+2)*-3)-7) 1: (((2+2)*-3)-7) 2: - -12 0: -12 1: -12 *** Failers No match ((2+2)*-3)-7) No match /^(x(y|(?1){2})z)/ Capturing subpattern count = 2 Options: anchored No first char No need char xyz 0: xyz 1: xyz 2: y xxyzxyzz 0: xxyzxyzz 1: xxyzxyzz 2: xyzxyz *** Failers No match xxyzz No match xxyzxyzxyzz No match /((< (?: (?(R) \d++ | [^<>]*+) | (?2)) * >))/x Capturing subpattern count = 2 Partial matching not supported Options: extended First char = '<' Need char = '>' <> 0: <> 1: <> 2: <> 0: 1: 2: hij> 0: hij> 1: hij> 2: hij> hij> 0: 1: 2: def> 0: def> 1: def> 2: def> 0: <> 1: <> 2: <> *** Failers No match b|c)d(?Pe)/D ------------------------------------------------------------------ 0 28 Bra 0 3 a 5 5 Bra 1 8 b 10 5 Alt 13 c 15 10 Ket 18 d 20 5 Bra 2 23 e 25 5 Ket 28 28 Ket 31 End ------------------------------------------------------------------ Capturing subpattern count = 2 Named capturing subpatterns: longername2 2 name1 1 No options First char = 'a' Need char = 'e' abde 0: abde 1: b 2: e acde 0: acde 1: c 2: e /(?:a(?Pc(?Pd)))(?Pa)/D ------------------------------------------------------------------ 0 35 Bra 0 3 21 Bra 0 6 a 8 13 Bra 1 11 c 13 5 Bra 2 16 d 18 5 Ket 21 13 Ket 24 21 Ket 27 5 Bra 3 30 a 32 5 Ket 35 35 Ket 38 End ------------------------------------------------------------------ Capturing subpattern count = 3 Named capturing subpatterns: a 3 c 1 d 2 No options First char = 'a' Need char = 'a' /(?Pa)...(?P=a)bbb(?P>a)d/D ------------------------------------------------------------------ 0 28 Bra 0 3 5 Bra 1 6 a 8 5 Ket 11 Any 12 Any 13 Any 14 \1 17 bbb 23 3 Recurse 26 d 28 28 Ket 31 End ------------------------------------------------------------------ Capturing subpattern count = 1 Max back reference = 1 Named capturing subpatterns: a 1 No options First char = 'a' Need char = 'd' /^\W*(?:(?P(?P.)\W*(?P>one)\W*(?P=two)|)|(?P(?P.)\W*(?P>three)\W*(?P=four)|\W*.\W*))\W*$/i Capturing subpattern count = 4 Max back reference = 4 Named capturing subpatterns: four 4 one 1 three 3 two 2 Partial matching not supported Options: anchored caseless No first char No need char 1221 0: 1221 1: 1221 2: 1 Satan, oscillate my metallic sonatas! 0: Satan, oscillate my metallic sonatas! 1: 2: 3: Satan, oscillate my metallic sonatas 4: S A man, a plan, a canal: Panama! 0: A man, a plan, a canal: Panama! 1: 2: 3: A man, a plan, a canal: Panama 4: A Able was I ere I saw Elba. 0: Able was I ere I saw Elba. 1: 2: 3: Able was I ere I saw Elba 4: A *** Failers No match The quick brown fox No match /((?(R)a|b))\1(?1)?/ Capturing subpattern count = 1 Max back reference = 1 No options No first char No need char bb 0: bb 1: b bbaa 0: bba 1: b /(.*)a/sI Capturing subpattern count = 1 Partial matching not supported Options: anchored dotall No first char Need char = 'a' /(.*)a\1/sI Capturing subpattern count = 1 Max back reference = 1 Partial matching not supported Options: dotall No first char Need char = 'a' /(.*)a(b)\2/sI Capturing subpattern count = 2 Max back reference = 2 Partial matching not supported Options: anchored dotall No first char Need char = 'b' /((.*)a|(.*)b)z/sI Capturing subpattern count = 3 Partial matching not supported Options: anchored dotall No first char Need char = 'z' /((.*)a|(.*)b)z\1/sI Capturing subpattern count = 3 Max back reference = 1 Partial matching not supported Options: dotall No first char Need char = 'z' /((.*)a|(.*)b)z\2/sI Capturing subpattern count = 3 Max back reference = 2 Partial matching not supported Options: dotall No first char Need char = 'z' /((.*)a|(.*)b)z\3/sI Capturing subpattern count = 3 Max back reference = 3 Partial matching not supported Options: dotall No first char Need char = 'z' /((.*)a|^(.*)b)z\3/sI Capturing subpattern count = 3 Max back reference = 3 Partial matching not supported Options: anchored dotall No first char Need char = 'z' /(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a/sI Capturing subpattern count = 31 Partial matching not supported Options: anchored dotall No first char No need char /(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\31/sI Capturing subpattern count = 31 Max back reference = 31 Partial matching not supported Options: dotall No first char No need char /(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)|(.*)a\32/sI Capturing subpattern count = 32 Max back reference = 32 Partial matching not supported Options: dotall No first char No need char /(a)(bc)/ND ------------------------------------------------------------------ 0 21 Bra 0 3 5 Bra 0 6 a 8 5 Ket 11 7 Bra 0 14 bc 18 7 Ket 21 21 Ket 24 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: First char = 'a' Need char = 'c' abc 0: abc /(?Pa)(bc)/ND ------------------------------------------------------------------ 0 21 Bra 0 3 5 Bra 1 6 a 8 5 Ket 11 7 Bra 0 14 bc 18 7 Ket 21 21 Ket 24 End ------------------------------------------------------------------ Capturing subpattern count = 1 Named capturing subpatterns: one 1 Options: First char = 'a' Need char = 'c' abc 0: abc 1: a /(a)(?Pbc)/ND ------------------------------------------------------------------ 0 21 Bra 0 3 5 Bra 0 6 a 8 5 Ket 11 7 Bra 1 14 bc 18 7 Ket 21 21 Ket 24 End ------------------------------------------------------------------ Capturing subpattern count = 1 Named capturing subpatterns: named 1 Options: First char = 'a' Need char = 'c' /(a+)*zz/ Capturing subpattern count = 1 Partial matching not supported No options No first char Need char = 'z' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazzbbbbbb\M Minimum match limit = 8 0: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaazz 1: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaz\M Minimum match limit = 32768 No match /(aaa(?C1)bbb|ab)/ Capturing subpattern count = 1 No options First char = 'a' Need char = 'b' aaabbb --->aaabbb 1 ^ ^ b 0: aaabbb 1: aaabbb aaabbb\C*0 --->aaabbb 1 ^ ^ b 0: aaabbb 1: aaabbb aaabbb\C*1 --->aaabbb 1 ^ ^ b Callout data = 1 0: ab 1: ab aaabbb\C*-1 --->aaabbb 1 ^ ^ b Callout data = -1 No match /ab(?Pcd)ef(?Pgh)/ Capturing subpattern count = 2 Named capturing subpatterns: one 1 two 2 No options First char = 'a' Need char = 'h' abcdefgh 0: abcdefgh 1: cd 2: gh abcdefgh\C1\Gtwo 0: abcdefgh 1: cd 2: gh 1C cd (2) 2G gh (2) abcdefgh\Cone\Ctwo 0: abcdefgh 1: cd 2: gh 1C cd (2) 2C gh (2) abcdefgh\Cthree no parentheses with name "three" 0: abcdefgh 1: cd 2: gh /(?P)(?P)/D ------------------------------------------------------------------ 0 15 Bra 0 3 3 Bra 1 6 3 Ket 9 3 Bra 2 12 3 Ket 15 15 Ket 18 End ------------------------------------------------------------------ Capturing subpattern count = 2 Named capturing subpatterns: Tes 1 Test 2 No options No first char No need char /(?P)(?P)/D ------------------------------------------------------------------ 0 15 Bra 0 3 3 Bra 1 6 3 Ket 9 3 Bra 2 12 3 Ket 15 15 Ket 18 End ------------------------------------------------------------------ Capturing subpattern count = 2 Named capturing subpatterns: Tes 2 Test 1 No options No first char No need char /(?Pzz)(?Paa)/ Capturing subpattern count = 2 Named capturing subpatterns: A 2 Z 1 No options First char = 'z' Need char = 'a' zzaa\CZ 0: zzaa 1: zz 2: aa 1C zz (2) zzaa\CA 0: zzaa 1: zz 2: aa 2C aa (2) /(?Peks)(?Peccs)/ Failed: two named groups have the same name at offset 16 /(?Pabc(?Pdef)(?Pxyz))/ Failed: two named groups have the same name at offset 31 "\[((?P\d+)(,(?P>elem))*)\]" Capturing subpattern count = 3 Named capturing subpatterns: elem 2 Partial matching not supported No options First char = '[' Need char = ']' [10,20,30,5,5,4,4,2,43,23,4234] 0: [10,20,30,5,5,4,4,2,43,23,4234] 1: 10,20,30,5,5,4,4,2,43,23,4234 2: 10 3: ,4234 *** Failers No match [] No match "\[((?P\d+)(,(?P>elem))*)?\]" Capturing subpattern count = 3 Named capturing subpatterns: elem 2 Partial matching not supported No options First char = '[' Need char = ']' [10,20,30,5,5,4,4,2,43,23,4234] 0: [10,20,30,5,5,4,4,2,43,23,4234] 1: 10,20,30,5,5,4,4,2,43,23,4234 2: 10 3: ,4234 [] 0: [] /(a(b(?2)c))?/D ------------------------------------------------------------------ 0 25 Bra 0 3 Brazero 4 18 Bra 1 7 a 9 10 Bra 2 12 b 14 9 Recurse 17 c 19 10 Ket 22 18 Ket 25 25 Ket 28 End ------------------------------------------------------------------ Capturing subpattern count = 2 No options No first char No need char /(a(b(?2)c))*/D ------------------------------------------------------------------ 0 25 Bra 0 3 Brazero 4 18 Bra 1 7 a 9 10 Bra 2 12 b 14 9 Recurse 17 c 19 10 Ket 22 18 KetRmax 25 25 Ket 28 End ------------------------------------------------------------------ Capturing subpattern count = 2 No options No first char No need char /(a(b(?2)c)){0,2}/D ------------------------------------------------------------------ 0 53 Bra 0 3 Brazero 4 46 Bra 0 7 18 Bra 1 10 a 12 10 Bra 2 15 b 17 12 Recurse 20 c 22 10 Ket 25 18 Ket 28 Brazero 29 18 Bra 1 32 a 34 10 Bra 2 37 b 39 12 Recurse 42 c 44 10 Ket 47 18 Ket 50 46 Ket 53 53 Ket 56 End ------------------------------------------------------------------ Capturing subpattern count = 2 No options No first char No need char /[ab]{1}+/D ------------------------------------------------------------------ 0 47 Bra 0 3 41 Once 6 [ab]{1,1} 44 41 Ket 47 47 Ket 50 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options No first char No need char /((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)/i Capturing subpattern count = 3 Partial matching not supported Options: caseless No first char Need char = 'g' (caseless) Baby Bjorn Active Carrier - With free SHIPPING!! 0: Baby Bjorn Active Carrier - With free SHIPPING!! 1: Baby Bjorn Active Carrier - With free SHIPPING!! /((w\/|-|with)*(free|immediate)*.*?shipping\s*[!.-]*)/iS Capturing subpattern count = 3 Partial matching not supported Options: caseless No first char Need char = 'g' (caseless) Study returned NULL Baby Bjorn Active Carrier - With free SHIPPING!! 0: Baby Bjorn Active Carrier - With free SHIPPING!! 1: Baby Bjorn Active Carrier - With free SHIPPING!! /a*.*b/SD ------------------------------------------------------------------ 0 9 Bra 0 3 a* 5 Any* 7 b 9 9 Ket 12 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported No options No first char Need char = 'b' Study returned NULL /(a|b)*.?c/SD ------------------------------------------------------------------ 0 21 Bra 0 3 Brazero 4 5 Bra 1 7 a 9 5 Alt 12 b 14 10 KetRmax 17 Any? 19 c 21 21 Ket 24 End ------------------------------------------------------------------ Capturing subpattern count = 1 No options No first char Need char = 'c' Study returned NULL /abc(?C255)de(?C)f/D ------------------------------------------------------------------ 0 27 Bra 0 3 abc 9 Callout 255 10 1 15 de 19 Callout 0 16 1 25 f 27 27 Ket 30 End ------------------------------------------------------------------ Capturing subpattern count = 0 No options First char = 'a' Need char = 'f' /abcde/CD ------------------------------------------------------------------ 0 49 Bra 0 3 Callout 255 0 1 9 a 11 Callout 255 1 1 17 b 19 Callout 255 2 1 25 c 27 Callout 255 3 1 33 d 35 Callout 255 4 1 41 e 43 Callout 255 5 0 49 49 Ket 52 End ------------------------------------------------------------------ Capturing subpattern count = 0 Options: First char = 'a' Need char = 'e' abcde --->abcde +0 ^ a +1 ^^ b +2 ^ ^ c +3 ^ ^ d +4 ^ ^ e +5 ^ ^ 0: abcde abcdfe --->abcdfe +0 ^ a +1 ^^ b +2 ^ ^ c +3 ^ ^ d +4 ^ ^ e No match /a*b/CD ------------------------------------------------------------------ 0 25 Bra 0 3 Callout 255 0 2 9 a* 11 Callout 255 2 1 17 b 19 Callout 255 3 0 25 25 Ket 28 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported Options: No first char Need char = 'b' ab --->ab +0 ^ a* +2 ^^ b +3 ^ ^ 0: ab aaaab --->aaaab +0 ^ a* +2 ^ ^ b +3 ^ ^ 0: aaaab aaaacb --->aaaacb +0 ^ a* +2 ^ ^ b +2 ^ ^ b +2 ^ ^ b +2 ^^ b +2 ^ b +0 ^ a* +2 ^ ^ b +2 ^ ^ b +2 ^^ b +2 ^ b +0 ^ a* +2 ^ ^ b +2 ^^ b +2 ^ b +0 ^ a* +2 ^^ b +2 ^ b +0 ^ a* +2 ^ b +0 ^ a* +2 ^ b +3 ^^ 0: b /a+b/CD ------------------------------------------------------------------ 0 25 Bra 0 3 Callout 255 0 2 9 a+ 11 Callout 255 2 1 17 b 19 Callout 255 3 0 25 25 Ket 28 End ------------------------------------------------------------------ Capturing subpattern count = 0 Partial matching not supported Options: First char = 'a' Need char = 'b' ab --->ab +0 ^ a+ +2 ^^ b +3 ^ ^ 0: ab aaaab --->aaaab +0 ^ a+ +2 ^ ^ b +3 ^ ^ 0: aaaab aaaacb --->aaaacb +0 ^ a+ +2 ^ ^ b +2 ^ ^ b +2 ^ ^ b +2 ^^ b +0 ^ a+ +2 ^ ^ b +2 ^ ^ b +2 ^^ b +0 ^ a+ +2 ^ ^ b +2 ^^ b +0 ^ a+ +2 ^^ b No match /(abc|def)x/CD ------------------------------------------------------------------ 0 92 Bra 0 3 Callout 255 0 9 9 33 Bra 1 12 Callout 255 1 1 18 a 20 Callout 255 2 1 26 b 28 Callout 255 3 1 34 c 36 Callout 255 4 0 42 33 Alt 45 Callout 255 5 1 51 d 53 Callout 255 6 1 59 e 61 Callout 255 7 1 67 f 69 Callout 255 8 0 75 66 Ket 78 Callout 255 9 1 84 x 86 Callout 255 10 0 92 92 Ket 95 End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: No first char Need char = 'x' abcx --->abcx +0 ^ (abc|def) +1 ^ a +2 ^^ b +3 ^ ^ c +4 ^ ^ | +9 ^ ^ x +10 ^ ^ 0: abcx 1: abc defx --->defx +0 ^ (abc|def) +1 ^ a +5 ^ d +6 ^^ e +7 ^ ^ f +8 ^ ^ ) +9 ^ ^ x +10 ^ ^ 0: defx 1: def abcdefzx --->abcdefzx +0 ^ (abc|def) +1 ^ a +2 ^^ b +3 ^ ^ c +4 ^ ^ | +9 ^ ^ x +5 ^ d +0 ^ (abc|def) +1 ^ a +5 ^ d +0 ^ (abc|def) +1 ^ a +5 ^ d +0 ^ (abc|def) +1 ^ a +5 ^ d +6 ^^ e +7 ^ ^ f +8 ^ ^ ) +9 ^ ^ x +0 ^ (abc|def) +1 ^ a +5 ^ d +0 ^ (abc|def) +1 ^ a +5 ^ d +0 ^ (abc|def) +1 ^ a +5 ^ d +0 ^ (abc|def) +1 ^ a +5 ^ d No match /(ab|cd){3,4}/C Capturing subpattern count = 1 Options: No first char No need char ababab --->ababab +0 ^ (ab|cd){3,4} +1 ^ a +2 ^^ b +3 ^ ^ | +1 ^ ^ a +2 ^ ^ b +3 ^ ^ | +1 ^ ^ a +2 ^ ^ b +3 ^ ^ | +1 ^ ^ a +4 ^ ^ c +12 ^ ^ 0: ababab 1: ab abcdabcd --->abcdabcd +0 ^ (ab|cd){3,4} +1 ^ a +2 ^^ b +3 ^ ^ | +1 ^ ^ a +4 ^ ^ c +5 ^ ^ d +6 ^ ^ ) +1 ^ ^ a +2 ^ ^ b +3 ^ ^ | +1 ^ ^ a +4 ^ ^ c +5 ^ ^ d +6 ^ ^ ) +12 ^ ^ 0: abcdabcd 1: cd abcdcdcdcdcd --->abcdcdcdcdcd +0 ^ (ab|cd){3,4} +1 ^ a +2 ^^ b +3 ^ ^ | +1 ^ ^ a +4 ^ ^ c +5 ^ ^ d +6 ^ ^ ) +1 ^ ^ a +4 ^ ^ c +5 ^ ^ d +6 ^ ^ ) +1 ^ ^ a +4 ^ ^ c +5 ^ ^ d +6 ^ ^ ) +12 ^ ^ 0: abcdcdcd 1: cd /([ab]{,4}c|xy)/CD ------------------------------------------------------------------ 0 131 Bra 0 3 Callout 255 0 14 9 88 Bra 1 12 Callout 255 1 4 18 [ab] 51 Callout 255 5 1 57 { 59 Callout 255 6 1 65 , 67 Callout 255 7 1 73 4 75 Callout 255 8 1 81 } 83 Callout 255 9 1 89 c 91 Callout 255 10 0 97 25 Alt 100 Callout 255 11 1 106 x 108 Callout 255 12 1 114 y 116 Callout 255 13 0 122 113 Ket 125 Callout 255 14 0 131 131 Ket 134 End ------------------------------------------------------------------ Capturing subpattern count = 1 Options: No first char No need char Note: that { does NOT introduce a quantifier --->Note: that { does NOT introduce a quantifier +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +5 ^^ { +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +5 ^^ { +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +5 ^^ { +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x +0 ^ ([ab]{,4}c|xy) +1 ^ [ab] +11 ^ x No match /([ab]{1,4}c|xy){4,5}?123/CD ------------------------------------------------------------------ 0 485 Bra 0 3 Callout 255 0 21 9 61 Bra 1 12 Callout 255 1 9 18 [ab]{1,4} 56 Callout 255 10 1 62 c 64 Callout 255 11 0 70 25 Alt 73 Callout 255 12 1 79 x 81 Callout 255 13 1 87 y 89 Callout 255 14 0 95 86 Ket 98 61 Bra 1 101 Callout 255 1 9 107 [ab]{1,4} 145 Callout 255 10 1 151 c 153 Callout 255 11 0 159 25 Alt 162 Callout 255 12 1 168 x 170 Callout 255 13 1 176 y 178 Callout 255 14 0 184 86 Ket 187 61 Bra 1 190 Callout 255 1 9 196 [ab]{1,4} 234 Callout 255 10 1 240 c 242 Callout 255 11 0 248 25 Alt 251 Callout 255 12 1 257 x 259 Callout 255 13 1 265 y 267 Callout 255 14 0 273 86 Ket 276 61 Bra 1 279 Callout 255 1 9 285 [ab]{1,4} 323 Callout 255 10 1 329 c 331 Callout 255 11 0 337 25 Alt 340 Callout 255 12 1 346 x 348 Callout 255 13 1 354 y 356 Callout 255 14 0 362 86 Ket 365 Braminzero 366 61 Bra 1 369 Callout 255 1 9 375 [ab]{1,4} 413 Callout 255 10 1 419 c 421 Callout 255 11 0 427 25 Alt 430 Callout 255 12 1 436 x 438 Callout 255 13 1 444 y 446 Callout 255 14 0 452 86 Ket 455 Callout 255 21 1 461 1 463 Callout 255 22 1 469 2 471 Callout 255 23 1 477 3 479 Callout 255 24 0 485 485 Ket 488 End ------------------------------------------------------------------ Capturing subpattern count = 1 Partial matching not supported Options: No first char Need char = '3' aacaacaacaacaac123 --->aacaacaacaacaac123 +0 ^ ([ab]{1,4}c|xy){4,5}? +1 ^ [ab]{1,4} +10 ^ ^ c +11 ^ ^ | +1 ^ ^ [ab]{1,4} +10 ^ ^ c +11 ^ ^ | +1 ^ ^ [ab]{1,4} +10 ^ ^ c +11 ^ ^ | +1 ^ ^ [ab]{1,4} +10 ^ ^ c +11 ^ ^ | +21 ^ ^ 1 +1 ^ ^ [ab]{1,4} +10 ^ ^ c +11 ^ ^ | +21 ^ ^ 1 +22 ^ ^ 2 +23 ^ ^ 3 +24 ^ ^ 0: aacaacaacaacaac123 1: aac /\b.*/I Capturing subpattern count = 0 Partial matching not supported No options No first char No need char ab cd\>1 0: cd /\b.*/Is Capturing subpattern count = 0 Partial matching not supported Options: dotall No first char No need char ab cd\>1 0: cd /(?!.bcd).*/I Capturing subpattern count = 0 Partial matching not supported No options No first char No need char Xbcd12345 0: bcd12345 /abcde/ Capturing subpattern count = 0 No options First char = 'a' Need char = 'e' ab\P Partial match abc\P Partial match abcd\P Partial match abcde\P 0: abcde the quick brown abc\P Partial match ** Failers\P No match the quick brown abxyz fox\P No match "^(0?[1-9]|[12][0-9]|3[01])/(0?[1-9]|1[012])/(20)?\d\d$" Capturing subpattern count = 3 Options: anchored No first char Need char = '/' 13/05/04\P 0: 13/05/04 1: 13 2: 05 13/5/2004\P 0: 13/5/2004 1: 13 2: 5 3: 20 02/05/09\P 0: 02/05/09 1: 02 2: 05 1\P Partial match 1/2\P Partial match 1/2/0\P Partial match 1/2/04\P 0: 1/2/04 1: 1 2: 2 0\P Partial match 02/\P Partial match 02/0\P Partial match 02/1\P Partial match ** Failers\P No match \P No match 123\P No match 33/4/04\P No match 3/13/04\P No match 0/1/2003\P No match 0/\P No match 02/0/\P No match 02/13\P No match /0{0,2}ABC/I Capturing subpattern count = 0 Partial matching not supported No options No first char Need char = 'C' /\d{3,}ABC/I Capturing subpattern count = 0 Partial matching not supported No options No first char Need char = 'C' /\d*ABC/I Capturing subpattern count = 0 Partial matching not supported No options No first char Need char = 'C' /[abc]+DE/I Capturing subpattern count = 0 Partial matching not supported No options No first char Need char = 'E' /[abc]?123/ Capturing subpattern count = 0 No options No first char Need char = '3' 123\P 0: 123 a\P Partial match b\P Partial match c\P Partial match c12\P Partial match c123\P 0: c123 /^(?:\d){3,5}X/ Capturing subpattern count = 0 Options: anchored No first char Need char = 'X' 1\P Partial match 123\P Partial match 123X 0: 123X 1234\P Partial match 1234X 0: 1234X 12345\P Partial match 12345X 0: 12345X *** Failers No match 1X No match 123456\P No match /abc/>testsavedregex Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' Compiled regex written to testsavedregex testsavedregex Capturing subpattern count = 0 No options First char = 'a' Need char = 'c' Compiled regex written to testsavedregex testsavedregex Capturing subpattern count = 1 No options No first char No need char Starting byte set: a b Compiled regex written to testsavedregex Study data written to testsavedregex testsavedregex Capturing subpattern count = 1 No options No first char No need char Starting byte set: a b Compiled regex written to testsavedregex Study data written to testsavedregex (.)*~smg Capturing subpattern count = 3 Max back reference = 1 Partial matching not supported Options: multiline dotall First char = '<' Need char = '>' \n\n\nPartner der LCO\nde\nPartner der LINEAS Consulting\nGmbH\nLINEAS Consulting GmbH Hamburg\nPartnerfirmen\n30 days\nindex,follow\n\nja\n3\nPartner\n\n\nLCO\nLINEAS Consulting\n15.10.2003\n\n\n\n\nDie Partnerfirmen der LINEAS Consulting\nGmbH\n\n\n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n 0: \x0a\x0aPartner der LCO\x0ade\x0aPartner der LINEAS Consulting\x0aGmbH\x0aLINEAS Consulting GmbH Hamburg\x0aPartnerfirmen\x0a30 days\x0aindex,follow\x0a\x0aja\x0a3\x0aPartner\x0a\x0a\x0aLCO\x0aLINEAS Consulting\x0a15.10.2003\x0a\x0a\x0a\x0a\x0aDie Partnerfirmen der LINEAS Consulting\x0aGmbH\x0a\x0a\x0a \x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a\x0a 1: seite 2: \x0a 3: seite /^a/IF Capturing subpattern count = 0 Options: anchored No first char No need char / End of testinput2 / Capturing subpattern count = 0 No options First char = ' ' Need char = ' ' tomcat-connectors-1.2.41-src/native/iis/pcre/configure.in0000644000000000000020000001041610517277132021636 0ustar rootbindnl Process this file with autoconf to produce a configure script. dnl This is required at the start; the name is the name of a file dnl it should be seeing, to verify it is in the same directory. AC_INIT(dftables.c) dnl A safety precaution AC_PREREQ(2.57) dnl Arrange to build config.h from config.in. Note that pcre.h is dnl built differently, as it is just a "substitution" file. dnl Manual says this macro should come right after AC_INIT. AC_CONFIG_HEADER(config.h:config.in) dnl Provide the current PCRE version information. Do not use numbers dnl with leading zeros for the minor version, as they end up in a C dnl macro, and may be treated as octal constants. Stick to single dnl digits for minor numbers less than 10. There are unlikely to be dnl that many releases anyway. PCRE_MAJOR=5 PCRE_MINOR=0 PCRE_DATE=13-Sep-2004 PCRE_VERSION=${PCRE_MAJOR}.${PCRE_MINOR} dnl Default values for miscellaneous macros POSIX_MALLOC_THRESHOLD=-DPOSIX_MALLOC_THRESHOLD=10 dnl Provide versioning information for libtool shared libraries that dnl are built by default on Unix systems. PCRE_LIB_VERSION=0:1:0 PCRE_POSIXLIB_VERSION=0:0:0 dnl Checks for programs. AC_PROG_CC dnl Checks for header files. AC_HEADER_STDC AC_CHECK_HEADERS(limits.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_TYPE_SIZE_T dnl Checks for library functions. AC_CHECK_FUNCS(bcopy memmove strerror) dnl Handle --enable-shared-libraries LIBTOOL=./libtool LIBSUFFIX=la AC_ARG_ENABLE(shared, [ --disable-shared build PCRE as a static library], if test "$enableval" = "no"; then LIBTOOL= LIBSUFFIX=a fi ) dnl Handle --enable-utf8 AC_ARG_ENABLE(utf8, [ --enable-utf8 enable UTF8 support], if test "$enableval" = "yes"; then UTF8=-DSUPPORT_UTF8 fi ) dnl Handle --enable-unicode-properties AC_ARG_ENABLE(unicode-properties, [ --enable-unicode-properties enable Unicode properties support], if test "$enableval" = "yes"; then UCP=-DSUPPORT_UCP fi ) dnl Handle --enable-newline-is-cr AC_ARG_ENABLE(newline-is-cr, [ --enable-newline-is-cr use CR as the newline character], if test "$enableval" = "yes"; then NEWLINE=-DNEWLINE=13 fi ) dnl Handle --enable-newline-is-lf AC_ARG_ENABLE(newline-is-lf, [ --enable-newline-is-lf use LF as the newline character], if test "$enableval" = "yes"; then NEWLINE=-DNEWLINE=10 fi ) dnl Handle --enable-ebcdic AC_ARG_ENABLE(ebcdic, [ --enable-ebcdic assume EBCDIC coding rather than ASCII], if test "$enableval" == "yes"; then EBCDIC=-DEBCDIC=1 fi ) dnl Handle --disable-stack-for-recursion AC_ARG_ENABLE(stack-for-recursion, [ --disable-stack-for-recursion disable use of stack recursion when matching], if test "$enableval" = "no"; then NO_RECURSE=-DNO_RECURSE fi ) dnl There doesn't seem to be a straightforward way of having parameters dnl that set values, other than fudging the --with thing. So that's what dnl I've done. dnl Handle --with-posix-malloc-threshold=n AC_ARG_WITH(posix-malloc-threshold, [ --with-posix-malloc-threshold=5 threshold for POSIX malloc usage], POSIX_MALLOC_THRESHOLD=-DPOSIX_MALLOC_THRESHOLD=$withval ) dnl Handle --with-link-size=n AC_ARG_WITH(link-size, [ --with-link-size=2 internal link size (2, 3, or 4 allowed)], LINK_SIZE=-DLINK_SIZE=$withval ) dnl Handle --with-match_limit=n AC_ARG_WITH(match-limit, [ --with-match-limit=10000000 default limit on internal looping)], MATCH_LIMIT=-DMATCH_LIMIT=$withval ) dnl Unicode character property support implies UTF-8 support if test "$UCP" != "" ; then UTF8=-DSUPPORT_UTF8 fi dnl "Export" these variables AC_SUBST(BUILD_EXEEXT) AC_SUBST(BUILD_OBJEXT) AC_SUBST(CC_FOR_BUILD) AC_SUBST(CFLAGS_FOR_BUILD) AC_SUBST(EBCDIC) AC_SUBST(HAVE_MEMMOVE) AC_SUBST(HAVE_STRERROR) AC_SUBST(LIBTOOL) AC_SUBST(LIBSUFFIX) AC_SUBST(LINK_SIZE) AC_SUBST(MATCH_LIMIT) AC_SUBST(NEWLINE) AC_SUBST(NO_RECURSE) AC_SUBST(PCRE_MAJOR) AC_SUBST(PCRE_MINOR) AC_SUBST(PCRE_DATE) AC_SUBST(PCRE_VERSION) AC_SUBST(PCRE_LIB_VERSION) AC_SUBST(PCRE_POSIXLIB_VERSION) AC_SUBST(POSIX_MALLOC_THRESHOLD) AC_SUBST(UCP) AC_SUBST(UTF8) if test "x$enable_shared" = "xno" ; then AC_DEFINE([PCRE_STATIC],[1],[to link statically]) fi dnl This must be last; it determines what files are written as well as config.h AC_OUTPUT(Makefile pcre.h:pcre.in pcre-config,[chmod a+x pcre-config]) tomcat-connectors-1.2.41-src/native/iis/pcre/NEWS0000644000000000000020000002041410517277132020023 0ustar rootbinNews about PCRE releases ------------------------ Release 5.0 13-Sep-04 --------------------- The licence under which PCRE is released has been changed to the more conventional "BSD" licence. In the code, some bugs have been fixed, and there are also some major changes in this release (which is why I've increased the number to 5.0). Some changes are internal rearrangements, and some provide a number of new facilities. The new features are: 1. There's an "automatic callout" feature that inserts callouts before every item in the regex, and there's a new callout field that gives the position in the pattern - useful for debugging and tracing. 2. The extra_data structure can now be used to pass in a set of character tables at exec time. This is useful if compiled regex are saved and re-used at a later time when the tables may not be at the same address. If the default internal tables are used, the pointer saved with the compiled pattern is now set to NULL, which means that you don't need to do anything special unless you are using custom tables. 3. It is possible, with some restrictions on the content of the regex, to request "partial" matching. A special return code is given if all of the subject string matched part of the regex. This could be useful for testing an input field as it is being typed. 4. There is now some optional support for Unicode character properties, which means that the patterns items such as \p{Lu} and \X can now be used. Only the general category properties are supported. If PCRE is compiled with this support, an additional 90K data structure is include, which increases the size of the library dramatically. 5. There is support for saving compiled patterns and re-using them later. 6. There is support for running regular expressions that were compiled on a different host with the opposite endianness. 7. The pcretest program has been extended to accommodate the new features. The main internal rearrangement is that sequences of literal characters are no longer handled as strings. Instead, each character is handled on its own. This makes some UTF-8 handling easier, and makes the support of partial matching possible. Compiled patterns containing long literal strings will be larger as a result of this change; I hope that performance will not be much affected. Release 4.5 01-Dec-03 --------------------- Again mainly a bug-fix and tidying release, with only a couple of new features: 1. It's possible now to compile PCRE so that it does not use recursive function calls when matching. Instead it gets memory from the heap. This slows things down, but may be necessary on systems with limited stacks. 2. UTF-8 string checking has been tightened to reject overlong sequences and to check that a starting offset points to the start of a character. Failure of the latter returns a new error code: PCRE_ERROR_BADUTF8_OFFSET. 3. PCRE can now be compiled for systems that use EBCDIC code. Release 4.4 21-Aug-03 --------------------- This is mainly a bug-fix and tidying release. The only new feature is that PCRE checks UTF-8 strings for validity by default. There is an option to suppress this, just in case anybody wants that teeny extra bit of performance. Releases 4.1 - 4.3 ------------------ Sorry, I forgot about updating the NEWS file for these releases. Please take a look at ChangeLog. Release 4.0 17-Feb-03 --------------------- There have been a lot of changes for the 4.0 release, adding additional functionality and mending bugs. Below is a list of the highlights of the new functionality. For full details of these features, please consult the documentation. For a complete list of changes, see the ChangeLog file. 1. Support for Perl's \Q...\E escapes. 2. "Possessive quantifiers" ?+, *+, ++, and {,}+ which come from Sun's Java package. They provide some syntactic sugar for simple cases of "atomic grouping". 3. Support for the \G assertion. It is true when the current matching position is at the start point of the match. 4. A new feature that provides some of the functionality that Perl provides with (?{...}). The facility is termed a "callout". The way it is done in PCRE is for the caller to provide an optional function, by setting pcre_callout to its entry point. To get the function called, the regex must include (?C) at appropriate points. 5. Support for recursive calls to individual subpatterns. This makes it really easy to get totally confused. 6. Support for named subpatterns. The Python syntax (?P...) is used to name a group. 7. Several extensions to UTF-8 support; it is now fairly complete. There is an option for pcregrep to make it operate in UTF-8 mode. 8. The single man page has been split into a number of separate man pages. These also give rise to individual HTML pages which are put in a separate directory. There is an index.html page that lists them all. Some hyperlinking between the pages has been installed. Release 3.5 15-Aug-01 --------------------- 1. The configuring system has been upgraded to use later versions of autoconf and libtool. By default it builds both a shared and a static library if the OS supports it. You can use --disable-shared or --disable-static on the configure command if you want only one of them. 2. The pcretest utility is now installed along with pcregrep because it is useful for users (to test regexs) and by doing this, it automatically gets relinked by libtool. The documentation has been turned into a man page, so there are now .1, .txt, and .html versions in /doc. 3. Upgrades to pcregrep: (i) Added long-form option names like gnu grep. (ii) Added --help to list all options with an explanatory phrase. (iii) Added -r, --recursive to recurse into sub-directories. (iv) Added -f, --file to read patterns from a file. 4. Added --enable-newline-is-cr and --enable-newline-is-lf to the configure script, to force use of CR or LF instead of \n in the source. On non-Unix systems, the value can be set in config.h. 5. The limit of 200 on non-capturing parentheses is a _nesting_ limit, not an absolute limit. Changed the text of the error message to make this clear, and likewise updated the man page. 6. The limit of 99 on the number of capturing subpatterns has been removed. The new limit is 65535, which I hope will not be a "real" limit. Release 3.3 01-Aug-00 --------------------- There is some support for UTF-8 character strings. This is incomplete and experimental. The documentation describes what is and what is not implemented. Otherwise, this is just a bug-fixing release. Release 3.0 01-Feb-00 --------------------- 1. A "configure" script is now used to configure PCRE for Unix systems. It builds a Makefile, a config.h file, and the pcre-config script. 2. PCRE is built as a shared library by default. 3. There is support for POSIX classes such as [:alpha:]. 5. There is an experimental recursion feature. ---------------------------------------------------------------------------- IMPORTANT FOR THOSE UPGRADING FROM VERSIONS BEFORE 2.00 Please note that there has been a change in the API such that a larger ovector is required at matching time, to provide some additional workspace. The new man page has details. This change was necessary in order to support some of the new functionality in Perl 5.005. IMPORTANT FOR THOSE UPGRADING FROM VERSION 2.00 Another (I hope this is the last!) change has been made to the API for the pcre_compile() function. An additional argument has been added to make it possible to pass over a pointer to character tables built in the current locale by pcre_maketables(). To use the default tables, this new arguement should be passed as NULL. IMPORTANT FOR THOSE UPGRADING FROM VERSION 2.05 Yet another (and again I hope this really is the last) change has been made to the API for the pcre_exec() function. An additional argument has been added to make it possible to start the match other than at the start of the subject string. This is important if there are lookbehinds. The new man page has the details, but you just want to convert existing programs, all you need to do is to stick in a new fifth argument to pcre_exec(), with a value of zero. For example, change pcre_exec(pattern, extra, subject, length, options, ovec, ovecsize) to pcre_exec(pattern, extra, subject, length, 0, options, ovec, ovecsize) **** tomcat-connectors-1.2.41-src/native/iis/pcre/makevp.bat0000644000000000000020000000154210517277132021300 0ustar rootbin@echo off REM This file was contributed by Alexander Tokarev for building PCRE for use REM with Virtual Pascal. It has not been tested with the latest PCRE release. REM CHANGE THIS FOR YOUR BORLAND C++ COMPILER PATH SET BORLAND=c:\usr\apps\bcc55 sh configure bcc32 -DDFTABLES -DSTATIC -DVPCOMPAT -I%BORLAND%\include -L%BORLAND%\lib dftables.c dftables > chartables.c bcc32 -c -RT- -y- -v- -u- -P- -O2 -5 -DSTATIC -DVPCOMPAT -UDFTABLES -I%BORLAND%\include get.c maketables.c pcre.c study.c tlib %BORLAND%\lib\cw32.lib *calloc *del *strncmp *memcpy *memmove *memset tlib pcre.lib +get.obj +maketables.obj +pcre.obj +study.obj +calloc.obj +del.obj +strncmp.obj +memcpy.obj +memmove.obj +memset.obj del *.obj *.exe *.tds *.bak >nul 2>nul echo --- echo Now the library should be complete. Please check all messages above. echo Don't care for warnings, it's OK. tomcat-connectors-1.2.41-src/native/iis/pcre/doc/0000755000000000000020000000000012555256552020077 5ustar rootbintomcat-connectors-1.2.41-src/native/iis/pcre/doc/README_httpd0000644000000000000020000000055110517277132022154 0ustar rootbinThe documentation directory has been omitted from this copy of PCRE inside the httpd codebase because it's huge--over a megabyte of PCRE docs. The PCRE documentation directory is available in unmodified form in the vendor branch. You can access it via web browser or Subversion checkout at http://svn.apache.org/repos/asf/httpd/httpd/vendor/pcre/current/doc/ tomcat-connectors-1.2.41-src/native/iis/pcre/ChangeLog0000644000000000000020000021727110517277132021107 0ustar rootbinChangeLog for PCRE ------------------ Version 5.0 13-Sep-04 --------------------- 1. Internal change: literal characters are no longer packed up into items containing multiple characters in a single byte-string. Each character is now matched using a separate opcode. However, there may be more than one byte in the character in UTF-8 mode. 2. The pcre_callout_block structure has two new fields: pattern_position and next_item_length. These contain the offset in the pattern to the next match item, and its length, respectively. 3. The PCRE_AUTO_CALLOUT option for pcre_compile() requests the automatic insertion of callouts before each pattern item. Added the /C option to pcretest to make use of this. 4. On the advice of a Windows user, the lines #if defined(_WIN32) || defined(WIN32) _setmode( _fileno( stdout ), 0x8000 ); #endif /* defined(_WIN32) || defined(WIN32) */ have been added to the source of pcretest. This apparently does useful magic in relation to line terminators. 5. Changed "r" and "w" in the calls to fopen() in pcretest to "rb" and "wb" for the benefit of those environments where the "b" makes a difference. 6. The icc compiler has the same options as gcc, but "configure" doesn't seem to know about it. I have put a hack into configure.in that adds in code to set GCC=yes if CC=icc. This seems to end up at a point in the generated configure script that is early enough to affect the setting of compiler options, which is what is needed, but I have no means of testing whether it really works. (The user who reported this had patched the generated configure script, which of course I cannot do.) LATER: After change 22 below (new libtool files), the configure script seems to know about icc (and also ecc). Therefore, I have commented out this hack in configure.in. 7. Added support for pkg-config (2 patches were sent in). 8. Negated POSIX character classes that used a combination of internal tables were completely broken. These were [[:^alpha:]], [[:^alnum:]], and [[:^ascii]]. Typically, they would match almost any characters. The other POSIX classes were not broken in this way. 9. Matching the pattern "\b.*?" against "ab cd", starting at offset 1, failed to find the match, as PCRE was deluded into thinking that the match had to start at the start point or following a newline. The same bug applied to patterns with negative forward assertions or any backward assertions preceding ".*" at the start, unless the pattern required a fixed first character. This was a failing pattern: "(?!.bcd).*". The bug is now fixed. 10. In UTF-8 mode, when moving forwards in the subject after a failed match starting at the last subject character, bytes beyond the end of the subject string were read. 11. Renamed the variable "class" as "classbits" to make life easier for C++ users. (Previously there was a macro definition, but it apparently wasn't enough.) 12. Added the new field "tables" to the extra data so that tables can be passed in at exec time, or the internal tables can be re-selected. This allows a compiled regex to be saved and re-used at a later time by a different program that might have everything at different addresses. 13. Modified the pcre-config script so that, when run on Solaris, it shows a -R library as well as a -L library. 14. The debugging options of pcretest (-d on the command line or D on a pattern) showed incorrect output for anything following an extended class that contained multibyte characters and which was followed by a quantifier. 15. Added optional support for general category Unicode character properties via the \p, \P, and \X escapes. Unicode property support implies UTF-8 support. It adds about 90K to the size of the library. The meanings of the inbuilt class escapes such as \d and \s have NOT been changed. 16. Updated pcredemo.c to include calls to free() to release the memory for the compiled pattern. 17. The generated file chartables.c was being created in the source directory instead of in the building directory. This caused the build to fail if the source directory was different from the building directory, and was read-only. 18. Added some sample Win commands from Mark Tetrode into the NON-UNIX-USE file. No doubt somebody will tell me if they don't make sense... Also added Dan Mooney's comments about building on OpenVMS. 19. Added support for partial matching via the PCRE_PARTIAL option for pcre_exec() and the \P data escape in pcretest. 20. Extended pcretest with 3 new pattern features: (i) A pattern option of the form ">rest-of-line" causes pcretest to write the compiled pattern to the file whose name is "rest-of-line". This is a straight binary dump of the data, with the saved pointer to the character tables forced to be NULL. The study data, if any, is written too. After writing, pcretest reads a new pattern. (ii) If, instead of a pattern, ": new target : new target : use native compiler : use native linker : handle Windows platform correctly : ditto : ditto copy DLL to top builddir before testing As part of these changes, -no-undefined was removed again. This was reported to give trouble on HP-UX 11.0, so getting rid of it seems like a good idea in any case. 3. Some tidies to get rid of compiler warnings: . In the match_data structure, match_limit was an unsigned long int, whereas match_call_count was an int. I've made them both unsigned long ints. . In pcretest the fact that a const uschar * doesn't automatically cast to a void * provoked a warning. . Turning on some more compiler warnings threw up some "shadow" variables and a few more missing casts. 4. If PCRE was complied with UTF-8 support, but called without the PCRE_UTF8 option, a class that contained a single character with a value between 128 and 255 (e.g. /[\xFF]/) caused PCRE to crash. 5. If PCRE was compiled with UTF-8 support, but called without the PCRE_UTF8 option, a class that contained several characters, but with at least one whose value was between 128 and 255 caused PCRE to crash. Version 4.1 12-Mar-03 --------------------- 1. Compiling with gcc -pedantic found a couple of places where casts were needed, and a string in dftables.c that was longer than standard compilers are required to support. 2. Compiling with Sun's compiler found a few more places where the code could be tidied up in order to avoid warnings. 3. The variables for cross-compiling were called HOST_CC and HOST_CFLAGS; the first of these names is deprecated in the latest Autoconf in favour of the name CC_FOR_BUILD, because "host" is typically used to mean the system on which the compiled code will be run. I can't find a reference for HOST_CFLAGS, but by analogy I have changed it to CFLAGS_FOR_BUILD. 4. Added -no-undefined to the linking command in the Makefile, because this is apparently helpful for Windows. To make it work, also added "-L. -lpcre" to the linking step for the pcreposix library. 5. PCRE was failing to diagnose the case of two named groups with the same name. 6. A problem with one of PCRE's optimizations was discovered. PCRE remembers a literal character that is needed in the subject for a match, and scans along to ensure that it is present before embarking on the full matching process. This saves time in cases of nested unlimited repeats that are never going to match. Problem: the scan can take a lot of time if the subject is very long (e.g. megabytes), thus penalizing straightforward matches. It is now done only if the amount of subject to be scanned is less than 1000 bytes. 7. A lesser problem with the same optimization is that it was recording the first character of an anchored pattern as "needed", thus provoking a search right along the subject, even when the first match of the pattern was going to fail. The "needed" character is now not set for anchored patterns, unless it follows something in the pattern that is of non-fixed length. Thus, it still fulfils its original purpose of finding quick non-matches in cases of nested unlimited repeats, but isn't used for simple anchored patterns such as /^abc/. Version 4.0 17-Feb-03 --------------------- 1. If a comment in an extended regex that started immediately after a meta-item extended to the end of string, PCRE compiled incorrect data. This could lead to all kinds of weird effects. Example: /#/ was bad; /()#/ was bad; /a#/ was not. 2. Moved to autoconf 2.53 and libtool 1.4.2. 3. Perl 5.8 no longer needs "use utf8" for doing UTF-8 things. Consequently, the special perltest8 script is no longer needed - all the tests can be run from a single perltest script. 4. From 5.004, Perl has not included the VT character (0x0b) in the set defined by \s. It has now been removed in PCRE. This means it isn't recognized as whitespace in /x regexes too, which is the same as Perl. Note that the POSIX class [:space:] *does* include VT, thereby creating a mess. 5. Added the class [:blank:] (a GNU extension from Perl 5.8) to match only space and tab. 6. Perl 5.005 was a long time ago. It's time to amalgamate the tests that use its new features into the main test script, reducing the number of scripts. 7. Perl 5.8 has changed the meaning of patterns like /a(?i)b/. Earlier versions were backward compatible, and made the (?i) apply to the whole pattern, as if /i were given. Now it behaves more logically, and applies the option setting only to what follows. PCRE has been changed to follow suit. However, if it finds options settings right at the start of the pattern, it extracts them into the global options, as before. Thus, they show up in the info data. 8. Added support for the \Q...\E escape sequence. Characters in between are treated as literals. This is slightly different from Perl in that $ and @ are also handled as literals inside the quotes. In Perl, they will cause variable interpolation. Note the following examples: Pattern PCRE matches Perl matches \Qabc$xyz\E abc$xyz abc followed by the contents of $xyz \Qabc\$xyz\E abc\$xyz abc\$xyz \Qabc\E\$\Qxyz\E abc$xyz abc$xyz For compatibility with Perl, \Q...\E sequences are recognized inside character classes as well as outside them. 9. Re-organized 3 code statements in pcretest to avoid "overflow in floating-point constant arithmetic" warnings from a Microsoft compiler. Added a (size_t) cast to one statement in pcretest and one in pcreposix to avoid signed/unsigned warnings. 10. SunOS4 doesn't have strtoul(). This was used only for unpicking the -o option for pcretest, so I've replaced it by a simple function that does just that job. 11. pcregrep was ending with code 0 instead of 2 for the commands "pcregrep" or "pcregrep -". 12. Added "possessive quantifiers" ?+, *+, ++, and {,}+ which come from Sun's Java package. This provides some syntactic sugar for simple cases of what my documentation calls "once-only subpatterns". A pattern such as x*+ is the same as (?>x*). In other words, if what is inside (?>...) is just a single repeated item, you can use this simplified notation. Note that only makes sense with greedy quantifiers. Consequently, the use of the possessive quantifier forces greediness, whatever the setting of the PCRE_UNGREEDY option. 13. A change of greediness default within a pattern was not taking effect at the current level for patterns like /(b+(?U)a+)/. It did apply to parenthesized subpatterns that followed. Patterns like /b+(?U)a+/ worked because the option was abstracted outside. 14. PCRE now supports the \G assertion. It is true when the current matching position is at the start point of the match. This differs from \A when the starting offset is non-zero. Used with the /g option of pcretest (or similar code), it works in the same way as it does for Perl's /g option. If all alternatives of a regex begin with \G, the expression is anchored to the start match position, and the "anchored" flag is set in the compiled expression. 15. Some bugs concerning the handling of certain option changes within patterns have been fixed. These applied to options other than (?ims). For example, "a(?x: b c )d" did not match "XabcdY" but did match "Xa b c dY". It should have been the other way round. Some of this was related to change 7 above. 16. PCRE now gives errors for /[.x.]/ and /[=x=]/ as unsupported POSIX features, as Perl does. Previously, PCRE gave the warnings only for /[[.x.]]/ and /[[=x=]]/. PCRE now also gives an error for /[:name:]/ because it supports POSIX classes only within a class (e.g. /[[:alpha:]]/). 17. Added support for Perl's \C escape. This matches one byte, even in UTF8 mode. Unlike ".", it always matches newline, whatever the setting of PCRE_DOTALL. However, PCRE does not permit \C to appear in lookbehind assertions. Perl allows it, but it doesn't (in general) work because it can't calculate the length of the lookbehind. At least, that's the case for Perl 5.8.0 - I've been told they are going to document that it doesn't work in future. 18. Added an error diagnosis for escapes that PCRE does not support: these are \L, \l, \N, \P, \p, \U, \u, and \X. 19. Although correctly diagnosing a missing ']' in a character class, PCRE was reading past the end of the pattern in cases such as /[abcd/. 20. PCRE was getting more memory than necessary for patterns with classes that contained both POSIX named classes and other characters, e.g. /[[:space:]abc/. 21. Added some code, conditional on #ifdef VPCOMPAT, to make life easier for compiling PCRE for use with Virtual Pascal. 22. Small fix to the Makefile to make it work properly if the build is done outside the source tree. 23. Added a new extension: a condition to go with recursion. If a conditional subpattern starts with (?(R) the "true" branch is used if recursion has happened, whereas the "false" branch is used only at the top level. 24. When there was a very long string of literal characters (over 255 bytes without UTF support, over 250 bytes with UTF support), the computation of how much memory was required could be incorrect, leading to segfaults or other strange effects. 25. PCRE was incorrectly assuming anchoring (either to start of subject or to start of line for a non-DOTALL pattern) when a pattern started with (.*) and there was a subsequent back reference to those brackets. This meant that, for example, /(.*)\d+\1/ failed to match "abc123bc". Unfortunately, it isn't possible to check for precisely this case. All we can do is abandon the optimization if .* occurs inside capturing brackets when there are any back references whatsoever. (See below for a better fix that came later.) 26. The handling of the optimization for finding the first character of a non-anchored pattern, and for finding a character that is required later in the match were failing in some cases. This didn't break the matching; it just failed to optimize when it could. The way this is done has been re-implemented. 27. Fixed typo in error message for invalid (?R item (it said "(?p"). 28. Added a new feature that provides some of the functionality that Perl provides with (?{...}). The facility is termed a "callout". The way it is done in PCRE is for the caller to provide an optional function, by setting pcre_callout to its entry point. Like pcre_malloc and pcre_free, this is a global variable. By default it is unset, which disables all calling out. To get the function called, the regex must include (?C) at appropriate points. This is, in fact, equivalent to (?C0), and any number <= 255 may be given with (?C). This provides a means of identifying different callout points. When PCRE reaches such a point in the regex, if pcre_callout has been set, the external function is called. It is provided with data in a structure called pcre_callout_block, which is defined in pcre.h. If the function returns 0, matching continues; if it returns a non-zero value, the match at the current point fails. However, backtracking will occur if possible. [This was changed later and other features added - see item 49 below.] 29. pcretest is upgraded to test the callout functionality. It provides a callout function that displays information. By default, it shows the start of the match and the current position in the text. There are some new data escapes to vary what happens: \C+ in addition, show current contents of captured substrings \C- do not supply a callout function \C!n return 1 when callout number n is reached \C!n!m return 1 when callout number n is reached for the mth time 30. If pcregrep was called with the -l option and just a single file name, it output "" if a match was found, instead of the file name. 31. Improve the efficiency of the POSIX API to PCRE. If the number of capturing slots is less than POSIX_MALLOC_THRESHOLD, use a block on the stack to pass to pcre_exec(). This saves a malloc/free per call. The default value of POSIX_MALLOC_THRESHOLD is 10; it can be changed by --with-posix-malloc-threshold when configuring. 32. The default maximum size of a compiled pattern is 64K. There have been a few cases of people hitting this limit. The code now uses macros to handle the storing of links as offsets within the compiled pattern. It defaults to 2-byte links, but this can be changed to 3 or 4 bytes by --with-link-size when configuring. Tests 2 and 5 work only with 2-byte links because they output debugging information about compiled patterns. 33. Internal code re-arrangements: (a) Moved the debugging function for printing out a compiled regex into its own source file (printint.c) and used #include to pull it into pcretest.c and, when DEBUG is defined, into pcre.c, instead of having two separate copies. (b) Defined the list of op-code names for debugging as a macro in internal.h so that it is next to the definition of the opcodes. (c) Defined a table of op-code lengths for simpler skipping along compiled code. This is again a macro in internal.h so that it is next to the definition of the opcodes. 34. Added support for recursive calls to individual subpatterns, along the lines of Robin Houston's patch (but implemented somewhat differently). 35. Further mods to the Makefile to help Win32. Also, added code to pcregrep to allow it to read and process whole directories in Win32. This code was contributed by Lionel Fourquaux; it has not been tested by me. 36. Added support for named subpatterns. The Python syntax (?P...) is used to name a group. Names consist of alphanumerics and underscores, and must be unique. Back references use the syntax (?P=name) and recursive calls use (?P>name) which is a PCRE extension to the Python extension. Groups still have numbers. The function pcre_fullinfo() can be used after compilation to extract a name/number map. There are three relevant calls: PCRE_INFO_NAMEENTRYSIZE yields the size of each entry in the map PCRE_INFO_NAMECOUNT yields the number of entries PCRE_INFO_NAMETABLE yields a pointer to the map. The map is a vector of fixed-size entries. The size of each entry depends on the length of the longest name used. The first two bytes of each entry are the group number, most significant byte first. There follows the corresponding name, zero terminated. The names are in alphabetical order. 37. Make the maximum literal string in the compiled code 250 for the non-UTF-8 case instead of 255. Making it the same both with and without UTF-8 support means that the same test output works with both. 38. There was a case of malloc(0) in the POSIX testing code in pcretest. Avoid calling malloc() with a zero argument. 39. Change 25 above had to resort to a heavy-handed test for the .* anchoring optimization. I've improved things by keeping a bitmap of backreferences with numbers 1-31 so that if .* occurs inside capturing brackets that are not in fact referenced, the optimization can be applied. It is unlikely that a relevant occurrence of .* (i.e. one which might indicate anchoring or forcing the match to follow \n) will appear inside brackets with a number greater than 31, but if it does, any back reference > 31 suppresses the optimization. 40. Added a new compile-time option PCRE_NO_AUTO_CAPTURE. This has the effect of disabling numbered capturing parentheses. Any opening parenthesis that is not followed by ? behaves as if it were followed by ?: but named parentheses can still be used for capturing (and they will acquire numbers in the usual way). 41. Redesigned the return codes from the match() function into yes/no/error so that errors can be passed back from deep inside the nested calls. A malloc failure while inside a recursive subpattern call now causes the PCRE_ERROR_NOMEMORY return instead of quietly going wrong. 42. It is now possible to set a limit on the number of times the match() function is called in a call to pcre_exec(). This facility makes it possible to limit the amount of recursion and backtracking, though not in a directly obvious way, because the match() function is used in a number of different circumstances. The count starts from zero for each position in the subject string (for non-anchored patterns). The default limit is, for compatibility, a large number, namely 10 000 000. You can change this in two ways: (a) When configuring PCRE before making, you can use --with-match-limit=n to set a default value for the compiled library. (b) For each call to pcre_exec(), you can pass a pcre_extra block in which a different value is set. See 45 below. If the limit is exceeded, pcre_exec() returns PCRE_ERROR_MATCHLIMIT. 43. Added a new function pcre_config(int, void *) to enable run-time extraction of things that can be changed at compile time. The first argument specifies what is wanted and the second points to where the information is to be placed. The current list of available information is: PCRE_CONFIG_UTF8 The output is an integer that is set to one if UTF-8 support is available; otherwise it is set to zero. PCRE_CONFIG_NEWLINE The output is an integer that it set to the value of the code that is used for newline. It is either LF (10) or CR (13). PCRE_CONFIG_LINK_SIZE The output is an integer that contains the number of bytes used for internal linkage in compiled expressions. The value is 2, 3, or 4. See item 32 above. PCRE_CONFIG_POSIX_MALLOC_THRESHOLD The output is an integer that contains the threshold above which the POSIX interface uses malloc() for output vectors. See item 31 above. PCRE_CONFIG_MATCH_LIMIT The output is an unsigned integer that contains the default limit of the number of match() calls in a pcre_exec() execution. See 42 above. 44. pcretest has been upgraded by the addition of the -C option. This causes it to extract all the available output from the new pcre_config() function, and to output it. The program then exits immediately. 45. A need has arisen to pass over additional data with calls to pcre_exec() in order to support additional features. One way would have been to define pcre_exec2() (for example) with extra arguments, but this would not have been extensible, and would also have required all calls to the original function to be mapped to the new one. Instead, I have chosen to extend the mechanism that is used for passing in "extra" data from pcre_study(). The pcre_extra structure is now exposed and defined in pcre.h. It currently contains the following fields: flags a bitmap indicating which of the following fields are set study_data opaque data from pcre_study() match_limit a way of specifying a limit on match() calls for a specific call to pcre_exec() callout_data data for callouts (see 49 below) The flag bits are also defined in pcre.h, and are PCRE_EXTRA_STUDY_DATA PCRE_EXTRA_MATCH_LIMIT PCRE_EXTRA_CALLOUT_DATA The pcre_study() function now returns one of these new pcre_extra blocks, with the actual study data pointed to by the study_data field, and the PCRE_EXTRA_STUDY_DATA flag set. This can be passed directly to pcre_exec() as before. That is, this change is entirely upwards-compatible and requires no change to existing code. If you want to pass in additional data to pcre_exec(), you can either place it in a pcre_extra block provided by pcre_study(), or create your own pcre_extra block. 46. pcretest has been extended to test the PCRE_EXTRA_MATCH_LIMIT feature. If a data string contains the escape sequence \M, pcretest calls pcre_exec() several times with different match limits, until it finds the minimum value needed for pcre_exec() to complete. The value is then output. This can be instructive; for most simple matches the number is quite small, but for pathological cases it gets very large very quickly. 47. There's a new option for pcre_fullinfo() called PCRE_INFO_STUDYSIZE. It returns the size of the data block pointed to by the study_data field in a pcre_extra block, that is, the value that was passed as the argument to pcre_malloc() when PCRE was getting memory in which to place the information created by pcre_study(). The fourth argument should point to a size_t variable. pcretest has been extended so that this information is shown after a successful pcre_study() call when information about the compiled regex is being displayed. 48. Cosmetic change to Makefile: there's no need to have / after $(DESTDIR) because what follows is always an absolute path. (Later: it turns out that this is more than cosmetic for MinGW, because it doesn't like empty path components.) 49. Some changes have been made to the callout feature (see 28 above): (i) A callout function now has three choices for what it returns: 0 => success, carry on matching > 0 => failure at this point, but backtrack if possible < 0 => serious error, return this value from pcre_exec() Negative values should normally be chosen from the set of PCRE_ERROR_xxx values. In particular, returning PCRE_ERROR_NOMATCH forces a standard "match failed" error. The error number PCRE_ERROR_CALLOUT is reserved for use by callout functions. It will never be used by PCRE itself. (ii) The pcre_extra structure (see 45 above) has a void * field called callout_data, with corresponding flag bit PCRE_EXTRA_CALLOUT_DATA. The pcre_callout_block structure has a field of the same name. The contents of the field passed in the pcre_extra structure are passed to the callout function in the corresponding field in the callout block. This makes it easier to use the same callout-containing regex from multiple threads. For testing, the pcretest program has a new data escape \C*n pass the number n (may be negative) as callout_data If the callout function in pcretest receives a non-zero value as callout_data, it returns that value. 50. Makefile wasn't handling CFLAGS properly when compiling dftables. Also, there were some redundant $(CFLAGS) in commands that are now specified as $(LINK), which already includes $(CFLAGS). 51. Extensions to UTF-8 support are listed below. These all apply when (a) PCRE has been compiled with UTF-8 support *and* pcre_compile() has been compiled with the PCRE_UTF8 flag. Patterns that are compiled without that flag assume one-byte characters throughout. Note that case-insensitive matching applies only to characters whose values are less than 256. PCRE doesn't support the notion of cases for higher-valued characters. (i) A character class whose characters are all within 0-255 is handled as a bit map, and the map is inverted for negative classes. Previously, a character > 255 always failed to match such a class; however it should match if the class was a negative one (e.g. [^ab]). This has been fixed. (ii) A negated character class with a single character < 255 is coded as "not this character" (OP_NOT). This wasn't working properly when the test character was multibyte, either singly or repeated. (iii) Repeats of multibyte characters are now handled correctly in UTF-8 mode, for example: \x{100}{2,3}. (iv) The character escapes \b, \B, \d, \D, \s, \S, \w, and \W (either singly or repeated) now correctly test multibyte characters. However, PCRE doesn't recognize any characters with values greater than 255 as digits, spaces, or word characters. Such characters always match \D, \S, and \W, and never match \d, \s, or \w. (v) Classes may now contain characters and character ranges with values greater than 255. For example: [ab\x{100}-\x{400}]. (vi) pcregrep now has a --utf-8 option (synonym -u) which makes it call PCRE in UTF-8 mode. 52. The info request value PCRE_INFO_FIRSTCHAR has been renamed PCRE_INFO_FIRSTBYTE because it is a byte value. However, the old name is retained for backwards compatibility. (Note that LASTLITERAL is also a byte value.) 53. The single man page has become too large. I have therefore split it up into a number of separate man pages. These also give rise to individual HTML pages; these are now put in a separate directory, and there is an index.html page that lists them all. Some hyperlinking between the pages has been installed. 54. Added convenience functions for handling named capturing parentheses. 55. Unknown escapes inside character classes (e.g. [\M]) and escapes that aren't interpreted therein (e.g. [\C]) are literals in Perl. This is now also true in PCRE, except when the PCRE_EXTENDED option is set, in which case they are faulted. 56. Introduced HOST_CC and HOST_CFLAGS which can be set in the environment when calling configure. These values are used when compiling the dftables.c program which is run to generate the source of the default character tables. They default to the values of CC and CFLAGS. If you are cross-compiling PCRE, you will need to set these values. 57. Updated the building process for Windows DLL, as provided by Fred Cox. Version 3.9 02-Jan-02 --------------------- 1. A bit of extraneous text had somehow crept into the pcregrep documentation. 2. If --disable-static was given, the building process failed when trying to build pcretest and pcregrep. (For some reason it was using libtool to compile them, which is not right, as they aren't part of the library.) Version 3.8 18-Dec-01 --------------------- 1. The experimental UTF-8 code was completely screwed up. It was packing the bytes in the wrong order. How dumb can you get? Version 3.7 29-Oct-01 --------------------- 1. In updating pcretest to check change 1 of version 3.6, I screwed up. This caused pcretest, when used on the test data, to segfault. Unfortunately, this didn't happen under Solaris 8, where I normally test things. 2. The Makefile had to be changed to make it work on BSD systems, where 'make' doesn't seem to recognize that ./xxx and xxx are the same file. (This entry isn't in ChangeLog distributed with 3.7 because I forgot when I hastily made this fix an hour or so after the initial 3.7 release.) Version 3.6 23-Oct-01 --------------------- 1. Crashed with /(sens|respons)e and \1ibility/ and "sense and sensibility" if offsets passed as NULL with zero offset count. 2. The config.guess and config.sub files had not been updated when I moved to the latest autoconf. Version 3.5 15-Aug-01 --------------------- 1. Added some missing #if !defined NOPOSIX conditionals in pcretest.c that had been forgotten. 2. By using declared but undefined structures, we can avoid using "void" definitions in pcre.h while keeping the internal definitions of the structures private. 3. The distribution is now built using autoconf 2.50 and libtool 1.4. From a user point of view, this means that both static and shared libraries are built by default, but this can be individually controlled. More of the work of handling this static/shared cases is now inside libtool instead of PCRE's make file. 4. The pcretest utility is now installed along with pcregrep because it is useful for users (to test regexs) and by doing this, it automatically gets relinked by libtool. The documentation has been turned into a man page, so there are now .1, .txt, and .html versions in /doc. 5. Upgrades to pcregrep: (i) Added long-form option names like gnu grep. (ii) Added --help to list all options with an explanatory phrase. (iii) Added -r, --recursive to recurse into sub-directories. (iv) Added -f, --file to read patterns from a file. 6. pcre_exec() was referring to its "code" argument before testing that argument for NULL (and giving an error if it was NULL). 7. Upgraded Makefile.in to allow for compiling in a different directory from the source directory. 8. Tiny buglet in pcretest: when pcre_fullinfo() was called to retrieve the options bits, the pointer it was passed was to an int instead of to an unsigned long int. This mattered only on 64-bit systems. 9. Fixed typo (3.4/1) in pcre.h again. Sigh. I had changed pcre.h (which is generated) instead of pcre.in, which it its source. Also made the same change in several of the .c files. 10. A new release of gcc defines printf() as a macro, which broke pcretest because it had an ifdef in the middle of a string argument for printf(). Fixed by using separate calls to printf(). 11. Added --enable-newline-is-cr and --enable-newline-is-lf to the configure script, to force use of CR or LF instead of \n in the source. On non-Unix systems, the value can be set in config.h. 12. The limit of 200 on non-capturing parentheses is a _nesting_ limit, not an absolute limit. Changed the text of the error message to make this clear, and likewise updated the man page. 13. The limit of 99 on the number of capturing subpatterns has been removed. The new limit is 65535, which I hope will not be a "real" limit. Version 3.4 22-Aug-00 --------------------- 1. Fixed typo in pcre.h: unsigned const char * changed to const unsigned char *. 2. Diagnose condition (?(0) as an error instead of crashing on matching. Version 3.3 01-Aug-00 --------------------- 1. If an octal character was given, but the value was greater than \377, it was not getting masked to the least significant bits, as documented. This could lead to crashes in some systems. 2. Perl 5.6 (if not earlier versions) accepts classes like [a-\d] and treats the hyphen as a literal. PCRE used to give an error; it now behaves like Perl. 3. Added the functions pcre_free_substring() and pcre_free_substring_list(). These just pass their arguments on to (pcre_free)(), but they are provided because some uses of PCRE bind it to non-C systems that can call its functions, but cannot call free() or pcre_free() directly. 4. Add "make test" as a synonym for "make check". Corrected some comments in the Makefile. 5. Add $(DESTDIR)/ in front of all the paths in the "install" target in the Makefile. 6. Changed the name of pgrep to pcregrep, because Solaris has introduced a command called pgrep for grepping around the active processes. 7. Added the beginnings of support for UTF-8 character strings. 8. Arranged for the Makefile to pass over the settings of CC, CFLAGS, and RANLIB to ./ltconfig so that they are used by libtool. I think these are all the relevant ones. (AR is not passed because ./ltconfig does its own figuring out for the ar command.) Version 3.2 12-May-00 --------------------- This is purely a bug fixing release. 1. If the pattern /((Z)+|A)*/ was matched agained ZABCDEFG it matched Z instead of ZA. This was just one example of several cases that could provoke this bug, which was introduced by change 9 of version 2.00. The code for breaking infinite loops after an iteration that matches an empty string was't working correctly. 2. The pcretest program was not imitating Perl correctly for the pattern /a*/g when matched against abbab (for example). After matching an empty string, it wasn't forcing anchoring when setting PCRE_NOTEMPTY for the next attempt; this caused it to match further down the string than it should. 3. The code contained an inclusion of sys/types.h. It isn't clear why this was there because it doesn't seem to be needed, and it causes trouble on some systems, as it is not a Standard C header. It has been removed. 4. Made 4 silly changes to the source to avoid stupid compiler warnings that were reported on the Macintosh. The changes were from while ((c = *(++ptr)) != 0 && c != '\n'); to while ((c = *(++ptr)) != 0 && c != '\n') ; Totally extraordinary, but if that's what it takes... 5. PCRE is being used in one environment where neither memmove() nor bcopy() is available. Added HAVE_BCOPY and an autoconf test for it; if neither HAVE_MEMMOVE nor HAVE_BCOPY is set, use a built-in emulation function which assumes the way PCRE uses memmove() (always moving upwards). 6. PCRE is being used in one environment where strchr() is not available. There was only one use in pcre.c, and writing it out to avoid strchr() probably gives faster code anyway. Version 3.2 12-May-00 --------------------- This is purely a bug fixing release. 1. If the pattern /((Z)+|A)*/ was matched agained ZABCDEFG it matched Z instead of ZA. This was just one example of several cases that could provoke this bug, which was introduced by change 9 of version 2.00. The code for breaking infinite loops after an iteration that matches an empty string was't working correctly. 2. The pcretest program was not imitating Perl correctly for the pattern /a*/g when matched against abbab (for example). After matching an empty string, it wasn't forcing anchoring when setting PCRE_NOTEMPTY for the next attempt; this caused it to match further down the string than it should. 3. The code contained an inclusion of sys/types.h. It isn't clear why this was there because it doesn't seem to be needed, and it causes trouble on some systems, as it is not a Standard C header. It has been removed. 4. Made 4 silly changes to the source to avoid stupid compiler warnings that were reported on the Macintosh. The changes were from while ((c = *(++ptr)) != 0 && c != '\n'); to while ((c = *(++ptr)) != 0 && c != '\n') ; Totally extraordinary, but if that's what it takes... 5. PCRE is being used in one environment where neither memmove() nor bcopy() is available. Added HAVE_BCOPY and an autoconf test for it; if neither HAVE_MEMMOVE nor HAVE_BCOPY is set, use a built-in emulation function which assumes the way PCRE uses memmove() (always moving upwards). 6. PCRE is being used in one environment where strchr() is not available. There was only one use in pcre.c, and writing it out to avoid strchr() probably gives faster code anyway. Version 3.1 09-Feb-00 --------------------- The only change in this release is the fixing of some bugs in Makefile.in for the "install" target: (1) It was failing to install pcreposix.h. (2) It was overwriting the pcre.3 man page with the pcreposix.3 man page. Version 3.0 01-Feb-00 --------------------- 1. Add support for the /+ modifier to perltest (to output $` like it does in pcretest). 2. Add support for the /g modifier to perltest. 3. Fix pcretest so that it behaves even more like Perl for /g when the pattern matches null strings. 4. Fix perltest so that it doesn't do unwanted things when fed an empty pattern. Perl treats empty patterns specially - it reuses the most recent pattern, which is not what we want. Replace // by /(?#)/ in order to avoid this effect. 5. The POSIX interface was broken in that it was just handing over the POSIX captured string vector to pcre_exec(), but (since release 2.00) PCRE has required a bigger vector, with some working space on the end. This means that the POSIX wrapper now has to get and free some memory, and copy the results. 6. Added some simple autoconf support, placing the test data and the documentation in separate directories, re-organizing some of the information files, and making it build pcre-config (a GNU standard). Also added libtool support for building PCRE as a shared library, which is now the default. 7. Got rid of the leading zero in the definition of PCRE_MINOR because 08 and 09 are not valid octal constants. Single digits will be used for minor values less than 10. 8. Defined REG_EXTENDED and REG_NOSUB as zero in the POSIX header, so that existing programs that set these in the POSIX interface can use PCRE without modification. 9. Added a new function, pcre_fullinfo() with an extensible interface. It can return all that pcre_info() returns, plus additional data. The pcre_info() function is retained for compatibility, but is considered to be obsolete. 10. Added experimental recursion feature (?R) to handle one common case that Perl 5.6 will be able to do with (?p{...}). 11. Added support for POSIX character classes like [:alpha:], which Perl is adopting. Version 2.08 31-Aug-99 ---------------------- 1. When startoffset was not zero and the pattern began with ".*", PCRE was not trying to match at the startoffset position, but instead was moving forward to the next newline as if a previous match had failed. 2. pcretest was not making use of PCRE_NOTEMPTY when repeating for /g and /G, and could get into a loop if a null string was matched other than at the start of the subject. 3. Added definitions of PCRE_MAJOR and PCRE_MINOR to pcre.h so the version can be distinguished at compile time, and for completeness also added PCRE_DATE. 5. Added Paul Sokolovsky's minor changes to make it easy to compile a Win32 DLL in GnuWin32 environments. Version 2.07 29-Jul-99 ---------------------- 1. The documentation is now supplied in plain text form and HTML as well as in the form of man page sources. 2. C++ compilers don't like assigning (void *) values to other pointer types. In particular this affects malloc(). Although there is no problem in Standard C, I've put in casts to keep C++ compilers happy. 3. Typo on pcretest.c; a cast of (unsigned char *) in the POSIX regexec() call should be (const char *). 4. If NOPOSIX is defined, pcretest.c compiles without POSIX support. This may be useful for non-Unix systems who don't want to bother with the POSIX stuff. However, I haven't made this a standard facility. The documentation doesn't mention it, and the Makefile doesn't support it. 5. The Makefile now contains an "install" target, with editable destinations at the top of the file. The pcretest program is not installed. 6. pgrep -V now gives the PCRE version number and date. 7. Fixed bug: a zero repetition after a literal string (e.g. /abcde{0}/) was causing the entire string to be ignored, instead of just the last character. 8. If a pattern like /"([^\\"]+|\\.)*"/ is applied in the normal way to a non-matching string, it can take a very, very long time, even for strings of quite modest length, because of the nested recursion. PCRE now does better in some of these cases. It does this by remembering the last required literal character in the pattern, and pre-searching the subject to ensure it is present before running the real match. In other words, it applies a heuristic to detect some types of certain failure quickly, and in the above example, if presented with a string that has no trailing " it gives "no match" very quickly. 9. A new runtime option PCRE_NOTEMPTY causes null string matches to be ignored; other alternatives are tried instead. Version 2.06 09-Jun-99 ---------------------- 1. Change pcretest's output for amount of store used to show just the code space, because the remainder (the data block) varies in size between 32-bit and 64-bit systems. 2. Added an extra argument to pcre_exec() to supply an offset in the subject to start matching at. This allows lookbehinds to work when searching for multiple occurrences in a string. 3. Added additional options to pcretest for testing multiple occurrences: /+ outputs the rest of the string that follows a match /g loops for multiple occurrences, using the new startoffset argument /G loops for multiple occurrences by passing an incremented pointer 4. PCRE wasn't doing the "first character" optimization for patterns starting with \b or \B, though it was doing it for other lookbehind assertions. That is, it wasn't noticing that a match for a pattern such as /\bxyz/ has to start with the letter 'x'. On long subject strings, this gives a significant speed-up. Version 2.05 21-Apr-99 ---------------------- 1. Changed the type of magic_number from int to long int so that it works properly on 16-bit systems. 2. Fixed a bug which caused patterns starting with .* not to work correctly when the subject string contained newline characters. PCRE was assuming anchoring for such patterns in all cases, which is not correct because .* will not pass a newline unless PCRE_DOTALL is set. It now assumes anchoring only if DOTALL is set at top level; otherwise it knows that patterns starting with .* must be retried after every newline in the subject. Version 2.04 18-Feb-99 ---------------------- 1. For parenthesized subpatterns with repeats whose minimum was zero, the computation of the store needed to hold the pattern was incorrect (too large). If such patterns were nested a few deep, this could multiply and become a real problem. 2. Added /M option to pcretest to show the memory requirement of a specific pattern. Made -m a synonym of -s (which does this globally) for compatibility. 3. Subpatterns of the form (regex){n,m} (i.e. limited maximum) were being compiled in such a way that the backtracking after subsequent failure was pessimal. Something like (a){0,3} was compiled as (a)?(a)?(a)? instead of ((a)((a)(a)?)?)? with disastrous performance if the maximum was of any size. Version 2.03 02-Feb-99 ---------------------- 1. Fixed typo and small mistake in man page. 2. Added 4th condition (GPL supersedes if conflict) and created separate LICENCE file containing the conditions. 3. Updated pcretest so that patterns such as /abc\/def/ work like they do in Perl, that is the internal \ allows the delimiter to be included in the pattern. Locked out the use of \ as a delimiter. If \ immediately follows the final delimiter, add \ to the end of the pattern (to test the error). 4. Added the convenience functions for extracting substrings after a successful match. Updated pcretest to make it able to test these functions. Version 2.02 14-Jan-99 ---------------------- 1. Initialized the working variables associated with each extraction so that their saving and restoring doesn't refer to uninitialized store. 2. Put dummy code into study.c in order to trick the optimizer of the IBM C compiler for OS/2 into generating correct code. Apparently IBM isn't going to fix the problem. 3. Pcretest: the timing code wasn't using LOOPREPEAT for timing execution calls, and wasn't printing the correct value for compiling calls. Increased the default value of LOOPREPEAT, and the number of significant figures in the times. 4. Changed "/bin/rm" in the Makefile to "-rm" so it works on Windows NT. 5. Renamed "deftables" as "dftables" to get it down to 8 characters, to avoid a building problem on Windows NT with a FAT file system. Version 2.01 21-Oct-98 ---------------------- 1. Changed the API for pcre_compile() to allow for the provision of a pointer to character tables built by pcre_maketables() in the current locale. If NULL is passed, the default tables are used. Version 2.00 24-Sep-98 ---------------------- 1. Since the (>?) facility is in Perl 5.005, don't require PCRE_EXTRA to enable it any more. 2. Allow quantification of (?>) groups, and make it work correctly. 3. The first character computation wasn't working for (?>) groups. 4. Correct the implementation of \Z (it is permitted to match on the \n at the end of the subject) and add 5.005's \z, which really does match only at the very end of the subject. 5. Remove the \X "cut" facility; Perl doesn't have it, and (?> is neater. 6. Remove the ability to specify CASELESS, MULTILINE, DOTALL, and DOLLAR_END_ONLY at runtime, to make it possible to implement the Perl 5.005 localized options. All options to pcre_study() were also removed. 7. Add other new features from 5.005: $(?<= positive lookbehind $(?a*))*/ (a PCRE_EXTRA facility). Version 1.00 18-Nov-97 ---------------------- 1. Added compile-time macros to support systems such as SunOS4 which don't have memmove() or strerror() but have other things that can be used instead. 2. Arranged that "make clean" removes the executables. Version 0.99 27-Oct-97 ---------------------- 1. Fixed bug in code for optimizing classes with only one character. It was initializing a 32-byte map regardless, which could cause it to run off the end of the memory it had got. 2. Added, conditional on PCRE_EXTRA, the proposed (?>REGEX) construction. Version 0.98 22-Oct-97 ---------------------- 1. Fixed bug in code for handling temporary memory usage when there are more back references than supplied space in the ovector. This could cause segfaults. Version 0.97 21-Oct-97 ---------------------- 1. Added the \X "cut" facility, conditional on PCRE_EXTRA. 2. Optimized negated single characters not to use a bit map. 3. Brought error texts together as macro definitions; clarified some of them; fixed one that was wrong - it said "range out of order" when it meant "invalid escape sequence". 4. Changed some char * arguments to const char *. 5. Added PCRE_NOTBOL and PCRE_NOTEOL (from POSIX). 6. Added the POSIX-style API wrapper in pcreposix.a and testing facilities in pcretest. Version 0.96 16-Oct-97 ---------------------- 1. Added a simple "pgrep" utility to the distribution. 2. Fixed an incompatibility with Perl: "{" is now treated as a normal character unless it appears in one of the precise forms "{ddd}", "{ddd,}", or "{ddd,ddd}" where "ddd" means "one or more decimal digits". 3. Fixed serious bug. If a pattern had a back reference, but the call to pcre_exec() didn't supply a large enough ovector to record the related identifying subpattern, the match always failed. PCRE now remembers the number of the largest back reference, and gets some temporary memory in which to save the offsets during matching if necessary, in order to ensure that backreferences always work. 4. Increased the compatibility with Perl in a number of ways: (a) . no longer matches \n by default; an option PCRE_DOTALL is provided to request this handling. The option can be set at compile or exec time. (b) $ matches before a terminating newline by default; an option PCRE_DOLLAR_ENDONLY is provided to override this (but not in multiline mode). The option can be set at compile or exec time. (c) The handling of \ followed by a digit other than 0 is now supposed to be the same as Perl's. If the decimal number it represents is less than 10 or there aren't that many previous left capturing parentheses, an octal escape is read. Inside a character class, it's always an octal escape, even if it is a single digit. (d) An escaped but undefined alphabetic character is taken as a literal, unless PCRE_EXTRA is set. Currently this just reserves the remaining escapes. (e) {0} is now permitted. (The previous item is removed from the compiled pattern). 5. Changed all the names of code files so that the basic parts are no longer than 10 characters, and abolished the teeny "globals.c" file. 6. Changed the handling of character classes; they are now done with a 32-byte bit map always. 7. Added the -d and /D options to pcretest to make it possible to look at the internals of compilation without having to recompile pcre. Version 0.95 23-Sep-97 ---------------------- 1. Fixed bug in pre-pass concerning escaped "normal" characters such as \x5c or \x20 at the start of a run of normal characters. These were being treated as real characters, instead of the source characters being re-checked. Version 0.94 18-Sep-97 ---------------------- 1. The functions are now thread-safe, with the caveat that the global variables containing pointers to malloc() and free() or alternative functions are the same for all threads. 2. Get pcre_study() to generate a bitmap of initial characters for non- anchored patterns when this is possible, and use it if passed to pcre_exec(). Version 0.93 15-Sep-97 ---------------------- 1. /(b)|(:+)/ was computing an incorrect first character. 2. Add pcre_study() to the API and the passing of pcre_extra to pcre_exec(), but not actually doing anything yet. 3. Treat "-" characters in classes that cannot be part of ranges as literals, as Perl does (e.g. [-az] or [az-]). 4. Set the anchored flag if a branch starts with .* or .*? because that tests all possible positions. 5. Split up into different modules to avoid including unneeded functions in a compiled binary. However, compile and exec are still in one module. The "study" function is split off. 6. The character tables are now in a separate module whose source is generated by an auxiliary program - but can then be edited by hand if required. There are now no calls to isalnum(), isspace(), isdigit(), isxdigit(), tolower() or toupper() in the code. 7. Turn the malloc/free funtions variables into pcre_malloc and pcre_free and make them global. Abolish the function for setting them, as the caller can now set them directly. Version 0.92 11-Sep-97 ---------------------- 1. A repeat with a fixed maximum and a minimum of 1 for an ordinary character (e.g. /a{1,3}/) was broken (I mis-optimized it). 2. Caseless matching was not working in character classes if the characters in the pattern were in upper case. 3. Make ranges like [W-c] work in the same way as Perl for caseless matching. 4. Make PCRE_ANCHORED public and accept as a compile option. 5. Add an options word to pcre_exec() and accept PCRE_ANCHORED and PCRE_CASELESS at run time. Add escapes \A and \I to pcretest to cause it to pass them. 6. Give an error if bad option bits passed at compile or run time. 7. Add PCRE_MULTILINE at compile and exec time, and (?m) as well. Add \M to pcretest to cause it to pass that flag. 8. Add pcre_info(), to get the number of identifying subpatterns, the stored options, and the first character, if set. 9. Recognize C+ or C{n,m} where n >= 1 as providing a fixed starting character. Version 0.91 10-Sep-97 ---------------------- 1. PCRE was failing to diagnose unlimited repeats of subpatterns that could match the empty string as in /(a*)*/. It was looping and ultimately crashing. 2. PCRE was looping on encountering an indefinitely repeated back reference to a subpattern that had matched an empty string, e.g. /(a|)\1*/. It now does what Perl does - treats the match as successful. **** tomcat-connectors-1.2.41-src/native/iis/pcre/ucptypetable.c0000644000000000000020000000630310517277132022172 0ustar rootbin/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. See the file Tech.Notes for some information on the internals. Written by: Philip Hazel Copyright (c) 1997-2004 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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 module contains a table for translating Unicode property names into code values for the ucp_findchar function. It is in a separate module so that it can be included both in the main pcre library, and into pcretest (for printing out internals). */ typedef struct { const char *name; int value; } ucp_type_table; static ucp_type_table utt[] = { { "C", 128 + ucp_C }, { "Cc", ucp_Cc }, { "Cf", ucp_Cf }, { "Cn", ucp_Cn }, { "Co", ucp_Co }, { "Cs", ucp_Cs }, { "L", 128 + ucp_L }, { "Ll", ucp_Ll }, { "Lm", ucp_Lm }, { "Lo", ucp_Lo }, { "Lt", ucp_Lt }, { "Lu", ucp_Lu }, { "M", 128 + ucp_M }, { "Mc", ucp_Mc }, { "Me", ucp_Me }, { "Mn", ucp_Mn }, { "N", 128 + ucp_N }, { "Nd", ucp_Nd }, { "Nl", ucp_Nl }, { "No", ucp_No }, { "P", 128 + ucp_P }, { "Pc", ucp_Pc }, { "Pd", ucp_Pd }, { "Pe", ucp_Pe }, { "Pf", ucp_Pf }, { "Pi", ucp_Pi }, { "Po", ucp_Po }, { "Ps", ucp_Ps }, { "S", 128 + ucp_S }, { "Sc", ucp_Sc }, { "Sk", ucp_Sk }, { "Sm", ucp_Sm }, { "So", ucp_So }, { "Z", 128 + ucp_Z }, { "Zl", ucp_Zl }, { "Zp", ucp_Zp }, { "Zs", ucp_Zs } }; /* End of ucptypetable.c */ tomcat-connectors-1.2.41-src/native/iis/pcre/pcre.c0000644000000000000020000104771310517277132020435 0ustar rootbin/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. See the file Tech.Notes for some information on the internals. Written by: Philip Hazel Copyright (c) 1997-2004 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. ----------------------------------------------------------------------------- */ /* Define DEBUG to get debugging output on stdout. */ /* #define DEBUG */ /* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef inline, and there are *still* stupid compilers about that don't like indented pre-processor statements. I suppose it's only been 10 years... */ #ifdef DEBUG #define DPRINTF(p) printf p #else #define DPRINTF(p) /*nothing*/ #endif /* Include the internals header, which itself includes "config.h", the Standard C headers, and the external pcre header. */ #include "internal.h" /* If Unicode Property support is wanted, include a private copy of the function that does it, and the table that translates names to numbers. */ #ifdef SUPPORT_UCP #include "ucp.c" #include "ucptypetable.c" #endif /* Maximum number of items on the nested bracket stacks at compile time. This applies to the nesting of all kinds of parentheses. It does not limit un-nested, non-capturing parentheses. This number can be made bigger if necessary - it is used to dimension one int and one unsigned char vector at compile time. */ #define BRASTACK_SIZE 200 /* Maximum number of ints of offset to save on the stack for recursive calls. If the offset vector is bigger, malloc is used. This should be a multiple of 3, because the offset vector is always a multiple of 3 long. */ #define REC_STACK_SAVE_MAX 30 /* The maximum remaining length of subject we are prepared to search for a req_byte match. */ #define REQ_BYTE_MAX 1000 /* Table of sizes for the fixed-length opcodes. It's defined in a macro so that the definition is next to the definition of the opcodes in internal.h. */ static const uschar OP_lengths[] = { OP_LENGTHS }; /* Min and max values for the common repeats; for the maxima, 0 => infinity */ static const char rep_min[] = { 0, 0, 1, 1, 0, 0 }; static const char rep_max[] = { 0, 0, 0, 0, 1, 1 }; /* Table for handling escaped characters in the range '0'-'z'. Positive returns are simple data values; negative values are for special things like \d and so on. Zero means further processing is needed (for things like \x), or the escape is invalid. */ #if !EBCDIC /* This is the "normal" table for ASCII systems */ static const short int escapes[] = { 0, 0, 0, 0, 0, 0, 0, 0, /* 0 - 7 */ 0, 0, ':', ';', '<', '=', '>', '?', /* 8 - ? */ '@', -ESC_A, -ESC_B, -ESC_C, -ESC_D, -ESC_E, 0, -ESC_G, /* @ - G */ 0, 0, 0, 0, 0, 0, 0, 0, /* H - O */ -ESC_P, -ESC_Q, 0, -ESC_S, 0, 0, 0, -ESC_W, /* P - W */ -ESC_X, 0, -ESC_Z, '[', '\\', ']', '^', '_', /* X - _ */ '`', 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0, /* ` - g */ 0, 0, 0, 0, 0, 0, ESC_n, 0, /* h - o */ -ESC_p, 0, ESC_r, -ESC_s, ESC_tee, 0, 0, -ESC_w, /* p - w */ 0, 0, -ESC_z /* x - z */ }; #else /* This is the "abnormal" table for EBCDIC systems */ static const short int escapes[] = { /* 48 */ 0, 0, 0, '.', '<', '(', '+', '|', /* 50 */ '&', 0, 0, 0, 0, 0, 0, 0, /* 58 */ 0, 0, '!', '$', '*', ')', ';', '~', /* 60 */ '-', '/', 0, 0, 0, 0, 0, 0, /* 68 */ 0, 0, '|', ',', '%', '_', '>', '?', /* 70 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 78 */ 0, '`', ':', '#', '@', '\'', '=', '"', /* 80 */ 0, 7, -ESC_b, 0, -ESC_d, ESC_e, ESC_f, 0, /* 88 */ 0, 0, 0, '{', 0, 0, 0, 0, /* 90 */ 0, 0, 0, 'l', 0, ESC_n, 0, -ESC_p, /* 98 */ 0, ESC_r, 0, '}', 0, 0, 0, 0, /* A0 */ 0, '~', -ESC_s, ESC_tee, 0, 0, -ESC_w, 0, /* A8 */ 0,-ESC_z, 0, 0, 0, '[', 0, 0, /* B0 */ 0, 0, 0, 0, 0, 0, 0, 0, /* B8 */ 0, 0, 0, 0, 0, ']', '=', '-', /* C0 */ '{',-ESC_A, -ESC_B, -ESC_C, -ESC_D,-ESC_E, 0, -ESC_G, /* C8 */ 0, 0, 0, 0, 0, 0, 0, 0, /* D0 */ '}', 0, 0, 0, 0, 0, 0, -ESC_P, /* D8 */-ESC_Q, 0, 0, 0, 0, 0, 0, 0, /* E0 */ '\\', 0, -ESC_S, 0, 0, 0, -ESC_W, -ESC_X, /* E8 */ 0,-ESC_Z, 0, 0, 0, 0, 0, 0, /* F0 */ 0, 0, 0, 0, 0, 0, 0, 0, /* F8 */ 0, 0, 0, 0, 0, 0, 0, 0 }; #endif /* Tables of names of POSIX character classes and their lengths. The list is terminated by a zero length entry. The first three must be alpha, upper, lower, as this is assumed for handling case independence. */ static const char *const posix_names[] = { "alpha", "lower", "upper", "alnum", "ascii", "blank", "cntrl", "digit", "graph", "print", "punct", "space", "word", "xdigit" }; static const uschar posix_name_lengths[] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 }; /* Table of class bit maps for each POSIX class; up to three may be combined to form the class. The table for [:blank:] is dynamically modified to remove the vertical space characters. */ static const int posix_class_maps[] = { cbit_lower, cbit_upper, -1, /* alpha */ cbit_lower, -1, -1, /* lower */ cbit_upper, -1, -1, /* upper */ cbit_digit, cbit_lower, cbit_upper, /* alnum */ cbit_print, cbit_cntrl, -1, /* ascii */ cbit_space, -1, -1, /* blank - a GNU extension */ cbit_cntrl, -1, -1, /* cntrl */ cbit_digit, -1, -1, /* digit */ cbit_graph, -1, -1, /* graph */ cbit_print, -1, -1, /* print */ cbit_punct, -1, -1, /* punct */ cbit_space, -1, -1, /* space */ cbit_word, -1, -1, /* word - a Perl extension */ cbit_xdigit,-1, -1 /* xdigit */ }; /* Table to identify digits and hex digits. This is used when compiling patterns. Note that the tables in chartables are dependent on the locale, and may mark arbitrary characters as digits - but the PCRE compiling code expects to handle only 0-9, a-z, and A-Z as digits when compiling. That is why we have a private table here. It costs 256 bytes, but it is a lot faster than doing character value tests (at least in some simple cases I timed), and in some applications one wants PCRE to compile efficiently as well as match efficiently. For convenience, we use the same bit definitions as in chartables: 0x04 decimal digit 0x08 hexadecimal digit Then we can use ctype_digit and ctype_xdigit in the code. */ #if !EBCDIC /* This is the "normal" case, for ASCII systems */ static const unsigned char digitab[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - ' */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ( - / */ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 */ 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00, /* 8 - ? */ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* @ - G */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H - O */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* P - W */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* X - _ */ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* ` - g */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h - o */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* p - w */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* x -127 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ #else /* This is the "abnormal" case, for EBCDIC systems */ static const unsigned char digitab[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 10 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 32- 39 20 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 30 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 40 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 72- | */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 50 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 88- ¬ */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 60 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 104- ? */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 70 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* 128- g 80 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144- p 90 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160- x A0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 B0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, /* { - G C0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* } - P D0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* \ - X E0 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */ 0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c, /* 0 - 7 F0 */ 0x0c,0x0c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */ static const unsigned char ebcdic_chartab[] = { /* chartable partial dup */ 0x80,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 0- 7 */ 0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 16- 23 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00, /* 32- 39 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 40- 47 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 48- 55 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 56- 63 */ 0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - 71 */ 0x00,0x00,0x00,0x80,0x00,0x80,0x80,0x80, /* 72- | */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* & - 87 */ 0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00, /* 88- ¬ */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* - -103 */ 0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x80, /* 104- ? */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 112-119 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 120- " */ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* 128- g */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* h -143 */ 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* 144- p */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* q -159 */ 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* 160- x */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* y -175 */ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* ^ -183 */ 0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ 0x80,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* { - G */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* H -207 */ 0x00,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* } - P */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Q -223 */ 0x00,0x00,0x12,0x12,0x12,0x12,0x12,0x12, /* \ - X */ 0x12,0x12,0x00,0x00,0x00,0x00,0x00,0x00, /* Y -239 */ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x00};/* 8 -255 */ #endif /* Definition to allow mutual recursion */ static BOOL compile_regex(int, int, int *, uschar **, const uschar **, const char **, BOOL, int, int *, int *, branch_chain *, compile_data *); /* Structure for building a chain of data that actually lives on the stack, for holding the values of the subject pointer at the start of each subpattern, so as to detect when an empty string has been matched by a subpattern - to break infinite loops. When NO_RECURSE is set, these blocks are on the heap, not on the stack. */ typedef struct eptrblock { struct eptrblock *epb_prev; const uschar *epb_saved_eptr; } eptrblock; /* Flag bits for the match() function */ #define match_condassert 0x01 /* Called to check a condition assertion */ #define match_isgroup 0x02 /* Set if start of bracketed group */ /* Non-error returns from the match() function. Error returns are externally defined PCRE_ERROR_xxx codes, which are all negative. */ #define MATCH_MATCH 1 #define MATCH_NOMATCH 0 /************************************************* * Global variables * *************************************************/ /* PCRE is thread-clean and doesn't use any global variables in the normal sense. However, it calls memory allocation and free functions via the four indirections below, and it can optionally do callouts. These values can be changed by the caller, but are shared between all threads. However, when compiling for Virtual Pascal, things are done differently (see pcre.in). */ #ifndef VPCOMPAT #ifdef __cplusplus extern "C" void *(*pcre_malloc)(size_t) = malloc; extern "C" void (*pcre_free)(void *) = free; extern "C" void *(*pcre_stack_malloc)(size_t) = malloc; extern "C" void (*pcre_stack_free)(void *) = free; extern "C" int (*pcre_callout)(pcre_callout_block *) = NULL; #else void *(*pcre_malloc)(size_t) = malloc; void (*pcre_free)(void *) = free; void *(*pcre_stack_malloc)(size_t) = malloc; void (*pcre_stack_free)(void *) = free; int (*pcre_callout)(pcre_callout_block *) = NULL; #endif #endif /************************************************* * Macros and tables for character handling * *************************************************/ /* When UTF-8 encoding is being used, a character is no longer just a single byte. The macros for character handling generate simple sequences when used in byte-mode, and more complicated ones for UTF-8 characters. */ #ifndef SUPPORT_UTF8 #define GETCHAR(c, eptr) c = *eptr; #define GETCHARINC(c, eptr) c = *eptr++; #define GETCHARINCTEST(c, eptr) c = *eptr++; #define GETCHARLEN(c, eptr, len) c = *eptr; #define BACKCHAR(eptr) #else /* SUPPORT_UTF8 */ /* Get the next UTF-8 character, not advancing the pointer. This is called when we know we are in UTF-8 mode. */ #define GETCHAR(c, eptr) \ c = *eptr; \ if ((c & 0xc0) == 0xc0) \ { \ int gcii; \ int gcaa = utf8_table4[c & 0x3f]; /* Number of additional bytes */ \ int gcss = 6*gcaa; \ c = (c & utf8_table3[gcaa]) << gcss; \ for (gcii = 1; gcii <= gcaa; gcii++) \ { \ gcss -= 6; \ c |= (eptr[gcii] & 0x3f) << gcss; \ } \ } /* Get the next UTF-8 character, advancing the pointer. This is called when we know we are in UTF-8 mode. */ #define GETCHARINC(c, eptr) \ c = *eptr++; \ if ((c & 0xc0) == 0xc0) \ { \ int gcaa = utf8_table4[c & 0x3f]; /* Number of additional bytes */ \ int gcss = 6*gcaa; \ c = (c & utf8_table3[gcaa]) << gcss; \ while (gcaa-- > 0) \ { \ gcss -= 6; \ c |= (*eptr++ & 0x3f) << gcss; \ } \ } /* Get the next character, testing for UTF-8 mode, and advancing the pointer */ #define GETCHARINCTEST(c, eptr) \ c = *eptr++; \ if (md->utf8 && (c & 0xc0) == 0xc0) \ { \ int gcaa = utf8_table4[c & 0x3f]; /* Number of additional bytes */ \ int gcss = 6*gcaa; \ c = (c & utf8_table3[gcaa]) << gcss; \ while (gcaa-- > 0) \ { \ gcss -= 6; \ c |= (*eptr++ & 0x3f) << gcss; \ } \ } /* Get the next UTF-8 character, not advancing the pointer, incrementing length if there are extra bytes. This is called when we know we are in UTF-8 mode. */ #define GETCHARLEN(c, eptr, len) \ c = *eptr; \ if ((c & 0xc0) == 0xc0) \ { \ int gcii; \ int gcaa = utf8_table4[c & 0x3f]; /* Number of additional bytes */ \ int gcss = 6*gcaa; \ c = (c & utf8_table3[gcaa]) << gcss; \ for (gcii = 1; gcii <= gcaa; gcii++) \ { \ gcss -= 6; \ c |= (eptr[gcii] & 0x3f) << gcss; \ } \ len += gcaa; \ } /* If the pointer is not at the start of a character, move it back until it is. Called only in UTF-8 mode. */ #define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr--; #endif /************************************************* * Default character tables * *************************************************/ /* A default set of character tables is included in the PCRE binary. Its source is built by the maketables auxiliary program, which uses the default C ctypes functions, and put in the file chartables.c. These tables are used by PCRE whenever the caller of pcre_compile() does not provide an alternate set of tables. */ #include "chartables.c" #ifdef SUPPORT_UTF8 /************************************************* * Tables for UTF-8 support * *************************************************/ /* These are the breakpoints for different numbers of bytes in a UTF-8 character. */ static const int utf8_table1[] = { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff}; /* These are the indicator bits and the mask for the data bits to set in the first byte of a character, indexed by the number of additional bytes. */ static const int utf8_table2[] = { 0, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc}; static const int utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01}; /* Table of the number of extra characters, indexed by the first character masked with 0x3f. The highest number for a valid UTF-8 character is in fact 0x3d. */ static const uschar utf8_table4[] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 }; /************************************************* * Convert character value to UTF-8 * *************************************************/ /* This function takes an integer value in the range 0 - 0x7fffffff and encodes it as a UTF-8 character in 0 to 6 bytes. Arguments: cvalue the character value buffer pointer to buffer for result - at least 6 bytes long Returns: number of characters placed in the buffer */ static int ord2utf8(int cvalue, uschar *buffer) { register int i, j; for (i = 0; i < sizeof(utf8_table1)/sizeof(int); i++) if (cvalue <= utf8_table1[i]) break; buffer += i; for (j = i; j > 0; j--) { *buffer-- = 0x80 | (cvalue & 0x3f); cvalue >>= 6; } *buffer = utf8_table2[i] | cvalue; return i + 1; } #endif /************************************************* * Print compiled regex * *************************************************/ /* The code for doing this is held in a separate file that is also included in pcretest.c. It defines a function called print_internals(). */ #ifdef DEBUG #include "printint.c" #endif /************************************************* * Return version string * *************************************************/ #define STRING(a) # a #define XSTRING(s) STRING(s) EXPORT const char * pcre_version(void) { return XSTRING(PCRE_MAJOR) "." XSTRING(PCRE_MINOR) " " XSTRING(PCRE_DATE); } /************************************************* * Flip bytes in an integer * *************************************************/ /* This function is called when the magic number in a regex doesn't match in order to flip its bytes to see if we are dealing with a pattern that was compiled on a host of different endianness. If so, this function is used to flip other byte values. Arguments: value the number to flip n the number of bytes to flip (assumed to be 2 or 4) Returns: the flipped value */ static pcre_uint16 byteflip2(pcre_uint16 value) { return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8); } static pcre_uint32 byteflip4(pcre_uint32 value) { return ((value & 0x000000ff) << 24) | ((value & 0x0000ff00) << 8) | ((value & 0x00ff0000) >> 8) | ((value & 0xff000000) >> 24); } /************************************************* * Test for a byte-flipped compiled regex * *************************************************/ /* This function is called from pce_exec() and also from pcre_fullinfo(). Its job is to test whether the regex is byte-flipped - that is, it was compiled on a system of opposite endianness. The function is called only when the native MAGIC_NUMBER test fails. If the regex is indeed flipped, we flip all the relevant values into a different data block, and return it. Arguments: re points to the regex study points to study data, or NULL internal_re points to a new regex block internal_study points to a new study block Returns: the new block if is is indeed a byte-flipped regex NULL if it is not */ static real_pcre * try_flipped(const real_pcre *re, real_pcre *internal_re, const pcre_study_data *study, pcre_study_data *internal_study) { if (byteflip4(re->magic_number) != MAGIC_NUMBER) return NULL; *internal_re = *re; /* To copy other fields */ internal_re->size = byteflip4(re->size); internal_re->options = byteflip4(re->options); internal_re->top_bracket = byteflip2(re->top_bracket); internal_re->top_backref = byteflip2(re->top_backref); internal_re->first_byte = byteflip2(re->first_byte); internal_re->req_byte = byteflip2(re->req_byte); internal_re->name_table_offset = byteflip2(re->name_table_offset); internal_re->name_entry_size = byteflip2(re->name_entry_size); internal_re->name_count = byteflip2(re->name_count); if (study != NULL) { *internal_study = *study; /* To copy other fields */ internal_study->size = byteflip4(study->size); internal_study->options = byteflip4(study->options); } return internal_re; } /************************************************* * (Obsolete) Return info about compiled pattern * *************************************************/ /* This is the original "info" function. It picks potentially useful data out of the private structure, but its interface was too rigid. It remains for backwards compatibility. The public options are passed back in an int - though the re->options field has been expanded to a long int, all the public options at the low end of it, and so even on 16-bit systems this will still be OK. Therefore, I haven't changed the API for pcre_info(). Arguments: argument_re points to compiled code optptr where to pass back the options first_byte where to pass back the first character, or -1 if multiline and all branches start ^, or -2 otherwise Returns: number of capturing subpatterns or negative values on error */ EXPORT int pcre_info(const pcre *argument_re, int *optptr, int *first_byte) { real_pcre internal_re; const real_pcre *re = (const real_pcre *)argument_re; if (re == NULL) return PCRE_ERROR_NULL; if (re->magic_number != MAGIC_NUMBER) { re = try_flipped(re, &internal_re, NULL, NULL); if (re == NULL) return PCRE_ERROR_BADMAGIC; } if (optptr != NULL) *optptr = (int)(re->options & PUBLIC_OPTIONS); if (first_byte != NULL) *first_byte = ((re->options & PCRE_FIRSTSET) != 0)? re->first_byte : ((re->options & PCRE_STARTLINE) != 0)? -1 : -2; return re->top_bracket; } /************************************************* * Return info about compiled pattern * *************************************************/ /* This is a newer "info" function which has an extensible interface so that additional items can be added compatibly. Arguments: argument_re points to compiled code extra_data points extra data, or NULL what what information is required where where to put the information Returns: 0 if data returned, negative on error */ EXPORT int pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data, int what, void *where) { real_pcre internal_re; pcre_study_data internal_study; const real_pcre *re = (const real_pcre *)argument_re; const pcre_study_data *study = NULL; if (re == NULL || where == NULL) return PCRE_ERROR_NULL; if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0) study = (const pcre_study_data *)extra_data->study_data; if (re->magic_number != MAGIC_NUMBER) { re = try_flipped(re, &internal_re, study, &internal_study); if (re == NULL) return PCRE_ERROR_BADMAGIC; if (study != NULL) study = &internal_study; } switch (what) { case PCRE_INFO_OPTIONS: *((unsigned long int *)where) = re->options & PUBLIC_OPTIONS; break; case PCRE_INFO_SIZE: *((size_t *)where) = re->size; break; case PCRE_INFO_STUDYSIZE: *((size_t *)where) = (study == NULL)? 0 : study->size; break; case PCRE_INFO_CAPTURECOUNT: *((int *)where) = re->top_bracket; break; case PCRE_INFO_BACKREFMAX: *((int *)where) = re->top_backref; break; case PCRE_INFO_FIRSTBYTE: *((int *)where) = ((re->options & PCRE_FIRSTSET) != 0)? re->first_byte : ((re->options & PCRE_STARTLINE) != 0)? -1 : -2; break; /* Make sure we pass back the pointer to the bit vector in the external block, not the internal copy (with flipped integer fields). */ case PCRE_INFO_FIRSTTABLE: *((const uschar **)where) = (study != NULL && (study->options & PCRE_STUDY_MAPPED) != 0)? ((const pcre_study_data *)extra_data->study_data)->start_bits : NULL; break; case PCRE_INFO_LASTLITERAL: *((int *)where) = ((re->options & PCRE_REQCHSET) != 0)? re->req_byte : -1; break; case PCRE_INFO_NAMEENTRYSIZE: *((int *)where) = re->name_entry_size; break; case PCRE_INFO_NAMECOUNT: *((int *)where) = re->name_count; break; case PCRE_INFO_NAMETABLE: *((const uschar **)where) = (const uschar *)re + re->name_table_offset; break; case PCRE_INFO_DEFAULT_TABLES: *((const uschar **)where) = (const uschar *)pcre_default_tables; break; default: return PCRE_ERROR_BADOPTION; } return 0; } /************************************************* * Return info about what features are configured * *************************************************/ /* This is function which has an extensible interface so that additional items can be added compatibly. Arguments: what what information is required where where to put the information Returns: 0 if data returned, negative on error */ EXPORT int pcre_config(int what, void *where) { switch (what) { case PCRE_CONFIG_UTF8: #ifdef SUPPORT_UTF8 *((int *)where) = 1; #else *((int *)where) = 0; #endif break; case PCRE_CONFIG_UNICODE_PROPERTIES: #ifdef SUPPORT_UCP *((int *)where) = 1; #else *((int *)where) = 0; #endif break; case PCRE_CONFIG_NEWLINE: *((int *)where) = NEWLINE; break; case PCRE_CONFIG_LINK_SIZE: *((int *)where) = LINK_SIZE; break; case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD: *((int *)where) = POSIX_MALLOC_THRESHOLD; break; case PCRE_CONFIG_MATCH_LIMIT: *((unsigned int *)where) = MATCH_LIMIT; break; case PCRE_CONFIG_STACKRECURSE: #ifdef NO_RECURSE *((int *)where) = 0; #else *((int *)where) = 1; #endif break; default: return PCRE_ERROR_BADOPTION; } return 0; } #ifdef DEBUG /************************************************* * Debugging function to print chars * *************************************************/ /* Print a sequence of chars in printable format, stopping at the end of the subject if the requested. Arguments: p points to characters length number to print is_subject TRUE if printing from within md->start_subject md pointer to matching data block, if is_subject is TRUE Returns: nothing */ static void pchars(const uschar *p, int length, BOOL is_subject, match_data *md) { int c; if (is_subject && length > md->end_subject - p) length = md->end_subject - p; while (length-- > 0) if (isprint(c = *(p++))) printf("%c", c); else printf("\\x%02x", c); } #endif /************************************************* * Handle escapes * *************************************************/ /* This function is called when a \ has been encountered. It either returns a positive value for a simple escape such as \n, or a negative value which encodes one of the more complicated things such as \d. When UTF-8 is enabled, a positive value greater than 255 may be returned. On entry, ptr is pointing at the \. On exit, it is on the final character of the escape sequence. Arguments: ptrptr points to the pattern position pointer errorptr points to the pointer to the error message bracount number of previous extracting brackets options the options bits isclass TRUE if inside a character class Returns: zero or positive => a data character negative => a special escape sequence on error, errorptr is set */ static int check_escape(const uschar **ptrptr, const char **errorptr, int bracount, int options, BOOL isclass) { const uschar *ptr = *ptrptr; int c, i; /* If backslash is at the end of the pattern, it's an error. */ c = *(++ptr); if (c == 0) *errorptr = ERR1; /* Non-alphamerics are literals. For digits or letters, do an initial lookup in a table. A non-zero result is something that can be returned immediately. Otherwise further processing may be required. */ #if !EBCDIC /* ASCII coding */ else if (c < '0' || c > 'z') {} /* Not alphameric */ else if ((i = escapes[c - '0']) != 0) c = i; #else /* EBCDIC coding */ else if (c < 'a' || (ebcdic_chartab[c] & 0x0E) == 0) {} /* Not alphameric */ else if ((i = escapes[c - 0x48]) != 0) c = i; #endif /* Escapes that need further processing, or are illegal. */ else { const uschar *oldptr; switch (c) { /* A number of Perl escapes are not handled by PCRE. We give an explicit error. */ case 'l': case 'L': case 'N': case 'u': case 'U': *errorptr = ERR37; break; /* The handling of escape sequences consisting of a string of digits starting with one that is not zero is not straightforward. By experiment, the way Perl works seems to be as follows: Outside a character class, the digits are read as a decimal number. If the number is less than 10, or if there are that many previous extracting left brackets, then it is a back reference. Otherwise, up to three octal digits are read to form an escaped byte. Thus \123 is likely to be octal 123 (cf \0123, which is octal 012 followed by the literal 3). If the octal value is greater than 377, the least significant 8 bits are taken. Inside a character class, \ followed by a digit is always an octal number. */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (!isclass) { oldptr = ptr; c -= '0'; while ((digitab[ptr[1]] & ctype_digit) != 0) c = c * 10 + *(++ptr) - '0'; if (c < 10 || c <= bracount) { c = -(ESC_REF + c); break; } ptr = oldptr; /* Put the pointer back and fall through */ } /* Handle an octal number following \. If the first digit is 8 or 9, Perl generates a binary zero byte and treats the digit as a following literal. Thus we have to pull back the pointer by one. */ if ((c = *ptr) >= '8') { ptr--; c = 0; break; } /* \0 always starts an octal number, but we may drop through to here with a larger first octal digit. */ case '0': c -= '0'; while(i++ < 2 && ptr[1] >= '0' && ptr[1] <= '7') c = c * 8 + *(++ptr) - '0'; c &= 255; /* Take least significant 8 bits */ break; /* \x is complicated when UTF-8 is enabled. \x{ddd} is a character number which can be greater than 0xff, but only if the ddd are hex digits. */ case 'x': #ifdef SUPPORT_UTF8 if (ptr[1] == '{' && (options & PCRE_UTF8) != 0) { const uschar *pt = ptr + 2; register int count = 0; c = 0; while ((digitab[*pt] & ctype_xdigit) != 0) { int cc = *pt++; count++; #if !EBCDIC /* ASCII coding */ if (cc >= 'a') cc -= 32; /* Convert to upper case */ c = c * 16 + cc - ((cc < 'A')? '0' : ('A' - 10)); #else /* EBCDIC coding */ if (cc >= 'a' && cc <= 'z') cc += 64; /* Convert to upper case */ c = c * 16 + cc - ((cc >= '0')? '0' : ('A' - 10)); #endif } if (*pt == '}') { if (c < 0 || count > 8) *errorptr = ERR34; ptr = pt; break; } /* If the sequence of hex digits does not end with '}', then we don't recognize this construct; fall through to the normal \x handling. */ } #endif /* Read just a single hex char */ c = 0; while (i++ < 2 && (digitab[ptr[1]] & ctype_xdigit) != 0) { int cc; /* Some compilers don't like ++ */ cc = *(++ptr); /* in initializers */ #if !EBCDIC /* ASCII coding */ if (cc >= 'a') cc -= 32; /* Convert to upper case */ c = c * 16 + cc - ((cc < 'A')? '0' : ('A' - 10)); #else /* EBCDIC coding */ if (cc <= 'z') cc += 64; /* Convert to upper case */ c = c * 16 + cc - ((cc >= '0')? '0' : ('A' - 10)); #endif } break; /* Other special escapes not starting with a digit are straightforward */ case 'c': c = *(++ptr); if (c == 0) { *errorptr = ERR2; return 0; } /* A letter is upper-cased; then the 0x40 bit is flipped. This coding is ASCII-specific, but then the whole concept of \cx is ASCII-specific. (However, an EBCDIC equivalent has now been added.) */ #if !EBCDIC /* ASCII coding */ if (c >= 'a' && c <= 'z') c -= 32; c ^= 0x40; #else /* EBCDIC coding */ if (c >= 'a' && c <= 'z') c += 64; c ^= 0xC0; #endif break; /* PCRE_EXTRA enables extensions to Perl in the matter of escapes. Any other alphameric following \ is an error if PCRE_EXTRA was set; otherwise, for Perl compatibility, it is a literal. This code looks a bit odd, but there used to be some cases other than the default, and there may be again in future, so I haven't "optimized" it. */ default: if ((options & PCRE_EXTRA) != 0) switch(c) { default: *errorptr = ERR3; break; } break; } } *ptrptr = ptr; return c; } #ifdef SUPPORT_UCP /************************************************* * Handle \P and \p * *************************************************/ /* This function is called after \P or \p has been encountered, provided that PCRE is compiled with support for Unicode properties. On entry, ptrptr is pointing at the P or p. On exit, it is pointing at the final character of the escape sequence. Argument: ptrptr points to the pattern position pointer negptr points to a boolean that is set TRUE for negation else FALSE errorptr points to the pointer to the error message Returns: value from ucp_type_table, or -1 for an invalid type */ static int get_ucp(const uschar **ptrptr, BOOL *negptr, const char **errorptr) { int c, i, bot, top; const uschar *ptr = *ptrptr; char name[4]; c = *(++ptr); if (c == 0) goto ERROR_RETURN; *negptr = FALSE; /* \P or \p can be followed by a one- or two-character name in {}, optionally preceded by ^ for negation. */ if (c == '{') { if (ptr[1] == '^') { *negptr = TRUE; ptr++; } for (i = 0; i <= 2; i++) { c = *(++ptr); if (c == 0) goto ERROR_RETURN; if (c == '}') break; name[i] = c; } if (c !='}') /* Try to distinguish error cases */ { while (*(++ptr) != 0 && *ptr != '}'); if (*ptr == '}') goto UNKNOWN_RETURN; else goto ERROR_RETURN; } name[i] = 0; } /* Otherwise there is just one following character */ else { name[0] = c; name[1] = 0; } *ptrptr = ptr; /* Search for a recognized property name using binary chop */ bot = 0; top = sizeof(utt)/sizeof(ucp_type_table); while (bot < top) { i = (bot + top)/2; c = strcmp(name, utt[i].name); if (c == 0) return utt[i].value; if (c > 0) bot = i + 1; else top = i; } UNKNOWN_RETURN: *errorptr = ERR47; *ptrptr = ptr; return -1; ERROR_RETURN: *errorptr = ERR46; *ptrptr = ptr; return -1; } #endif /************************************************* * Check for counted repeat * *************************************************/ /* This function is called when a '{' is encountered in a place where it might start a quantifier. It looks ahead to see if it really is a quantifier or not. It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd} where the ddds are digits. Arguments: p pointer to the first char after '{' Returns: TRUE or FALSE */ static BOOL is_counted_repeat(const uschar *p) { if ((digitab[*p++] & ctype_digit) == 0) return FALSE; while ((digitab[*p] & ctype_digit) != 0) p++; if (*p == '}') return TRUE; if (*p++ != ',') return FALSE; if (*p == '}') return TRUE; if ((digitab[*p++] & ctype_digit) == 0) return FALSE; while ((digitab[*p] & ctype_digit) != 0) p++; return (*p == '}'); } /************************************************* * Read repeat counts * *************************************************/ /* Read an item of the form {n,m} and return the values. This is called only after is_counted_repeat() has confirmed that a repeat-count quantifier exists, so the syntax is guaranteed to be correct, but we need to check the values. Arguments: p pointer to first char after '{' minp pointer to int for min maxp pointer to int for max returned as -1 if no max errorptr points to pointer to error message Returns: pointer to '}' on success; current ptr on error, with errorptr set */ static const uschar * read_repeat_counts(const uschar *p, int *minp, int *maxp, const char **errorptr) { int min = 0; int max = -1; /* Read the minimum value and do a paranoid check: a negative value indicates an integer overflow. */ while ((digitab[*p] & ctype_digit) != 0) min = min * 10 + *p++ - '0'; if (min < 0 || min > 65535) { *errorptr = ERR5; return p; } /* Read the maximum value if there is one, and again do a paranoid on its size. Also, max must not be less than min. */ if (*p == '}') max = min; else { if (*(++p) != '}') { max = 0; while((digitab[*p] & ctype_digit) != 0) max = max * 10 + *p++ - '0'; if (max < 0 || max > 65535) { *errorptr = ERR5; return p; } if (max < min) { *errorptr = ERR4; return p; } } } /* Fill in the required variables, and pass back the pointer to the terminating '}'. */ *minp = min; *maxp = max; return p; } /************************************************* * Find first significant op code * *************************************************/ /* This is called by several functions that scan a compiled expression looking for a fixed first character, or an anchoring op code etc. It skips over things that do not influence this. For some calls, a change of option is important. For some calls, it makes sense to skip negative forward and all backward assertions, and also the \b assertion; for others it does not. Arguments: code pointer to the start of the group options pointer to external options optbit the option bit whose changing is significant, or zero if none are skipassert TRUE if certain assertions are to be skipped Returns: pointer to the first significant opcode */ static const uschar* first_significant_code(const uschar *code, int *options, int optbit, BOOL skipassert) { for (;;) { switch ((int)*code) { case OP_OPT: if (optbit > 0 && ((int)code[1] & optbit) != (*options & optbit)) *options = (int)code[1]; code += 2; break; case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: if (!skipassert) return code; do code += GET(code, 1); while (*code == OP_ALT); code += OP_lengths[*code]; break; case OP_WORD_BOUNDARY: case OP_NOT_WORD_BOUNDARY: if (!skipassert) return code; /* Fall through */ case OP_CALLOUT: case OP_CREF: case OP_BRANUMBER: code += OP_lengths[*code]; break; default: return code; } } /* Control never reaches here */ } /************************************************* * Find the fixed length of a pattern * *************************************************/ /* Scan a pattern and compute the fixed length of subject that will match it, if the length is fixed. This is needed for dealing with backward assertions. In UTF8 mode, the result is in characters rather than bytes. Arguments: code points to the start of the pattern (the bracket) options the compiling options Returns: the fixed length, or -1 if there is no fixed length, or -2 if \C was encountered */ static int find_fixedlength(uschar *code, int options) { int length = -1; register int branchlength = 0; register uschar *cc = code + 1 + LINK_SIZE; /* Scan along the opcodes for this branch. If we get to the end of the branch, check the length against that of the other branches. */ for (;;) { int d; register int op = *cc; if (op >= OP_BRA) op = OP_BRA; switch (op) { case OP_BRA: case OP_ONCE: case OP_COND: d = find_fixedlength(cc, options); if (d < 0) return d; branchlength += d; do cc += GET(cc, 1); while (*cc == OP_ALT); cc += 1 + LINK_SIZE; break; /* Reached end of a branch; if it's a ket it is the end of a nested call. If it's ALT it is an alternation in a nested call. If it is END it's the end of the outer call. All can be handled by the same code. */ case OP_ALT: case OP_KET: case OP_KETRMAX: case OP_KETRMIN: case OP_END: if (length < 0) length = branchlength; else if (length != branchlength) return -1; if (*cc != OP_ALT) return length; cc += 1 + LINK_SIZE; branchlength = 0; break; /* Skip over assertive subpatterns */ case OP_ASSERT: case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: do cc += GET(cc, 1); while (*cc == OP_ALT); /* Fall through */ /* Skip over things that don't match chars */ case OP_REVERSE: case OP_BRANUMBER: case OP_CREF: case OP_OPT: case OP_CALLOUT: case OP_SOD: case OP_SOM: case OP_EOD: case OP_EODN: case OP_CIRC: case OP_DOLL: case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: cc += OP_lengths[*cc]; break; /* Handle literal characters */ case OP_CHAR: case OP_CHARNC: branchlength++; cc += 2; #ifdef SUPPORT_UTF8 if ((options & PCRE_UTF8) != 0) { while ((*cc & 0xc0) == 0x80) cc++; } #endif break; /* Handle exact repetitions. The count is already in characters, but we need to skip over a multibyte character in UTF8 mode. */ case OP_EXACT: branchlength += GET2(cc,1); cc += 4; #ifdef SUPPORT_UTF8 if ((options & PCRE_UTF8) != 0) { while((*cc & 0x80) == 0x80) cc++; } #endif break; case OP_TYPEEXACT: branchlength += GET2(cc,1); cc += 4; break; /* Handle single-char matchers */ case OP_PROP: case OP_NOTPROP: cc++; /* Fall through */ case OP_NOT_DIGIT: case OP_DIGIT: case OP_NOT_WHITESPACE: case OP_WHITESPACE: case OP_NOT_WORDCHAR: case OP_WORDCHAR: case OP_ANY: branchlength++; cc++; break; /* The single-byte matcher isn't allowed */ case OP_ANYBYTE: return -2; /* Check a class for variable quantification */ #ifdef SUPPORT_UTF8 case OP_XCLASS: cc += GET(cc, 1) - 33; /* Fall through */ #endif case OP_CLASS: case OP_NCLASS: cc += 33; switch (*cc) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRQUERY: case OP_CRMINQUERY: return -1; case OP_CRRANGE: case OP_CRMINRANGE: if (GET2(cc,1) != GET2(cc,3)) return -1; branchlength += GET2(cc,1); cc += 5; break; default: branchlength++; } break; /* Anything else is variable length */ default: return -1; } } /* Control never gets here */ } /************************************************* * Scan compiled regex for numbered bracket * *************************************************/ /* This little function scans through a compiled pattern until it finds a capturing bracket with the given number. Arguments: code points to start of expression utf8 TRUE in UTF-8 mode number the required bracket number Returns: pointer to the opcode for the bracket, or NULL if not found */ static const uschar * find_bracket(const uschar *code, BOOL utf8, int number) { #ifndef SUPPORT_UTF8 utf8 = utf8; /* Stop pedantic compilers complaining */ #endif for (;;) { register int c = *code; if (c == OP_END) return NULL; else if (c > OP_BRA) { int n = c - OP_BRA; if (n > EXTRACT_BASIC_MAX) n = GET2(code, 2+LINK_SIZE); if (n == number) return (uschar *)code; code += OP_lengths[OP_BRA]; } else { code += OP_lengths[c]; #ifdef SUPPORT_UTF8 /* In UTF-8 mode, opcodes that are followed by a character may be followed by a multi-byte character. The length in the table is a minimum, so we have to scan along to skip the extra bytes. All opcodes are less than 128, so we can use relatively efficient code. */ if (utf8) switch(c) { case OP_CHAR: case OP_CHARNC: case OP_EXACT: case OP_UPTO: case OP_MINUPTO: case OP_STAR: case OP_MINSTAR: case OP_PLUS: case OP_MINPLUS: case OP_QUERY: case OP_MINQUERY: while ((*code & 0xc0) == 0x80) code++; break; /* XCLASS is used for classes that cannot be represented just by a bit map. This includes negated single high-valued characters. The length in the table is zero; the actual length is stored in the compiled code. */ case OP_XCLASS: code += GET(code, 1) + 1; break; } #endif } } } /************************************************* * Scan compiled regex for recursion reference * *************************************************/ /* This little function scans through a compiled pattern until it finds an instance of OP_RECURSE. Arguments: code points to start of expression utf8 TRUE in UTF-8 mode Returns: pointer to the opcode for OP_RECURSE, or NULL if not found */ static const uschar * find_recurse(const uschar *code, BOOL utf8) { #ifndef SUPPORT_UTF8 utf8 = utf8; /* Stop pedantic compilers complaining */ #endif for (;;) { register int c = *code; if (c == OP_END) return NULL; else if (c == OP_RECURSE) return code; else if (c > OP_BRA) { code += OP_lengths[OP_BRA]; } else { code += OP_lengths[c]; #ifdef SUPPORT_UTF8 /* In UTF-8 mode, opcodes that are followed by a character may be followed by a multi-byte character. The length in the table is a minimum, so we have to scan along to skip the extra bytes. All opcodes are less than 128, so we can use relatively efficient code. */ if (utf8) switch(c) { case OP_CHAR: case OP_CHARNC: case OP_EXACT: case OP_UPTO: case OP_MINUPTO: case OP_STAR: case OP_MINSTAR: case OP_PLUS: case OP_MINPLUS: case OP_QUERY: case OP_MINQUERY: while ((*code & 0xc0) == 0x80) code++; break; /* XCLASS is used for classes that cannot be represented just by a bit map. This includes negated single high-valued characters. The length in the table is zero; the actual length is stored in the compiled code. */ case OP_XCLASS: code += GET(code, 1) + 1; break; } #endif } } } /************************************************* * Scan compiled branch for non-emptiness * *************************************************/ /* This function scans through a branch of a compiled pattern to see whether it can match the empty string or not. It is called only from could_be_empty() below. Note that first_significant_code() skips over assertions. If we hit an unclosed bracket, we return "empty" - this means we've struck an inner bracket whose current branch will already have been scanned. Arguments: code points to start of search endcode points to where to stop utf8 TRUE if in UTF8 mode Returns: TRUE if what is matched could be empty */ static BOOL could_be_empty_branch(const uschar *code, const uschar *endcode, BOOL utf8) { register int c; for (code = first_significant_code(code + 1 + LINK_SIZE, NULL, 0, TRUE); code < endcode; code = first_significant_code(code + OP_lengths[c], NULL, 0, TRUE)) { const uschar *ccode; c = *code; if (c >= OP_BRA) { BOOL empty_branch; if (GET(code, 1) == 0) return TRUE; /* Hit unclosed bracket */ /* Scan a closed bracket */ empty_branch = FALSE; do { if (!empty_branch && could_be_empty_branch(code, endcode, utf8)) empty_branch = TRUE; code += GET(code, 1); } while (*code == OP_ALT); if (!empty_branch) return FALSE; /* All branches are non-empty */ code += 1 + LINK_SIZE; c = *code; } else switch (c) { /* Check for quantifiers after a class */ #ifdef SUPPORT_UTF8 case OP_XCLASS: ccode = code + GET(code, 1); goto CHECK_CLASS_REPEAT; #endif case OP_CLASS: case OP_NCLASS: ccode = code + 33; #ifdef SUPPORT_UTF8 CHECK_CLASS_REPEAT: #endif switch (*ccode) { case OP_CRSTAR: /* These could be empty; continue */ case OP_CRMINSTAR: case OP_CRQUERY: case OP_CRMINQUERY: break; default: /* Non-repeat => class must match */ case OP_CRPLUS: /* These repeats aren't empty */ case OP_CRMINPLUS: return FALSE; case OP_CRRANGE: case OP_CRMINRANGE: if (GET2(ccode, 1) > 0) return FALSE; /* Minimum > 0 */ break; } break; /* Opcodes that must match a character */ case OP_PROP: case OP_NOTPROP: case OP_EXTUNI: case OP_NOT_DIGIT: case OP_DIGIT: case OP_NOT_WHITESPACE: case OP_WHITESPACE: case OP_NOT_WORDCHAR: case OP_WORDCHAR: case OP_ANY: case OP_ANYBYTE: case OP_CHAR: case OP_CHARNC: case OP_NOT: case OP_PLUS: case OP_MINPLUS: case OP_EXACT: case OP_NOTPLUS: case OP_NOTMINPLUS: case OP_NOTEXACT: case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEEXACT: return FALSE; /* End of branch */ case OP_KET: case OP_KETRMAX: case OP_KETRMIN: case OP_ALT: return TRUE; /* In UTF-8 mode, STAR, MINSTAR, QUERY, MINQUERY, UPTO, and MINUPTO may be followed by a multibyte character */ #ifdef SUPPORT_UTF8 case OP_STAR: case OP_MINSTAR: case OP_QUERY: case OP_MINQUERY: case OP_UPTO: case OP_MINUPTO: if (utf8) while ((code[2] & 0xc0) == 0x80) code++; break; #endif } } return TRUE; } /************************************************* * Scan compiled regex for non-emptiness * *************************************************/ /* This function is called to check for left recursive calls. We want to check the current branch of the current pattern to see if it could match the empty string. If it could, we must look outwards for branches at other levels, stopping when we pass beyond the bracket which is the subject of the recursion. Arguments: code points to start of the recursion endcode points to where to stop (current RECURSE item) bcptr points to the chain of current (unclosed) branch starts utf8 TRUE if in UTF-8 mode Returns: TRUE if what is matched could be empty */ static BOOL could_be_empty(const uschar *code, const uschar *endcode, branch_chain *bcptr, BOOL utf8) { while (bcptr != NULL && bcptr->current >= code) { if (!could_be_empty_branch(bcptr->current, endcode, utf8)) return FALSE; bcptr = bcptr->outer; } return TRUE; } /************************************************* * Check for POSIX class syntax * *************************************************/ /* This function is called when the sequence "[:" or "[." or "[=" is encountered in a character class. It checks whether this is followed by an optional ^ and then a sequence of letters, terminated by a matching ":]" or ".]" or "=]". Argument: ptr pointer to the initial [ endptr where to return the end pointer cd pointer to compile data Returns: TRUE or FALSE */ static BOOL check_posix_syntax(const uschar *ptr, const uschar **endptr, compile_data *cd) { int terminator; /* Don't combine these lines; the Solaris cc */ terminator = *(++ptr); /* compiler warns about "non-constant" initializer. */ if (*(++ptr) == '^') ptr++; while ((cd->ctypes[*ptr] & ctype_letter) != 0) ptr++; if (*ptr == terminator && ptr[1] == ']') { *endptr = ptr; return TRUE; } return FALSE; } /************************************************* * Check POSIX class name * *************************************************/ /* This function is called to check the name given in a POSIX-style class entry such as [:alnum:]. Arguments: ptr points to the first letter len the length of the name Returns: a value representing the name, or -1 if unknown */ static int check_posix_name(const uschar *ptr, int len) { register int yield = 0; while (posix_name_lengths[yield] != 0) { if (len == posix_name_lengths[yield] && strncmp((const char *)ptr, posix_names[yield], len) == 0) return yield; yield++; } return -1; } /************************************************* * Adjust OP_RECURSE items in repeated group * *************************************************/ /* OP_RECURSE items contain an offset from the start of the regex to the group that is referenced. This means that groups can be replicated for fixed repetition simply by copying (because the recursion is allowed to refer to earlier groups that are outside the current group). However, when a group is optional (i.e. the minimum quantifier is zero), OP_BRAZERO is inserted before it, after it has been compiled. This means that any OP_RECURSE items within it that refer to the group itself or any contained groups have to have their offsets adjusted. That is the job of this function. Before it is called, the partially compiled regex must be temporarily terminated with OP_END. Arguments: group points to the start of the group adjust the amount by which the group is to be moved utf8 TRUE in UTF-8 mode cd contains pointers to tables etc. Returns: nothing */ static void adjust_recurse(uschar *group, int adjust, BOOL utf8, compile_data *cd) { uschar *ptr = group; while ((ptr = (uschar *)find_recurse(ptr, utf8)) != NULL) { int offset = GET(ptr, 1); if (cd->start_code + offset >= group) PUT(ptr, 1, offset + adjust); ptr += 1 + LINK_SIZE; } } /************************************************* * Insert an automatic callout point * *************************************************/ /* This function is called when the PCRE_AUTO_CALLOUT option is set, to insert callout points before each pattern item. Arguments: code current code pointer ptr current pattern pointer cd pointers to tables etc Returns: new code pointer */ static uschar * auto_callout(uschar *code, const uschar *ptr, compile_data *cd) { *code++ = OP_CALLOUT; *code++ = 255; PUT(code, 0, ptr - cd->start_pattern); /* Pattern offset */ PUT(code, LINK_SIZE, 0); /* Default length */ return code + 2*LINK_SIZE; } /************************************************* * Complete a callout item * *************************************************/ /* A callout item contains the length of the next item in the pattern, which we can't fill in till after we have reached the relevant point. This is used for both automatic and manual callouts. Arguments: previous_callout points to previous callout item ptr current pattern pointer cd pointers to tables etc Returns: nothing */ static void complete_callout(uschar *previous_callout, const uschar *ptr, compile_data *cd) { int length = ptr - cd->start_pattern - GET(previous_callout, 2); PUT(previous_callout, 2 + LINK_SIZE, length); } #ifdef SUPPORT_UCP /************************************************* * Get othercase range * *************************************************/ /* This function is passed the start and end of a class range, in UTF-8 mode with UCP support. It searches up the characters, looking for internal ranges of characters in the "other" case. Each call returns the next one, updating the start address. Arguments: cptr points to starting character value; updated d end value ocptr where to put start of othercase range odptr where to put end of othercase range Yield: TRUE when range returned; FALSE when no more */ static BOOL get_othercase_range(int *cptr, int d, int *ocptr, int *odptr) { int c, chartype, othercase, next; for (c = *cptr; c <= d; c++) { if (ucp_findchar(c, &chartype, &othercase) == ucp_L && othercase != 0) break; } if (c > d) return FALSE; *ocptr = othercase; next = othercase + 1; for (++c; c <= d; c++) { if (ucp_findchar(c, &chartype, &othercase) != ucp_L || othercase != next) break; next++; } *odptr = next - 1; *cptr = c; return TRUE; } #endif /* SUPPORT_UCP */ /************************************************* * Compile one branch * *************************************************/ /* Scan the pattern, compiling it into the code vector. If the options are changed during the branch, the pointer is used to change the external options bits. Arguments: optionsptr pointer to the option bits brackets points to number of extracting brackets used codeptr points to the pointer to the current code point ptrptr points to the current pattern pointer errorptr points to pointer to error message firstbyteptr set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE) reqbyteptr set to the last literal character required, else < 0 bcptr points to current branch chain cd contains pointers to tables etc. Returns: TRUE on success FALSE, with *errorptr set on error */ static BOOL compile_branch(int *optionsptr, int *brackets, uschar **codeptr, const uschar **ptrptr, const char **errorptr, int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, compile_data *cd) { int repeat_type, op_type; int repeat_min = 0, repeat_max = 0; /* To please picky compilers */ int bravalue = 0; int greedy_default, greedy_non_default; int firstbyte, reqbyte; int zeroreqbyte, zerofirstbyte; int req_caseopt, reqvary, tempreqvary; int condcount = 0; int options = *optionsptr; int after_manual_callout = 0; register int c; register uschar *code = *codeptr; uschar *tempcode; BOOL inescq = FALSE; BOOL groupsetfirstbyte = FALSE; const uschar *ptr = *ptrptr; const uschar *tempptr; uschar *previous = NULL; uschar *previous_callout = NULL; uschar classbits[32]; #ifdef SUPPORT_UTF8 BOOL class_utf8; BOOL utf8 = (options & PCRE_UTF8) != 0; uschar *class_utf8data; uschar utf8_char[6]; #else BOOL utf8 = FALSE; #endif /* Set up the default and non-default settings for greediness */ greedy_default = ((options & PCRE_UNGREEDY) != 0); greedy_non_default = greedy_default ^ 1; /* Initialize no first byte, no required byte. REQ_UNSET means "no char matching encountered yet". It gets changed to REQ_NONE if we hit something that matches a non-fixed char first char; reqbyte just remains unset if we never find one. When we hit a repeat whose minimum is zero, we may have to adjust these values to take the zero repeat into account. This is implemented by setting them to zerofirstbyte and zeroreqbyte when such a repeat is encountered. The individual item types that can be repeated set these backoff variables appropriately. */ firstbyte = reqbyte = zerofirstbyte = zeroreqbyte = REQ_UNSET; /* The variable req_caseopt contains either the REQ_CASELESS value or zero, according to the current setting of the caseless flag. REQ_CASELESS is a bit value > 255. It is added into the firstbyte or reqbyte variables to record the case status of the value. This is used only for ASCII characters. */ req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS : 0; /* Switch on next character until the end of the branch */ for (;; ptr++) { BOOL negate_class; BOOL possessive_quantifier; BOOL is_quantifier; int class_charcount; int class_lastchar; int newoptions; int recno; int skipbytes; int subreqbyte; int subfirstbyte; int mclength; uschar mcbuffer[8]; /* Next byte in the pattern */ c = *ptr; /* If in \Q...\E, check for the end; if not, we have a literal */ if (inescq && c != 0) { if (c == '\\' && ptr[1] == 'E') { inescq = FALSE; ptr++; continue; } else { if (previous_callout != NULL) { complete_callout(previous_callout, ptr, cd); previous_callout = NULL; } if ((options & PCRE_AUTO_CALLOUT) != 0) { previous_callout = code; code = auto_callout(code, ptr, cd); } goto NORMAL_CHAR; } } /* Fill in length of a previous callout, except when the next thing is a quantifier. */ is_quantifier = c == '*' || c == '+' || c == '?' || (c == '{' && is_counted_repeat(ptr+1)); if (!is_quantifier && previous_callout != NULL && after_manual_callout-- <= 0) { complete_callout(previous_callout, ptr, cd); previous_callout = NULL; } /* In extended mode, skip white space and comments */ if ((options & PCRE_EXTENDED) != 0) { if ((cd->ctypes[c] & ctype_space) != 0) continue; if (c == '#') { /* The space before the ; is to avoid a warning on a silly compiler on the Macintosh. */ while ((c = *(++ptr)) != 0 && c != NEWLINE) ; if (c != 0) continue; /* Else fall through to handle end of string */ } } /* No auto callout for quantifiers. */ if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier) { previous_callout = code; code = auto_callout(code, ptr, cd); } switch(c) { /* The branch terminates at end of string, |, or ). */ case 0: case '|': case ')': *firstbyteptr = firstbyte; *reqbyteptr = reqbyte; *codeptr = code; *ptrptr = ptr; return TRUE; /* Handle single-character metacharacters. In multiline mode, ^ disables the setting of any following char as a first character. */ case '^': if ((options & PCRE_MULTILINE) != 0) { if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; } previous = NULL; *code++ = OP_CIRC; break; case '$': previous = NULL; *code++ = OP_DOLL; break; /* There can never be a first char if '.' is first, whatever happens about repeats. The value of reqbyte doesn't change either. */ case '.': if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; zerofirstbyte = firstbyte; zeroreqbyte = reqbyte; previous = code; *code++ = OP_ANY; break; /* Character classes. If the included characters are all < 255 in value, we build a 32-byte bitmap of the permitted characters, except in the special case where there is only one such character. For negated classes, we build the map as usual, then invert it at the end. However, we use a different opcode so that data characters > 255 can be handled correctly. If the class contains characters outside the 0-255 range, a different opcode is compiled. It may optionally have a bit map for characters < 256, but those above are are explicitly listed afterwards. A flag byte tells whether the bitmap is present, and whether this is a negated class or not. */ case '[': previous = code; /* PCRE supports POSIX class stuff inside a class. Perl gives an error if they are encountered at the top level, so we'll do that too. */ if ((ptr[1] == ':' || ptr[1] == '.' || ptr[1] == '=') && check_posix_syntax(ptr, &tempptr, cd)) { *errorptr = (ptr[1] == ':')? ERR13 : ERR31; goto FAILED; } /* If the first character is '^', set the negation flag and skip it. */ if ((c = *(++ptr)) == '^') { negate_class = TRUE; c = *(++ptr); } else { negate_class = FALSE; } /* Keep a count of chars with values < 256 so that we can optimize the case of just a single character (as long as it's < 256). For higher valued UTF-8 characters, we don't yet do any optimization. */ class_charcount = 0; class_lastchar = -1; #ifdef SUPPORT_UTF8 class_utf8 = FALSE; /* No chars >= 256 */ class_utf8data = code + LINK_SIZE + 34; /* For UTF-8 items */ #endif /* Initialize the 32-char bit map to all zeros. We have to build the map in a temporary bit of store, in case the class contains only 1 character (< 256), because in that case the compiled code doesn't use the bit map. */ memset(classbits, 0, 32 * sizeof(uschar)); /* Process characters until ] is reached. By writing this as a "do" it means that an initial ] is taken as a data character. The first pass through the regex checked the overall syntax, so we don't need to be very strict here. At the start of the loop, c contains the first byte of the character. */ do { #ifdef SUPPORT_UTF8 if (utf8 && c > 127) { /* Braces are required because the */ GETCHARLEN(c, ptr, ptr); /* macro generates multiple statements */ } #endif /* Inside \Q...\E everything is literal except \E */ if (inescq) { if (c == '\\' && ptr[1] == 'E') { inescq = FALSE; ptr++; continue; } else goto LONE_SINGLE_CHARACTER; } /* Handle POSIX class names. Perl allows a negation extension of the form [:^name:]. A square bracket that doesn't match the syntax is treated as a literal. We also recognize the POSIX constructions [.ch.] and [=ch=] ("collating elements") and fault them, as Perl 5.6 and 5.8 do. */ if (c == '[' && (ptr[1] == ':' || ptr[1] == '.' || ptr[1] == '=') && check_posix_syntax(ptr, &tempptr, cd)) { BOOL local_negate = FALSE; int posix_class, i; register const uschar *cbits = cd->cbits; if (ptr[1] != ':') { *errorptr = ERR31; goto FAILED; } ptr += 2; if (*ptr == '^') { local_negate = TRUE; ptr++; } posix_class = check_posix_name(ptr, tempptr - ptr); if (posix_class < 0) { *errorptr = ERR30; goto FAILED; } /* If matching is caseless, upper and lower are converted to alpha. This relies on the fact that the class table starts with alpha, lower, upper as the first 3 entries. */ if ((options & PCRE_CASELESS) != 0 && posix_class <= 2) posix_class = 0; /* Or into the map we are building up to 3 of the static class tables, or their negations. The [:blank:] class sets up the same chars as the [:space:] class (all white space). We remove the vertical white space chars afterwards. */ posix_class *= 3; for (i = 0; i < 3; i++) { BOOL blankclass = strncmp((char *)ptr, "blank", 5) == 0; int taboffset = posix_class_maps[posix_class + i]; if (taboffset < 0) break; if (local_negate) { if (i == 0) for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+taboffset]; else for (c = 0; c < 32; c++) classbits[c] &= ~cbits[c+taboffset]; if (blankclass) classbits[1] |= 0x3c; } else { for (c = 0; c < 32; c++) classbits[c] |= cbits[c+taboffset]; if (blankclass) classbits[1] &= ~0x3c; } } ptr = tempptr + 1; class_charcount = 10; /* Set > 1; assumes more than 1 per class */ continue; /* End of POSIX syntax handling */ } /* Backslash may introduce a single character, or it may introduce one of the specials, which just set a flag. Escaped items are checked for validity in the pre-compiling pass. The sequence \b is a special case. Inside a class (and only there) it is treated as backspace. Elsewhere it marks a word boundary. Other escapes have preset maps ready to or into the one we are building. We assume they have more than one character in them, so set class_charcount bigger than one. */ if (c == '\\') { c = check_escape(&ptr, errorptr, *brackets, options, TRUE); if (-c == ESC_b) c = '\b'; /* \b is backslash in a class */ else if (-c == ESC_X) c = 'X'; /* \X is literal X in a class */ else if (-c == ESC_Q) /* Handle start of quoted string */ { if (ptr[1] == '\\' && ptr[2] == 'E') { ptr += 2; /* avoid empty string */ } else inescq = TRUE; continue; } if (c < 0) { register const uschar *cbits = cd->cbits; class_charcount += 2; /* Greater than 1 is what matters */ switch (-c) { case ESC_d: for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_digit]; continue; case ESC_D: for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_digit]; continue; case ESC_w: for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_word]; continue; case ESC_W: for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_word]; continue; case ESC_s: for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_space]; classbits[1] &= ~0x08; /* Perl 5.004 onwards omits VT from \s */ continue; case ESC_S: for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_space]; classbits[1] |= 0x08; /* Perl 5.004 onwards omits VT from \s */ continue; #ifdef SUPPORT_UCP case ESC_p: case ESC_P: { BOOL negated; int property = get_ucp(&ptr, &negated, errorptr); if (property < 0) goto FAILED; class_utf8 = TRUE; *class_utf8data++ = ((-c == ESC_p) != negated)? XCL_PROP : XCL_NOTPROP; *class_utf8data++ = property; class_charcount -= 2; /* Not a < 256 character */ } continue; #endif /* Unrecognized escapes are faulted if PCRE is running in its strict mode. By default, for compatibility with Perl, they are treated as literals. */ default: if ((options & PCRE_EXTRA) != 0) { *errorptr = ERR7; goto FAILED; } c = *ptr; /* The final character */ class_charcount -= 2; /* Undo the default count from above */ } } /* Fall through if we have a single character (c >= 0). This may be > 256 in UTF-8 mode. */ } /* End of backslash handling */ /* A single character may be followed by '-' to form a range. However, Perl does not permit ']' to be the end of the range. A '-' character here is treated as a literal. */ if (ptr[1] == '-' && ptr[2] != ']') { int d; ptr += 2; #ifdef SUPPORT_UTF8 if (utf8) { /* Braces are required because the */ GETCHARLEN(d, ptr, ptr); /* macro generates multiple statements */ } else #endif d = *ptr; /* Not UTF-8 mode */ /* The second part of a range can be a single-character escape, but not any of the other escapes. Perl 5.6 treats a hyphen as a literal in such circumstances. */ if (d == '\\') { const uschar *oldptr = ptr; d = check_escape(&ptr, errorptr, *brackets, options, TRUE); /* \b is backslash; \X is literal X; any other special means the '-' was literal */ if (d < 0) { if (d == -ESC_b) d = '\b'; else if (d == -ESC_X) d = 'X'; else { ptr = oldptr - 2; goto LONE_SINGLE_CHARACTER; /* A few lines below */ } } } /* The check that the two values are in the correct order happens in the pre-pass. Optimize one-character ranges */ if (d == c) goto LONE_SINGLE_CHARACTER; /* A few lines below */ /* In UTF-8 mode, if the upper limit is > 255, or > 127 for caseless matching, we have to use an XCLASS with extra data items. Caseless matching for characters > 127 is available only if UCP support is available. */ #ifdef SUPPORT_UTF8 if (utf8 && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127))) { class_utf8 = TRUE; /* With UCP support, we can find the other case equivalents of the relevant characters. There may be several ranges. Optimize how they fit with the basic range. */ #ifdef SUPPORT_UCP if ((options & PCRE_CASELESS) != 0) { int occ, ocd; int cc = c; int origd = d; while (get_othercase_range(&cc, origd, &occ, &ocd)) { if (occ >= c && ocd <= d) continue; /* Skip embedded ranges */ if (occ < c && ocd >= c - 1) /* Extend the basic range */ { /* if there is overlap, */ c = occ; /* noting that if occ < c */ continue; /* we can't have ocd > d */ } /* because a subrange is */ if (ocd > d && occ <= d + 1) /* always shorter than */ { /* the basic range. */ d = ocd; continue; } if (occ == ocd) { *class_utf8data++ = XCL_SINGLE; } else { *class_utf8data++ = XCL_RANGE; class_utf8data += ord2utf8(occ, class_utf8data); } class_utf8data += ord2utf8(ocd, class_utf8data); } } #endif /* SUPPORT_UCP */ /* Now record the original range, possibly modified for UCP caseless overlapping ranges. */ *class_utf8data++ = XCL_RANGE; class_utf8data += ord2utf8(c, class_utf8data); class_utf8data += ord2utf8(d, class_utf8data); /* With UCP support, we are done. Without UCP support, there is no caseless matching for UTF-8 characters > 127; we can use the bit map for the smaller ones. */ #ifdef SUPPORT_UCP continue; /* With next character in the class */ #else if ((options & PCRE_CASELESS) == 0 || c > 127) continue; /* Adjust upper limit and fall through to set up the map */ d = 127; #endif /* SUPPORT_UCP */ } #endif /* SUPPORT_UTF8 */ /* We use the bit map for all cases when not in UTF-8 mode; else ranges that lie entirely within 0-127 when there is UCP support; else for partial ranges without UCP support. */ for (; c <= d; c++) { classbits[c/8] |= (1 << (c&7)); if ((options & PCRE_CASELESS) != 0) { int uc = cd->fcc[c]; /* flip case */ classbits[uc/8] |= (1 << (uc&7)); } class_charcount++; /* in case a one-char range */ class_lastchar = c; } continue; /* Go get the next char in the class */ } /* Handle a lone single character - we can get here for a normal non-escape char, or after \ that introduces a single character or for an apparent range that isn't. */ LONE_SINGLE_CHARACTER: /* Handle a character that cannot go in the bit map */ #ifdef SUPPORT_UTF8 if (utf8 && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127))) { class_utf8 = TRUE; *class_utf8data++ = XCL_SINGLE; class_utf8data += ord2utf8(c, class_utf8data); #ifdef SUPPORT_UCP if ((options & PCRE_CASELESS) != 0) { int chartype; int othercase; if (ucp_findchar(c, &chartype, &othercase) >= 0 && othercase > 0) { *class_utf8data++ = XCL_SINGLE; class_utf8data += ord2utf8(othercase, class_utf8data); } } #endif /* SUPPORT_UCP */ } else #endif /* SUPPORT_UTF8 */ /* Handle a single-byte character */ { classbits[c/8] |= (1 << (c&7)); if ((options & PCRE_CASELESS) != 0) { c = cd->fcc[c]; /* flip case */ classbits[c/8] |= (1 << (c&7)); } class_charcount++; class_lastchar = c; } } /* Loop until ']' reached; the check for end of string happens inside the loop. This "while" is the end of the "do" above. */ while ((c = *(++ptr)) != ']' || inescq); /* If class_charcount is 1, we saw precisely one character whose value is less than 256. In non-UTF-8 mode we can always optimize. In UTF-8 mode, we can optimize the negative case only if there were no characters >= 128 because OP_NOT and the related opcodes like OP_NOTSTAR operate on single-bytes only. This is an historical hangover. Maybe one day we can tidy these opcodes to handle multi-byte characters. The optimization throws away the bit map. We turn the item into a 1-character OP_CHAR[NC] if it's positive, or OP_NOT if it's negative. Note that OP_NOT does not support multibyte characters. In the positive case, it can cause firstbyte to be set. Otherwise, there can be no first char if this item is first, whatever repeat count may follow. In the case of reqbyte, save the previous value for reinstating. */ #ifdef SUPPORT_UTF8 if (class_charcount == 1 && (!utf8 || (!class_utf8 && (!negate_class || class_lastchar < 128)))) #else if (class_charcount == 1) #endif { zeroreqbyte = reqbyte; /* The OP_NOT opcode works on one-byte characters only. */ if (negate_class) { if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; zerofirstbyte = firstbyte; *code++ = OP_NOT; *code++ = class_lastchar; break; } /* For a single, positive character, get the value into mcbuffer, and then we can handle this with the normal one-character code. */ #ifdef SUPPORT_UTF8 if (utf8 && class_lastchar > 127) mclength = ord2utf8(class_lastchar, mcbuffer); else #endif { mcbuffer[0] = class_lastchar; mclength = 1; } goto ONE_CHAR; } /* End of 1-char optimization */ /* The general case - not the one-char optimization. If this is the first thing in the branch, there can be no first char setting, whatever the repeat count. Any reqbyte setting must remain unchanged after any kind of repeat. */ if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE; zerofirstbyte = firstbyte; zeroreqbyte = reqbyte; /* If there are characters with values > 255, we have to compile an extended class, with its own opcode. If there are no characters < 256, we can omit the bitmap. */ #ifdef SUPPORT_UTF8 if (class_utf8) { *class_utf8data++ = XCL_END; /* Marks the end of extra data */ *code++ = OP_XCLASS; code += LINK_SIZE; *code = negate_class? XCL_NOT : 0; /* If the map is required, install it, and move on to the end of the extra data */ if (class_charcount > 0) { *code++ |= XCL_MAP; memcpy(code, classbits, 32); code = class_utf8data; } /* If the map is not required, slide down the extra data. */ else { int len = class_utf8data - (code + 33); memmove(code + 1, code + 33, len); code += len + 1; } /* Now fill in the complete length of the item */ PUT(previous, 1, code - previous); break; /* End of class handling */ } #endif /* If there are no characters > 255, negate the 32-byte map if necessary, and copy it into the code vector. If this is the first thing in the branch, there can be no first char setting, whatever the repeat count. Any reqbyte setting must remain unchanged after any kind of repeat. */ if (negate_class) { *code++ = OP_NCLASS; for (c = 0; c < 32; c++) code[c] = ~classbits[c]; } else { *code++ = OP_CLASS; memcpy(code, classbits, 32); } code += 32; break; /* Various kinds of repeat; '{' is not necessarily a quantifier, but this has been tested above. */ case '{': if (!is_quantifier) goto NORMAL_CHAR; ptr = read_repeat_counts(ptr+1, &repeat_min, &repeat_max, errorptr); if (*errorptr != NULL) goto FAILED; goto REPEAT; case '*': repeat_min = 0; repeat_max = -1; goto REPEAT; case '+': repeat_min = 1; repeat_max = -1; goto REPEAT; case '?': repeat_min = 0; repeat_max = 1; REPEAT: if (previous == NULL) { *errorptr = ERR9; goto FAILED; } if (repeat_min == 0) { firstbyte = zerofirstbyte; /* Adjust for zero repeat */ reqbyte = zeroreqbyte; /* Ditto */ } /* Remember whether this is a variable length repeat */ reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY; op_type = 0; /* Default single-char op codes */ possessive_quantifier = FALSE; /* Default not possessive quantifier */ /* Save start of previous item, in case we have to move it up to make space for an inserted OP_ONCE for the additional '+' extension. */ tempcode = previous; /* If the next character is '+', we have a possessive quantifier. This implies greediness, whatever the setting of the PCRE_UNGREEDY option. If the next character is '?' this is a minimizing repeat, by default, but if PCRE_UNGREEDY is set, it works the other way round. We change the repeat type to the non-default. */ if (ptr[1] == '+') { repeat_type = 0; /* Force greedy */ possessive_quantifier = TRUE; ptr++; } else if (ptr[1] == '?') { repeat_type = greedy_non_default; ptr++; } else repeat_type = greedy_default; /* If previous was a recursion, we need to wrap it inside brackets so that it can be replicated if necessary. */ if (*previous == OP_RECURSE) { memmove(previous + 1 + LINK_SIZE, previous, 1 + LINK_SIZE); code += 1 + LINK_SIZE; *previous = OP_BRA; PUT(previous, 1, code - previous); *code = OP_KET; PUT(code, 1, code - previous); code += 1 + LINK_SIZE; } /* If previous was a character match, abolish the item and generate a repeat item instead. If a char item has a minumum of more than one, ensure that it is set in reqbyte - it might not be if a sequence such as x{3} is the first thing in a branch because the x will have gone into firstbyte instead. */ if (*previous == OP_CHAR || *previous == OP_CHARNC) { /* Deal with UTF-8 characters that take up more than one byte. It's easier to write this out separately than try to macrify it. Use c to hold the length of the character in bytes, plus 0x80 to flag that it's a length rather than a small character. */ #ifdef SUPPORT_UTF8 if (utf8 && (code[-1] & 0x80) != 0) { uschar *lastchar = code - 1; while((*lastchar & 0xc0) == 0x80) lastchar--; c = code - lastchar; /* Length of UTF-8 character */ memcpy(utf8_char, lastchar, c); /* Save the char */ c |= 0x80; /* Flag c as a length */ } else #endif /* Handle the case of a single byte - either with no UTF8 support, or with UTF-8 disabled, or for a UTF-8 character < 128. */ { c = code[-1]; if (repeat_min > 1) reqbyte = c | req_caseopt | cd->req_varyopt; } goto OUTPUT_SINGLE_REPEAT; /* Code shared with single character types */ } /* If previous was a single negated character ([^a] or similar), we use one of the special opcodes, replacing it. The code is shared with single- character repeats by setting opt_type to add a suitable offset into repeat_type. OP_NOT is currently used only for single-byte chars. */ else if (*previous == OP_NOT) { op_type = OP_NOTSTAR - OP_STAR; /* Use "not" opcodes */ c = previous[1]; goto OUTPUT_SINGLE_REPEAT; } /* If previous was a character type match (\d or similar), abolish it and create a suitable repeat item. The code is shared with single-character repeats by setting op_type to add a suitable offset into repeat_type. Note the the Unicode property types will be present only when SUPPORT_UCP is defined, but we don't wrap the little bits of code here because it just makes it horribly messy. */ else if (*previous < OP_EODN) { uschar *oldcode; int prop_type; op_type = OP_TYPESTAR - OP_STAR; /* Use type opcodes */ c = *previous; OUTPUT_SINGLE_REPEAT: prop_type = (*previous == OP_PROP || *previous == OP_NOTPROP)? previous[1] : -1; oldcode = code; code = previous; /* Usually overwrite previous item */ /* If the maximum is zero then the minimum must also be zero; Perl allows this case, so we do too - by simply omitting the item altogether. */ if (repeat_max == 0) goto END_REPEAT; /* All real repeats make it impossible to handle partial matching (maybe one day we will be able to remove this restriction). */ if (repeat_max != 1) cd->nopartial = TRUE; /* Combine the op_type with the repeat_type */ repeat_type += op_type; /* A minimum of zero is handled either as the special case * or ?, or as an UPTO, with the maximum given. */ if (repeat_min == 0) { if (repeat_max == -1) *code++ = OP_STAR + repeat_type; else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type; else { *code++ = OP_UPTO + repeat_type; PUT2INC(code, 0, repeat_max); } } /* A repeat minimum of 1 is optimized into some special cases. If the maximum is unlimited, we use OP_PLUS. Otherwise, the original item it left in place and, if the maximum is greater than 1, we use OP_UPTO with one less than the maximum. */ else if (repeat_min == 1) { if (repeat_max == -1) *code++ = OP_PLUS + repeat_type; else { code = oldcode; /* leave previous item in place */ if (repeat_max == 1) goto END_REPEAT; *code++ = OP_UPTO + repeat_type; PUT2INC(code, 0, repeat_max - 1); } } /* The case {n,n} is just an EXACT, while the general case {n,m} is handled as an EXACT followed by an UPTO. */ else { *code++ = OP_EXACT + op_type; /* NB EXACT doesn't have repeat_type */ PUT2INC(code, 0, repeat_min); /* If the maximum is unlimited, insert an OP_STAR. Before doing so, we have to insert the character for the previous code. For a repeated Unicode property match, there is an extra byte that defines the required property. In UTF-8 mode, long characters have their length in c, with the 0x80 bit as a flag. */ if (repeat_max < 0) { #ifdef SUPPORT_UTF8 if (utf8 && c >= 128) { memcpy(code, utf8_char, c & 7); code += c & 7; } else #endif { *code++ = c; if (prop_type >= 0) *code++ = prop_type; } *code++ = OP_STAR + repeat_type; } /* Else insert an UPTO if the max is greater than the min, again preceded by the character, for the previously inserted code. */ else if (repeat_max != repeat_min) { #ifdef SUPPORT_UTF8 if (utf8 && c >= 128) { memcpy(code, utf8_char, c & 7); code += c & 7; } else #endif *code++ = c; if (prop_type >= 0) *code++ = prop_type; repeat_max -= repeat_min; *code++ = OP_UPTO + repeat_type; PUT2INC(code, 0, repeat_max); } } /* The character or character type itself comes last in all cases. */ #ifdef SUPPORT_UTF8 if (utf8 && c >= 128) { memcpy(code, utf8_char, c & 7); code += c & 7; } else #endif *code++ = c; /* For a repeated Unicode property match, there is an extra byte that defines the required property. */ #ifdef SUPPORT_UCP if (prop_type >= 0) *code++ = prop_type; #endif } /* If previous was a character class or a back reference, we put the repeat stuff after it, but just skip the item if the repeat was {0,0}. */ else if (*previous == OP_CLASS || *previous == OP_NCLASS || #ifdef SUPPORT_UTF8 *previous == OP_XCLASS || #endif *previous == OP_REF) { if (repeat_max == 0) { code = previous; goto END_REPEAT; } /* All real repeats make it impossible to handle partial matching (maybe one day we will be able to remove this restriction). */ if (repeat_max != 1) cd->nopartial = TRUE; if (repeat_min == 0 && repeat_max == -1) *code++ = OP_CRSTAR + repeat_type; else if (repeat_min == 1 && repeat_max == -1) *code++ = OP_CRPLUS + repeat_type; else if (repeat_min == 0 && repeat_max == 1) *code++ = OP_CRQUERY + repeat_type; else { *code++ = OP_CRRANGE + repeat_type; PUT2INC(code, 0, repeat_min); if (repeat_max == -1) repeat_max = 0; /* 2-byte encoding for max */ PUT2INC(code, 0, repeat_max); } } /* If previous was a bracket group, we may have to replicate it in certain cases. */ else if (*previous >= OP_BRA || *previous == OP_ONCE || *previous == OP_COND) { register int i; int ketoffset = 0; int len = code - previous; uschar *bralink = NULL; /* If the maximum repeat count is unlimited, find the end of the bracket by scanning through from the start, and compute the offset back to it from the current code pointer. There may be an OP_OPT setting following the final KET, so we can't find the end just by going back from the code pointer. */ if (repeat_max == -1) { register uschar *ket = previous; do ket += GET(ket, 1); while (*ket != OP_KET); ketoffset = code - ket; } /* The case of a zero minimum is special because of the need to stick OP_BRAZERO in front of it, and because the group appears once in the data, whereas in other cases it appears the minimum number of times. For this reason, it is simplest to treat this case separately, as otherwise the code gets far too messy. There are several special subcases when the minimum is zero. */ if (repeat_min == 0) { /* If the maximum is also zero, we just omit the group from the output altogether. */ if (repeat_max == 0) { code = previous; goto END_REPEAT; } /* If the maximum is 1 or unlimited, we just have to stick in the BRAZERO and do no more at this point. However, we do need to adjust any OP_RECURSE calls inside the group that refer to the group itself or any internal group, because the offset is from the start of the whole regex. Temporarily terminate the pattern while doing this. */ if (repeat_max <= 1) { *code = OP_END; adjust_recurse(previous, 1, utf8, cd); memmove(previous+1, previous, len); code++; *previous++ = OP_BRAZERO + repeat_type; } /* If the maximum is greater than 1 and limited, we have to replicate in a nested fashion, sticking OP_BRAZERO before each set of brackets. The first one has to be handled carefully because it's the original copy, which has to be moved up. The remainder can be handled by code that is common with the non-zero minimum case below. We have to adjust the value or repeat_max, since one less copy is required. Once again, we may have to adjust any OP_RECURSE calls inside the group. */ else { int offset; *code = OP_END; adjust_recurse(previous, 2 + LINK_SIZE, utf8, cd); memmove(previous + 2 + LINK_SIZE, previous, len); code += 2 + LINK_SIZE; *previous++ = OP_BRAZERO + repeat_type; *previous++ = OP_BRA; /* We chain together the bracket offset fields that have to be filled in later when the ends of the brackets are reached. */ offset = (bralink == NULL)? 0 : previous - bralink; bralink = previous; PUTINC(previous, 0, offset); } repeat_max--; } /* If the minimum is greater than zero, replicate the group as many times as necessary, and adjust the maximum to the number of subsequent copies that we need. If we set a first char from the group, and didn't set a required char, copy the latter from the former. */ else { if (repeat_min > 1) { if (groupsetfirstbyte && reqbyte < 0) reqbyte = firstbyte; for (i = 1; i < repeat_min; i++) { memcpy(code, previous, len); code += len; } } if (repeat_max > 0) repeat_max -= repeat_min; } /* This code is common to both the zero and non-zero minimum cases. If the maximum is limited, it replicates the group in a nested fashion, remembering the bracket starts on a stack. In the case of a zero minimum, the first one was set up above. In all cases the repeat_max now specifies the number of additional copies needed. */ if (repeat_max >= 0) { for (i = repeat_max - 1; i >= 0; i--) { *code++ = OP_BRAZERO + repeat_type; /* All but the final copy start a new nesting, maintaining the chain of brackets outstanding. */ if (i != 0) { int offset; *code++ = OP_BRA; offset = (bralink == NULL)? 0 : code - bralink; bralink = code; PUTINC(code, 0, offset); } memcpy(code, previous, len); code += len; } /* Now chain through the pending brackets, and fill in their length fields (which are holding the chain links pro tem). */ while (bralink != NULL) { int oldlinkoffset; int offset = code - bralink + 1; uschar *bra = code - offset; oldlinkoffset = GET(bra, 1); bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset; *code++ = OP_KET; PUTINC(code, 0, offset); PUT(bra, 1, offset); } } /* If the maximum is unlimited, set a repeater in the final copy. We can't just offset backwards from the current code point, because we don't know if there's been an options resetting after the ket. The correct offset was computed above. */ else code[-ketoffset] = OP_KETRMAX + repeat_type; } /* Else there's some kind of shambles */ else { *errorptr = ERR11; goto FAILED; } /* If the character following a repeat is '+', we wrap the entire repeated item inside OP_ONCE brackets. This is just syntactic sugar, taken from Sun's Java package. The repeated item starts at tempcode, not at previous, which might be the first part of a string whose (former) last char we repeated. However, we don't support '+' after a greediness '?'. */ if (possessive_quantifier) { int len = code - tempcode; memmove(tempcode + 1+LINK_SIZE, tempcode, len); code += 1 + LINK_SIZE; len += 1 + LINK_SIZE; tempcode[0] = OP_ONCE; *code++ = OP_KET; PUTINC(code, 0, len); PUT(tempcode, 1, len); } /* In all case we no longer have a previous item. We also set the "follows varying string" flag for subsequently encountered reqbytes if it isn't already set and we have just passed a varying length item. */ END_REPEAT: previous = NULL; cd->req_varyopt |= reqvary; break; /* Start of nested bracket sub-expression, or comment or lookahead or lookbehind or option setting or condition. First deal with special things that can come after a bracket; all are introduced by ?, and the appearance of any of them means that this is not a referencing group. They were checked for validity in the first pass over the string, so we don't have to check for syntax errors here. */ case '(': newoptions = options; skipbytes = 0; if (*(++ptr) == '?') { int set, unset; int *optset; switch (*(++ptr)) { case '#': /* Comment; skip to ket */ ptr++; while (*ptr != ')') ptr++; continue; case ':': /* Non-extracting bracket */ bravalue = OP_BRA; ptr++; break; case '(': bravalue = OP_COND; /* Conditional group */ /* Condition to test for recursion */ if (ptr[1] == 'R') { code[1+LINK_SIZE] = OP_CREF; PUT2(code, 2+LINK_SIZE, CREF_RECURSE); skipbytes = 3; ptr += 3; } /* Condition to test for a numbered subpattern match. We know that if a digit follows ( then there will just be digits until ) because the syntax was checked in the first pass. */ else if ((digitab[ptr[1]] && ctype_digit) != 0) { int condref; /* Don't amalgamate; some compilers */ condref = *(++ptr) - '0'; /* grumble at autoincrement in declaration */ while (*(++ptr) != ')') condref = condref*10 + *ptr - '0'; if (condref == 0) { *errorptr = ERR35; goto FAILED; } ptr++; code[1+LINK_SIZE] = OP_CREF; PUT2(code, 2+LINK_SIZE, condref); skipbytes = 3; } /* For conditions that are assertions, we just fall through, having set bravalue above. */ break; case '=': /* Positive lookahead */ bravalue = OP_ASSERT; ptr++; break; case '!': /* Negative lookahead */ bravalue = OP_ASSERT_NOT; ptr++; break; case '<': /* Lookbehinds */ switch (*(++ptr)) { case '=': /* Positive lookbehind */ bravalue = OP_ASSERTBACK; ptr++; break; case '!': /* Negative lookbehind */ bravalue = OP_ASSERTBACK_NOT; ptr++; break; } break; case '>': /* One-time brackets */ bravalue = OP_ONCE; ptr++; break; case 'C': /* Callout - may be followed by digits; */ previous_callout = code; /* Save for later completion */ after_manual_callout = 1; /* Skip one item before completing */ *code++ = OP_CALLOUT; /* Already checked that the terminating */ { /* closing parenthesis is present. */ int n = 0; while ((digitab[*(++ptr)] & ctype_digit) != 0) n = n * 10 + *ptr - '0'; if (n > 255) { *errorptr = ERR38; goto FAILED; } *code++ = n; PUT(code, 0, ptr - cd->start_pattern + 1); /* Pattern offset */ PUT(code, LINK_SIZE, 0); /* Default length */ code += 2 * LINK_SIZE; } previous = NULL; continue; case 'P': /* Named subpattern handling */ if (*(++ptr) == '<') /* Definition */ { int i, namelen; uschar *slot = cd->name_table; const uschar *name; /* Don't amalgamate; some compilers */ name = ++ptr; /* grumble at autoincrement in declaration */ while (*ptr++ != '>'); namelen = ptr - name - 1; for (i = 0; i < cd->names_found; i++) { int crc = memcmp(name, slot+2, namelen); if (crc == 0) { if (slot[2+namelen] == 0) { *errorptr = ERR43; goto FAILED; } crc = -1; /* Current name is substring */ } if (crc < 0) { memmove(slot + cd->name_entry_size, slot, (cd->names_found - i) * cd->name_entry_size); break; } slot += cd->name_entry_size; } PUT2(slot, 0, *brackets + 1); memcpy(slot + 2, name, namelen); slot[2+namelen] = 0; cd->names_found++; goto NUMBERED_GROUP; } if (*ptr == '=' || *ptr == '>') /* Reference or recursion */ { int i, namelen; int type = *ptr++; const uschar *name = ptr; uschar *slot = cd->name_table; while (*ptr != ')') ptr++; namelen = ptr - name; for (i = 0; i < cd->names_found; i++) { if (strncmp((char *)name, (char *)slot+2, namelen) == 0) break; slot += cd->name_entry_size; } if (i >= cd->names_found) { *errorptr = ERR15; goto FAILED; } recno = GET2(slot, 0); if (type == '>') goto HANDLE_RECURSION; /* A few lines below */ /* Back reference */ previous = code; *code++ = OP_REF; PUT2INC(code, 0, recno); cd->backref_map |= (recno < 32)? (1 << recno) : 1; if (recno > cd->top_backref) cd->top_backref = recno; continue; } /* Should never happen */ break; case 'R': /* Pattern recursion */ ptr++; /* Same as (?0) */ /* Fall through */ /* Recursion or "subroutine" call */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { const uschar *called; recno = 0; while((digitab[*ptr] & ctype_digit) != 0) recno = recno * 10 + *ptr++ - '0'; /* Come here from code above that handles a named recursion */ HANDLE_RECURSION: previous = code; /* Find the bracket that is being referenced. Temporarily end the regex in case it doesn't exist. */ *code = OP_END; called = (recno == 0)? cd->start_code : find_bracket(cd->start_code, utf8, recno); if (called == NULL) { *errorptr = ERR15; goto FAILED; } /* If the subpattern is still open, this is a recursive call. We check to see if this is a left recursion that could loop for ever, and diagnose that case. */ if (GET(called, 1) == 0 && could_be_empty(called, code, bcptr, utf8)) { *errorptr = ERR40; goto FAILED; } /* Insert the recursion/subroutine item */ *code = OP_RECURSE; PUT(code, 1, called - cd->start_code); code += 1 + LINK_SIZE; } continue; /* Character after (? not specially recognized */ default: /* Option setting */ set = unset = 0; optset = &set; while (*ptr != ')' && *ptr != ':') { switch (*ptr++) { case '-': optset = &unset; break; case 'i': *optset |= PCRE_CASELESS; break; case 'm': *optset |= PCRE_MULTILINE; break; case 's': *optset |= PCRE_DOTALL; break; case 'x': *optset |= PCRE_EXTENDED; break; case 'U': *optset |= PCRE_UNGREEDY; break; case 'X': *optset |= PCRE_EXTRA; break; } } /* Set up the changed option bits, but don't change anything yet. */ newoptions = (options | set) & (~unset); /* If the options ended with ')' this is not the start of a nested group with option changes, so the options change at this level. Compile code to change the ims options if this setting actually changes any of them. We also pass the new setting back so that it can be put at the start of any following branches, and when this group ends (if we are in a group), a resetting item can be compiled. Note that if this item is right at the start of the pattern, the options will have been abstracted and made global, so there will be no change to compile. */ if (*ptr == ')') { if ((options & PCRE_IMS) != (newoptions & PCRE_IMS)) { *code++ = OP_OPT; *code++ = newoptions & PCRE_IMS; } /* Change options at this level, and pass them back for use in subsequent branches. Reset the greedy defaults and the case value for firstbyte and reqbyte. */ *optionsptr = options = newoptions; greedy_default = ((newoptions & PCRE_UNGREEDY) != 0); greedy_non_default = greedy_default ^ 1; req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS : 0; previous = NULL; /* This item can't be repeated */ continue; /* It is complete */ } /* If the options ended with ':' we are heading into a nested group with possible change of options. Such groups are non-capturing and are not assertions of any kind. All we need to do is skip over the ':'; the newoptions value is handled below. */ bravalue = OP_BRA; ptr++; } } /* If PCRE_NO_AUTO_CAPTURE is set, all unadorned brackets become non-capturing and behave like (?:...) brackets */ else if ((options & PCRE_NO_AUTO_CAPTURE) != 0) { bravalue = OP_BRA; } /* Else we have a referencing group; adjust the opcode. If the bracket number is greater than EXTRACT_BASIC_MAX, we set the opcode one higher, and arrange for the true number to follow later, in an OP_BRANUMBER item. */ else { NUMBERED_GROUP: if (++(*brackets) > EXTRACT_BASIC_MAX) { bravalue = OP_BRA + EXTRACT_BASIC_MAX + 1; code[1+LINK_SIZE] = OP_BRANUMBER; PUT2(code, 2+LINK_SIZE, *brackets); skipbytes = 3; } else bravalue = OP_BRA + *brackets; } /* Process nested bracketed re. Assertions may not be repeated, but other kinds can be. We copy code into a non-register variable in order to be able to pass its address because some compilers complain otherwise. Pass in a new setting for the ims options if they have changed. */ previous = (bravalue >= OP_ONCE)? code : NULL; *code = bravalue; tempcode = code; tempreqvary = cd->req_varyopt; /* Save value before bracket */ if (!compile_regex( newoptions, /* The complete new option state */ options & PCRE_IMS, /* The previous ims option state */ brackets, /* Extracting bracket count */ &tempcode, /* Where to put code (updated) */ &ptr, /* Input pointer (updated) */ errorptr, /* Where to put an error message */ (bravalue == OP_ASSERTBACK || bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */ skipbytes, /* Skip over OP_COND/OP_BRANUMBER */ &subfirstbyte, /* For possible first char */ &subreqbyte, /* For possible last char */ bcptr, /* Current branch chain */ cd)) /* Tables block */ goto FAILED; /* At the end of compiling, code is still pointing to the start of the group, while tempcode has been updated to point past the end of the group and any option resetting that may follow it. The pattern pointer (ptr) is on the bracket. */ /* If this is a conditional bracket, check that there are no more than two branches in the group. */ else if (bravalue == OP_COND) { uschar *tc = code; condcount = 0; do { condcount++; tc += GET(tc,1); } while (*tc != OP_KET); if (condcount > 2) { *errorptr = ERR27; goto FAILED; } /* If there is just one branch, we must not make use of its firstbyte or reqbyte, because this is equivalent to an empty second branch. */ if (condcount == 1) subfirstbyte = subreqbyte = REQ_NONE; } /* Handle updating of the required and first characters. Update for normal brackets of all kinds, and conditions with two branches (see code above). If the bracket is followed by a quantifier with zero repeat, we have to back off. Hence the definition of zeroreqbyte and zerofirstbyte outside the main loop so that they can be accessed for the back off. */ zeroreqbyte = reqbyte; zerofirstbyte = firstbyte; groupsetfirstbyte = FALSE; if (bravalue >= OP_BRA || bravalue == OP_ONCE || bravalue == OP_COND) { /* If we have not yet set a firstbyte in this branch, take it from the subpattern, remembering that it was set here so that a repeat of more than one can replicate it as reqbyte if necessary. If the subpattern has no firstbyte, set "none" for the whole branch. In both cases, a zero repeat forces firstbyte to "none". */ if (firstbyte == REQ_UNSET) { if (subfirstbyte >= 0) { firstbyte = subfirstbyte; groupsetfirstbyte = TRUE; } else firstbyte = REQ_NONE; zerofirstbyte = REQ_NONE; } /* If firstbyte was previously set, convert the subpattern's firstbyte into reqbyte if there wasn't one, using the vary flag that was in existence beforehand. */ else if (subfirstbyte >= 0 && subreqbyte < 0) subreqbyte = subfirstbyte | tempreqvary; /* If the subpattern set a required byte (or set a first byte that isn't really the first byte - see above), set it. */ if (subreqbyte >= 0) reqbyte = subreqbyte; } /* For a forward assertion, we take the reqbyte, if set. This can be helpful if the pattern that follows the assertion doesn't set a different char. For example, it's useful for /(?=abcde).+/. We can't set firstbyte for an assertion, however because it leads to incorrect effect for patterns such as /(?=a)a.+/ when the "real" "a" would then become a reqbyte instead of a firstbyte. This is overcome by a scan at the end if there's no firstbyte, looking for an asserted first char. */ else if (bravalue == OP_ASSERT && subreqbyte >= 0) reqbyte = subreqbyte; /* Now update the main code pointer to the end of the group. */ code = tempcode; /* Error if hit end of pattern */ if (*ptr != ')') { *errorptr = ERR14; goto FAILED; } break; /* Check \ for being a real metacharacter; if not, fall through and handle it as a data character at the start of a string. Escape items are checked for validity in the pre-compiling pass. */ case '\\': tempptr = ptr; c = check_escape(&ptr, errorptr, *brackets, options, FALSE); /* Handle metacharacters introduced by \. For ones like \d, the ESC_ values are arranged to be the negation of the corresponding OP_values. For the back references, the values are ESC_REF plus the reference number. Only back references and those types that consume a character may be repeated. We can test for values between ESC_b and ESC_Z for the latter; this may have to change if any new ones are ever created. */ if (c < 0) { if (-c == ESC_Q) /* Handle start of quoted string */ { if (ptr[1] == '\\' && ptr[2] == 'E') ptr += 2; /* avoid empty string */ else inescq = TRUE; continue; } /* For metasequences that actually match a character, we disable the setting of a first character if it hasn't already been set. */ if (firstbyte == REQ_UNSET && -c > ESC_b && -c < ESC_Z) firstbyte = REQ_NONE; /* Set values to reset to if this is followed by a zero repeat. */ zerofirstbyte = firstbyte; zeroreqbyte = reqbyte; /* Back references are handled specially */ if (-c >= ESC_REF) { int number = -c - ESC_REF; previous = code; *code++ = OP_REF; PUT2INC(code, 0, number); } /* So are Unicode property matches, if supported. We know that get_ucp won't fail because it was tested in the pre-pass. */ #ifdef SUPPORT_UCP else if (-c == ESC_P || -c == ESC_p) { BOOL negated; int value = get_ucp(&ptr, &negated, errorptr); previous = code; *code++ = ((-c == ESC_p) != negated)? OP_PROP : OP_NOTPROP; *code++ = value; } #endif /* For the rest, we can obtain the OP value by negating the escape value */ else { previous = (-c > ESC_b && -c < ESC_Z)? code : NULL; *code++ = -c; } continue; } /* We have a data character whose value is in c. In UTF-8 mode it may have a value > 127. We set its representation in the length/buffer, and then handle it as a data character. */ #ifdef SUPPORT_UTF8 if (utf8 && c > 127) mclength = ord2utf8(c, mcbuffer); else #endif { mcbuffer[0] = c; mclength = 1; } goto ONE_CHAR; /* Handle a literal character. It is guaranteed not to be whitespace or # when the extended flag is set. If we are in UTF-8 mode, it may be a multi-byte literal character. */ default: NORMAL_CHAR: mclength = 1; mcbuffer[0] = c; #ifdef SUPPORT_UTF8 if (utf8 && (c & 0xc0) == 0xc0) { while ((ptr[1] & 0xc0) == 0x80) mcbuffer[mclength++] = *(++ptr); } #endif /* At this point we have the character's bytes in mcbuffer, and the length in mclength. When not in UTF-8 mode, the length is always 1. */ ONE_CHAR: previous = code; *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARNC : OP_CHAR; for (c = 0; c < mclength; c++) *code++ = mcbuffer[c]; /* Set the first and required bytes appropriately. If no previous first byte, set it from this character, but revert to none on a zero repeat. Otherwise, leave the firstbyte value alone, and don't change it on a zero repeat. */ if (firstbyte == REQ_UNSET) { zerofirstbyte = REQ_NONE; zeroreqbyte = reqbyte; /* If the character is more than one byte long, we can set firstbyte only if it is not to be matched caselessly. */ if (mclength == 1 || req_caseopt == 0) { firstbyte = mcbuffer[0] | req_caseopt; if (mclength != 1) reqbyte = code[-1] | cd->req_varyopt; } else firstbyte = reqbyte = REQ_NONE; } /* firstbyte was previously set; we can set reqbyte only the length is 1 or the matching is caseful. */ else { zerofirstbyte = firstbyte; zeroreqbyte = reqbyte; if (mclength == 1 || req_caseopt == 0) reqbyte = code[-1] | req_caseopt | cd->req_varyopt; } break; /* End of literal character handling */ } } /* end of big loop */ /* Control never reaches here by falling through, only by a goto for all the error states. Pass back the position in the pattern so that it can be displayed to the user for diagnosing the error. */ FAILED: *ptrptr = ptr; return FALSE; } /************************************************* * Compile sequence of alternatives * *************************************************/ /* On entry, ptr is pointing past the bracket character, but on return it points to the closing bracket, or vertical bar, or end of string. The code variable is pointing at the byte into which the BRA operator has been stored. If the ims options are changed at the start (for a (?ims: group) or during any branch, we need to insert an OP_OPT item at the start of every following branch to ensure they get set correctly at run time, and also pass the new options into every subsequent branch compile. Argument: options option bits, including any changes for this subpattern oldims previous settings of ims option bits brackets -> int containing the number of extracting brackets used codeptr -> the address of the current code pointer ptrptr -> the address of the current pattern pointer errorptr -> pointer to error message lookbehind TRUE if this is a lookbehind assertion skipbytes skip this many bytes at start (for OP_COND, OP_BRANUMBER) firstbyteptr place to put the first required character, or a negative number reqbyteptr place to put the last required character, or a negative number bcptr pointer to the chain of currently open branches cd points to the data block with tables pointers etc. Returns: TRUE on success */ static BOOL compile_regex(int options, int oldims, int *brackets, uschar **codeptr, const uschar **ptrptr, const char **errorptr, BOOL lookbehind, int skipbytes, int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, compile_data *cd) { const uschar *ptr = *ptrptr; uschar *code = *codeptr; uschar *last_branch = code; uschar *start_bracket = code; uschar *reverse_count = NULL; int firstbyte, reqbyte; int branchfirstbyte, branchreqbyte; branch_chain bc; bc.outer = bcptr; bc.current = code; firstbyte = reqbyte = REQ_UNSET; /* Offset is set zero to mark that this bracket is still open */ PUT(code, 1, 0); code += 1 + LINK_SIZE + skipbytes; /* Loop for each alternative branch */ for (;;) { /* Handle a change of ims options at the start of the branch */ if ((options & PCRE_IMS) != oldims) { *code++ = OP_OPT; *code++ = options & PCRE_IMS; } /* Set up dummy OP_REVERSE if lookbehind assertion */ if (lookbehind) { *code++ = OP_REVERSE; reverse_count = code; PUTINC(code, 0, 0); } /* Now compile the branch */ if (!compile_branch(&options, brackets, &code, &ptr, errorptr, &branchfirstbyte, &branchreqbyte, &bc, cd)) { *ptrptr = ptr; return FALSE; } /* If this is the first branch, the firstbyte and reqbyte values for the branch become the values for the regex. */ if (*last_branch != OP_ALT) { firstbyte = branchfirstbyte; reqbyte = branchreqbyte; } /* If this is not the first branch, the first char and reqbyte have to match the values from all the previous branches, except that if the previous value for reqbyte didn't have REQ_VARY set, it can still match, and we set REQ_VARY for the regex. */ else { /* If we previously had a firstbyte, but it doesn't match the new branch, we have to abandon the firstbyte for the regex, but if there was previously no reqbyte, it takes on the value of the old firstbyte. */ if (firstbyte >= 0 && firstbyte != branchfirstbyte) { if (reqbyte < 0) reqbyte = firstbyte; firstbyte = REQ_NONE; } /* If we (now or from before) have no firstbyte, a firstbyte from the branch becomes a reqbyte if there isn't a branch reqbyte. */ if (firstbyte < 0 && branchfirstbyte >= 0 && branchreqbyte < 0) branchreqbyte = branchfirstbyte; /* Now ensure that the reqbytes match */ if ((reqbyte & ~REQ_VARY) != (branchreqbyte & ~REQ_VARY)) reqbyte = REQ_NONE; else reqbyte |= branchreqbyte; /* To "or" REQ_VARY */ } /* If lookbehind, check that this branch matches a fixed-length string, and put the length into the OP_REVERSE item. Temporarily mark the end of the branch with OP_END. */ if (lookbehind) { int length; *code = OP_END; length = find_fixedlength(last_branch, options); DPRINTF(("fixed length = %d\n", length)); if (length < 0) { *errorptr = (length == -2)? ERR36 : ERR25; *ptrptr = ptr; return FALSE; } PUT(reverse_count, 0, length); } /* Reached end of expression, either ')' or end of pattern. Go back through the alternative branches and reverse the chain of offsets, with the field in the BRA item now becoming an offset to the first alternative. If there are no alternatives, it points to the end of the group. The length in the terminating ket is always the length of the whole bracketed item. If any of the ims options were changed inside the group, compile a resetting op-code following, except at the very end of the pattern. Return leaving the pointer at the terminating char. */ if (*ptr != '|') { int length = code - last_branch; do { int prev_length = GET(last_branch, 1); PUT(last_branch, 1, length); length = prev_length; last_branch -= length; } while (length > 0); /* Fill in the ket */ *code = OP_KET; PUT(code, 1, code - start_bracket); code += 1 + LINK_SIZE; /* Resetting option if needed */ if ((options & PCRE_IMS) != oldims && *ptr == ')') { *code++ = OP_OPT; *code++ = oldims; } /* Set values to pass back */ *codeptr = code; *ptrptr = ptr; *firstbyteptr = firstbyte; *reqbyteptr = reqbyte; return TRUE; } /* Another branch follows; insert an "or" node. Its length field points back to the previous branch while the bracket remains open. At the end the chain is reversed. It's done like this so that the start of the bracket has a zero offset until it is closed, making it possible to detect recursion. */ *code = OP_ALT; PUT(code, 1, code - last_branch); bc.current = last_branch = code; code += 1 + LINK_SIZE; ptr++; } /* Control never reaches here */ } /************************************************* * Check for anchored expression * *************************************************/ /* Try to find out if this is an anchored regular expression. Consider each alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then it's anchored. However, if this is a multiline pattern, then only OP_SOD counts, since OP_CIRC can match in the middle. We can also consider a regex to be anchored if OP_SOM starts all its branches. This is the code for \G, which means "match at start of match position, taking into account the match offset". A branch is also implicitly anchored if it starts with .* and DOTALL is set, because that will try the rest of the pattern at all possible matching points, so there is no point trying again.... er .... .... except when the .* appears inside capturing parentheses, and there is a subsequent back reference to those parentheses. We haven't enough information to catch that case precisely. At first, the best we could do was to detect when .* was in capturing brackets and the highest back reference was greater than or equal to that level. However, by keeping a bitmap of the first 31 back references, we can catch some of the more common cases more precisely. Arguments: code points to start of expression (the bracket) options points to the options setting bracket_map a bitmap of which brackets we are inside while testing; this handles up to substring 31; after that we just have to take the less precise approach backref_map the back reference bitmap Returns: TRUE or FALSE */ static BOOL is_anchored(register const uschar *code, int *options, unsigned int bracket_map, unsigned int backref_map) { do { const uschar *scode = first_significant_code(code + 1+LINK_SIZE, options, PCRE_MULTILINE, FALSE); register int op = *scode; /* Capturing brackets */ if (op > OP_BRA) { int new_map; op -= OP_BRA; if (op > EXTRACT_BASIC_MAX) op = GET2(scode, 2+LINK_SIZE); new_map = bracket_map | ((op < 32)? (1 << op) : 1); if (!is_anchored(scode, options, new_map, backref_map)) return FALSE; } /* Other brackets */ else if (op == OP_BRA || op == OP_ASSERT || op == OP_ONCE || op == OP_COND) { if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE; } /* .* is not anchored unless DOTALL is set and it isn't in brackets that are or may be referenced. */ else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR) && (*options & PCRE_DOTALL) != 0) { if (scode[1] != OP_ANY || (bracket_map & backref_map) != 0) return FALSE; } /* Check for explicit anchoring */ else if (op != OP_SOD && op != OP_SOM && ((*options & PCRE_MULTILINE) != 0 || op != OP_CIRC)) return FALSE; code += GET(code, 1); } while (*code == OP_ALT); /* Loop for each alternative */ return TRUE; } /************************************************* * Check for starting with ^ or .* * *************************************************/ /* This is called to find out if every branch starts with ^ or .* so that "first char" processing can be done to speed things up in multiline matching and for non-DOTALL patterns that start with .* (which must start at the beginning or after \n). As in the case of is_anchored() (see above), we have to take account of back references to capturing brackets that contain .* because in that case we can't make the assumption. Arguments: code points to start of expression (the bracket) bracket_map a bitmap of which brackets we are inside while testing; this handles up to substring 31; after that we just have to take the less precise approach backref_map the back reference bitmap Returns: TRUE or FALSE */ static BOOL is_startline(const uschar *code, unsigned int bracket_map, unsigned int backref_map) { do { const uschar *scode = first_significant_code(code + 1+LINK_SIZE, NULL, 0, FALSE); register int op = *scode; /* Capturing brackets */ if (op > OP_BRA) { int new_map; op -= OP_BRA; if (op > EXTRACT_BASIC_MAX) op = GET2(scode, 2+LINK_SIZE); new_map = bracket_map | ((op < 32)? (1 << op) : 1); if (!is_startline(scode, new_map, backref_map)) return FALSE; } /* Other brackets */ else if (op == OP_BRA || op == OP_ASSERT || op == OP_ONCE || op == OP_COND) { if (!is_startline(scode, bracket_map, backref_map)) return FALSE; } /* .* means "start at start or after \n" if it isn't in brackets that may be referenced. */ else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR) { if (scode[1] != OP_ANY || (bracket_map & backref_map) != 0) return FALSE; } /* Check for explicit circumflex */ else if (op != OP_CIRC) return FALSE; /* Move on to the next alternative */ code += GET(code, 1); } while (*code == OP_ALT); /* Loop for each alternative */ return TRUE; } /************************************************* * Check for asserted fixed first char * *************************************************/ /* During compilation, the "first char" settings from forward assertions are discarded, because they can cause conflicts with actual literals that follow. However, if we end up without a first char setting for an unanchored pattern, it is worth scanning the regex to see if there is an initial asserted first char. If all branches start with the same asserted char, or with a bracket all of whose alternatives start with the same asserted char (recurse ad lib), then we return that char, otherwise -1. Arguments: code points to start of expression (the bracket) options pointer to the options (used to check casing changes) inassert TRUE if in an assertion Returns: -1 or the fixed first char */ static int find_firstassertedchar(const uschar *code, int *options, BOOL inassert) { register int c = -1; do { int d; const uschar *scode = first_significant_code(code + 1+LINK_SIZE, options, PCRE_CASELESS, TRUE); register int op = *scode; if (op >= OP_BRA) op = OP_BRA; switch(op) { default: return -1; case OP_BRA: case OP_ASSERT: case OP_ONCE: case OP_COND: if ((d = find_firstassertedchar(scode, options, op == OP_ASSERT)) < 0) return -1; if (c < 0) c = d; else if (c != d) return -1; break; case OP_EXACT: /* Fall through */ scode += 2; case OP_CHAR: case OP_CHARNC: case OP_PLUS: case OP_MINPLUS: if (!inassert) return -1; if (c < 0) { c = scode[1]; if ((*options & PCRE_CASELESS) != 0) c |= REQ_CASELESS; } else if (c != scode[1]) return -1; break; } code += GET(code, 1); } while (*code == OP_ALT); return c; } #ifdef SUPPORT_UTF8 /************************************************* * Validate a UTF-8 string * *************************************************/ /* This function is called (optionally) at the start of compile or match, to validate that a supposed UTF-8 string is actually valid. The early check means that subsequent code can assume it is dealing with a valid string. The check can be turned off for maximum performance, but then consequences of supplying an invalid string are then undefined. Arguments: string points to the string length length of string, or -1 if the string is zero-terminated Returns: < 0 if the string is a valid UTF-8 string >= 0 otherwise; the value is the offset of the bad byte */ static int valid_utf8(const uschar *string, int length) { register const uschar *p; if (length < 0) { for (p = string; *p != 0; p++); length = p - string; } for (p = string; length-- > 0; p++) { register int ab; register int c = *p; if (c < 128) continue; if ((c & 0xc0) != 0xc0) return p - string; ab = utf8_table4[c & 0x3f]; /* Number of additional bytes */ if (length < ab) return p - string; length -= ab; /* Check top bits in the second byte */ if ((*(++p) & 0xc0) != 0x80) return p - string; /* Check for overlong sequences for each different length */ switch (ab) { /* Check for xx00 000x */ case 1: if ((c & 0x3e) == 0) return p - string; continue; /* We know there aren't any more bytes to check */ /* Check for 1110 0000, xx0x xxxx */ case 2: if (c == 0xe0 && (*p & 0x20) == 0) return p - string; break; /* Check for 1111 0000, xx00 xxxx */ case 3: if (c == 0xf0 && (*p & 0x30) == 0) return p - string; break; /* Check for 1111 1000, xx00 0xxx */ case 4: if (c == 0xf8 && (*p & 0x38) == 0) return p - string; break; /* Check for leading 0xfe or 0xff, and then for 1111 1100, xx00 00xx */ case 5: if (c == 0xfe || c == 0xff || (c == 0xfc && (*p & 0x3c) == 0)) return p - string; break; } /* Check for valid bytes after the 2nd, if any; all must start 10 */ while (--ab > 0) { if ((*(++p) & 0xc0) != 0x80) return p - string; } } return -1; } #endif /************************************************* * Compile a Regular Expression * *************************************************/ /* This function takes a string and returns a pointer to a block of store holding a compiled version of the expression. Arguments: pattern the regular expression options various option bits errorptr pointer to pointer to error text erroroffset ptr offset in pattern where error was detected tables pointer to character tables or NULL Returns: pointer to compiled data block, or NULL on error, with errorptr and erroroffset set */ EXPORT pcre * pcre_compile(const char *pattern, int options, const char **errorptr, int *erroroffset, const unsigned char *tables) { real_pcre *re; int length = 1 + LINK_SIZE; /* For initial BRA plus length */ int c, firstbyte, reqbyte; int bracount = 0; int branch_extra = 0; int branch_newextra; int item_count = -1; int name_count = 0; int max_name_size = 0; int lastitemlength = 0; #ifdef SUPPORT_UTF8 BOOL utf8; BOOL class_utf8; #endif BOOL inescq = FALSE; unsigned int brastackptr = 0; size_t size; uschar *code; const uschar *codestart; const uschar *ptr; compile_data compile_block; int brastack[BRASTACK_SIZE]; uschar bralenstack[BRASTACK_SIZE]; /* We can't pass back an error message if errorptr is NULL; I guess the best we can do is just return NULL. */ if (errorptr == NULL) return NULL; *errorptr = NULL; /* However, we can give a message for this error */ if (erroroffset == NULL) { *errorptr = ERR16; return NULL; } *erroroffset = 0; /* Can't support UTF8 unless PCRE has been compiled to include the code. */ #ifdef SUPPORT_UTF8 utf8 = (options & PCRE_UTF8) != 0; if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0 && (*erroroffset = valid_utf8((uschar *)pattern, -1)) >= 0) { *errorptr = ERR44; return NULL; } #else if ((options & PCRE_UTF8) != 0) { *errorptr = ERR32; return NULL; } #endif if ((options & ~PUBLIC_OPTIONS) != 0) { *errorptr = ERR17; return NULL; } /* Set up pointers to the individual character tables */ if (tables == NULL) tables = pcre_default_tables; compile_block.lcc = tables + lcc_offset; compile_block.fcc = tables + fcc_offset; compile_block.cbits = tables + cbits_offset; compile_block.ctypes = tables + ctypes_offset; /* Maximum back reference and backref bitmap. This is updated for numeric references during the first pass, but for named references during the actual compile pass. The bitmap records up to 31 back references to help in deciding whether (.*) can be treated as anchored or not. */ compile_block.top_backref = 0; compile_block.backref_map = 0; /* Reflect pattern for debugging output */ DPRINTF(("------------------------------------------------------------------\n")); DPRINTF(("%s\n", pattern)); /* The first thing to do is to make a pass over the pattern to compute the amount of store required to hold the compiled code. This does not have to be perfect as long as errors are overestimates. At the same time we can detect any flag settings right at the start, and extract them. Make an attempt to correct for any counted white space if an "extended" flag setting appears late in the pattern. We can't be so clever for #-comments. */ ptr = (const uschar *)(pattern - 1); while ((c = *(++ptr)) != 0) { int min, max; int class_optcount; int bracket_length; int duplength; /* If we are inside a \Q...\E sequence, all chars are literal */ if (inescq) { if ((options & PCRE_AUTO_CALLOUT) != 0) length += 2 + 2*LINK_SIZE; goto NORMAL_CHAR; } /* Otherwise, first check for ignored whitespace and comments */ if ((options & PCRE_EXTENDED) != 0) { if ((compile_block.ctypes[c] & ctype_space) != 0) continue; if (c == '#') { /* The space before the ; is to avoid a warning on a silly compiler on the Macintosh. */ while ((c = *(++ptr)) != 0 && c != NEWLINE) ; if (c == 0) break; continue; } } item_count++; /* Is zero for the first non-comment item */ /* Allow space for auto callout before every item except quantifiers. */ if ((options & PCRE_AUTO_CALLOUT) != 0 && c != '*' && c != '+' && c != '?' && (c != '{' || !is_counted_repeat(ptr + 1))) length += 2 + 2*LINK_SIZE; switch(c) { /* A backslashed item may be an escaped data character or it may be a character type. */ case '\\': c = check_escape(&ptr, errorptr, bracount, options, FALSE); if (*errorptr != NULL) goto PCRE_ERROR_RETURN; lastitemlength = 1; /* Default length of last item for repeats */ if (c >= 0) /* Data character */ { length += 2; /* For a one-byte character */ #ifdef SUPPORT_UTF8 if (utf8 && c > 127) { int i; for (i = 0; i < sizeof(utf8_table1)/sizeof(int); i++) if (c <= utf8_table1[i]) break; length += i; lastitemlength += i; } #endif continue; } /* If \Q, enter "literal" mode */ if (-c == ESC_Q) { inescq = TRUE; continue; } /* \X is supported only if Unicode property support is compiled */ #ifndef SUPPORT_UCP if (-c == ESC_X) { *errorptr = ERR45; goto PCRE_ERROR_RETURN; } #endif /* \P and \p are for Unicode properties, but only when the support has been compiled. Each item needs 2 bytes. */ else if (-c == ESC_P || -c == ESC_p) { #ifdef SUPPORT_UCP BOOL negated; length += 2; lastitemlength = 2; if (get_ucp(&ptr, &negated, errorptr) < 0) goto PCRE_ERROR_RETURN; continue; #else *errorptr = ERR45; goto PCRE_ERROR_RETURN; #endif } /* Other escapes need one byte */ length++; /* A back reference needs an additional 2 bytes, plus either one or 5 bytes for a repeat. We also need to keep the value of the highest back reference. */ if (c <= -ESC_REF) { int refnum = -c - ESC_REF; compile_block.backref_map |= (refnum < 32)? (1 << refnum) : 1; if (refnum > compile_block.top_backref) compile_block.top_backref = refnum; length += 2; /* For single back reference */ if (ptr[1] == '{' && is_counted_repeat(ptr+2)) { ptr = read_repeat_counts(ptr+2, &min, &max, errorptr); if (*errorptr != NULL) goto PCRE_ERROR_RETURN; if ((min == 0 && (max == 1 || max == -1)) || (min == 1 && max == -1)) length++; else length += 5; if (ptr[1] == '?') ptr++; } } continue; case '^': /* Single-byte metacharacters */ case '.': case '$': length++; lastitemlength = 1; continue; case '*': /* These repeats won't be after brackets; */ case '+': /* those are handled separately */ case '?': length++; goto POSESSIVE; /* A few lines below */ /* This covers the cases of braced repeats after a single char, metachar, class, or back reference. */ case '{': if (!is_counted_repeat(ptr+1)) goto NORMAL_CHAR; ptr = read_repeat_counts(ptr+1, &min, &max, errorptr); if (*errorptr != NULL) goto PCRE_ERROR_RETURN; /* These special cases just insert one extra opcode */ if ((min == 0 && (max == 1 || max == -1)) || (min == 1 && max == -1)) length++; /* These cases might insert additional copies of a preceding character. */ else { if (min != 1) { length -= lastitemlength; /* Uncount the original char or metachar */ if (min > 0) length += 3 + lastitemlength; } length += lastitemlength + ((max > 0)? 3 : 1); } if (ptr[1] == '?') ptr++; /* Needs no extra length */ POSESSIVE: /* Test for possessive quantifier */ if (ptr[1] == '+') { ptr++; length += 2 + 2*LINK_SIZE; /* Allow for atomic brackets */ } continue; /* An alternation contains an offset to the next branch or ket. If any ims options changed in the previous branch(es), and/or if we are in a lookbehind assertion, extra space will be needed at the start of the branch. This is handled by branch_extra. */ case '|': length += 1 + LINK_SIZE + branch_extra; continue; /* A character class uses 33 characters provided that all the character values are less than 256. Otherwise, it uses a bit map for low valued characters, and individual items for others. Don't worry about character types that aren't allowed in classes - they'll get picked up during the compile. A character class that contains only one single-byte character uses 2 or 3 bytes, depending on whether it is negated or not. Notice this where we can. (In UTF-8 mode we can do this only for chars < 128.) */ case '[': if (*(++ptr) == '^') { class_optcount = 10; /* Greater than one */ ptr++; } else class_optcount = 0; #ifdef SUPPORT_UTF8 class_utf8 = FALSE; #endif /* Written as a "do" so that an initial ']' is taken as data */ if (*ptr != 0) do { /* Inside \Q...\E everything is literal except \E */ if (inescq) { if (*ptr != '\\' || ptr[1] != 'E') goto GET_ONE_CHARACTER; inescq = FALSE; ptr += 1; continue; } /* Outside \Q...\E, check for escapes */ if (*ptr == '\\') { c = check_escape(&ptr, errorptr, bracount, options, TRUE); if (*errorptr != NULL) goto PCRE_ERROR_RETURN; /* \b is backspace inside a class; \X is literal */ if (-c == ESC_b) c = '\b'; else if (-c == ESC_X) c = 'X'; /* \Q enters quoting mode */ else if (-c == ESC_Q) { inescq = TRUE; continue; } /* Handle escapes that turn into characters */ if (c >= 0) goto NON_SPECIAL_CHARACTER; /* Escapes that are meta-things. The normal ones just affect the bit map, but Unicode properties require an XCLASS extended item. */ else { class_optcount = 10; /* \d, \s etc; make sure > 1 */ #ifdef SUPPORT_UTF8 if (-c == ESC_p || -c == ESC_P) { if (!class_utf8) { class_utf8 = TRUE; length += LINK_SIZE + 2; } length += 2; } #endif } } /* Check the syntax for POSIX stuff. The bits we actually handle are checked during the real compile phase. */ else if (*ptr == '[' && check_posix_syntax(ptr, &ptr, &compile_block)) { ptr++; class_optcount = 10; /* Make sure > 1 */ } /* Anything else increments the possible optimization count. We have to detect ranges here so that we can compute the number of extra ranges for caseless wide characters when UCP support is available. If there are wide characters, we are going to have to use an XCLASS, even for single characters. */ else { int d; GET_ONE_CHARACTER: #ifdef SUPPORT_UTF8 if (utf8) { int extra = 0; GETCHARLEN(c, ptr, extra); ptr += extra; } else c = *ptr; #else c = *ptr; #endif /* Come here from handling \ above when it escapes to a char value */ NON_SPECIAL_CHARACTER: class_optcount++; d = -1; if (ptr[1] == '-') { uschar const *hyptr = ptr++; if (ptr[1] == '\\') { ptr++; d = check_escape(&ptr, errorptr, bracount, options, TRUE); if (*errorptr != NULL) goto PCRE_ERROR_RETURN; if (-d == ESC_b) d = '\b'; /* backspace */ else if (-d == ESC_X) d = 'X'; /* literal X in a class */ } else if (ptr[1] != 0 && ptr[1] != ']') { ptr++; #ifdef SUPPORT_UTF8 if (utf8) { int extra = 0; GETCHARLEN(d, ptr, extra); ptr += extra; } else #endif d = *ptr; } if (d < 0) ptr = hyptr; /* go back to hyphen as data */ } /* If d >= 0 we have a range. In UTF-8 mode, if the end is > 255, or > 127 for caseless matching, we will need to use an XCLASS. */ if (d >= 0) { class_optcount = 10; /* Ensure > 1 */ if (d < c) { *errorptr = ERR8; goto PCRE_ERROR_RETURN; } #ifdef SUPPORT_UTF8 if (utf8 && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127))) { uschar buffer[6]; if (!class_utf8) /* Allow for XCLASS overhead */ { class_utf8 = TRUE; length += LINK_SIZE + 2; } #ifdef SUPPORT_UCP /* If we have UCP support, find out how many extra ranges are needed to map the other case of characters within this range. We have to mimic the range optimization here, because extending the range upwards might push d over a boundary that makes is use another byte in the UTF-8 representation. */ if ((options & PCRE_CASELESS) != 0) { int occ, ocd; int cc = c; int origd = d; while (get_othercase_range(&cc, origd, &occ, &ocd)) { if (occ >= c && ocd <= d) continue; /* Skip embedded */ if (occ < c && ocd >= c - 1) /* Extend the basic range */ { /* if there is overlap, */ c = occ; /* noting that if occ < c */ continue; /* we can't have ocd > d */ } /* because a subrange is */ if (ocd > d && occ <= d + 1) /* always shorter than */ { /* the basic range. */ d = ocd; continue; } /* An extra item is needed */ length += 1 + ord2utf8(occ, buffer) + ((occ == ocd)? 0 : ord2utf8(ocd, buffer)); } } #endif /* SUPPORT_UCP */ /* The length of the (possibly extended) range */ length += 1 + ord2utf8(c, buffer) + ord2utf8(d, buffer); } #endif /* SUPPORT_UTF8 */ } /* We have a single character. There is nothing to be done unless we are in UTF-8 mode. If the char is > 255, or 127 when caseless, we must allow for an XCL_SINGLE item, doubled for caselessness if there is UCP support. */ else { #ifdef SUPPORT_UTF8 if (utf8 && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127))) { uschar buffer[6]; class_optcount = 10; /* Ensure > 1 */ if (!class_utf8) /* Allow for XCLASS overhead */ { class_utf8 = TRUE; length += LINK_SIZE + 2; } #ifdef SUPPORT_UCP length += (((options & PCRE_CASELESS) != 0)? 2 : 1) * (1 + ord2utf8(c, buffer)); #else /* SUPPORT_UCP */ length += 1 + ord2utf8(c, buffer); #endif /* SUPPORT_UCP */ } #endif /* SUPPORT_UTF8 */ } } } while (*(++ptr) != 0 && (inescq || *ptr != ']')); /* Concludes "do" above */ if (*ptr == 0) /* Missing terminating ']' */ { *errorptr = ERR6; goto PCRE_ERROR_RETURN; } /* We can optimize when there was only one optimizable character. Repeats for positive and negated single one-byte chars are handled by the general code. Here, we handle repeats for the class opcodes. */ if (class_optcount == 1) length += 3; else { length += 33; /* A repeat needs either 1 or 5 bytes. If it is a possessive quantifier, we also need extra for wrapping the whole thing in a sub-pattern. */ if (*ptr != 0 && ptr[1] == '{' && is_counted_repeat(ptr+2)) { ptr = read_repeat_counts(ptr+2, &min, &max, errorptr); if (*errorptr != NULL) goto PCRE_ERROR_RETURN; if ((min == 0 && (max == 1 || max == -1)) || (min == 1 && max == -1)) length++; else length += 5; if (ptr[1] == '+') { ptr++; length += 2 + 2*LINK_SIZE; } else if (ptr[1] == '?') ptr++; } } continue; /* Brackets may be genuine groups or special things */ case '(': branch_newextra = 0; bracket_length = 1 + LINK_SIZE; /* Handle special forms of bracket, which all start (? */ if (ptr[1] == '?') { int set, unset; int *optset; switch (c = ptr[2]) { /* Skip over comments entirely */ case '#': ptr += 3; while (*ptr != 0 && *ptr != ')') ptr++; if (*ptr == 0) { *errorptr = ERR18; goto PCRE_ERROR_RETURN; } continue; /* Non-referencing groups and lookaheads just move the pointer on, and then behave like a non-special bracket, except that they don't increment the count of extracting brackets. Ditto for the "once only" bracket, which is in Perl from version 5.005. */ case ':': case '=': case '!': case '>': ptr += 2; break; /* (?R) specifies a recursive call to the regex, which is an extension to provide the facility which can be obtained by (?p{perl-code}) in Perl 5.6. In Perl 5.8 this has become (??{perl-code}). From PCRE 4.00, items such as (?3) specify subroutine-like "calls" to the appropriate numbered brackets. This includes both recursive and non-recursive calls. (?R) is now synonymous with (?0). */ case 'R': ptr++; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': ptr += 2; if (c != 'R') while ((digitab[*(++ptr)] & ctype_digit) != 0); if (*ptr != ')') { *errorptr = ERR29; goto PCRE_ERROR_RETURN; } length += 1 + LINK_SIZE; /* If this item is quantified, it will get wrapped inside brackets so as to use the code for quantified brackets. We jump down and use the code that handles this for real brackets. */ if (ptr[1] == '+' || ptr[1] == '*' || ptr[1] == '?' || ptr[1] == '{') { length += 2 + 2 * LINK_SIZE; /* to make bracketed */ duplength = 5 + 3 * LINK_SIZE; goto HANDLE_QUANTIFIED_BRACKETS; } continue; /* (?C) is an extension which provides "callout" - to provide a bit of the functionality of the Perl (?{...}) feature. An optional number may follow (default is zero). */ case 'C': ptr += 2; while ((digitab[*(++ptr)] & ctype_digit) != 0); if (*ptr != ')') { *errorptr = ERR39; goto PCRE_ERROR_RETURN; } length += 2 + 2*LINK_SIZE; continue; /* Named subpatterns are an extension copied from Python */ case 'P': ptr += 3; if (*ptr == '<') { const uschar *p; /* Don't amalgamate; some compilers */ p = ++ptr; /* grumble at autoincrement in declaration */ while ((compile_block.ctypes[*ptr] & ctype_word) != 0) ptr++; if (*ptr != '>') { *errorptr = ERR42; goto PCRE_ERROR_RETURN; } name_count++; if (ptr - p > max_name_size) max_name_size = (ptr - p); break; } if (*ptr == '=' || *ptr == '>') { while ((compile_block.ctypes[*(++ptr)] & ctype_word) != 0); if (*ptr != ')') { *errorptr = ERR42; goto PCRE_ERROR_RETURN; } break; } /* Unknown character after (?P */ *errorptr = ERR41; goto PCRE_ERROR_RETURN; /* Lookbehinds are in Perl from version 5.005 */ case '<': ptr += 3; if (*ptr == '=' || *ptr == '!') { branch_newextra = 1 + LINK_SIZE; length += 1 + LINK_SIZE; /* For the first branch */ break; } *errorptr = ERR24; goto PCRE_ERROR_RETURN; /* Conditionals are in Perl from version 5.005. The bracket must either be followed by a number (for bracket reference) or by an assertion group, or (a PCRE extension) by 'R' for a recursion test. */ case '(': if (ptr[3] == 'R' && ptr[4] == ')') { ptr += 4; length += 3; } else if ((digitab[ptr[3]] & ctype_digit) != 0) { ptr += 4; length += 3; while ((digitab[*ptr] & ctype_digit) != 0) ptr++; if (*ptr != ')') { *errorptr = ERR26; goto PCRE_ERROR_RETURN; } } else /* An assertion must follow */ { ptr++; /* Can treat like ':' as far as spacing is concerned */ if (ptr[2] != '?' || (ptr[3] != '=' && ptr[3] != '!' && ptr[3] != '<') ) { ptr += 2; /* To get right offset in message */ *errorptr = ERR28; goto PCRE_ERROR_RETURN; } } break; /* Else loop checking valid options until ) is met. Anything else is an error. If we are without any brackets, i.e. at top level, the settings act as if specified in the options, so massage the options immediately. This is for backward compatibility with Perl 5.004. */ default: set = unset = 0; optset = &set; ptr += 2; for (;; ptr++) { c = *ptr; switch (c) { case 'i': *optset |= PCRE_CASELESS; continue; case 'm': *optset |= PCRE_MULTILINE; continue; case 's': *optset |= PCRE_DOTALL; continue; case 'x': *optset |= PCRE_EXTENDED; continue; case 'X': *optset |= PCRE_EXTRA; continue; case 'U': *optset |= PCRE_UNGREEDY; continue; case '-': optset = &unset; continue; /* A termination by ')' indicates an options-setting-only item; if this is at the very start of the pattern (indicated by item_count being zero), we use it to set the global options. This is helpful when analyzing the pattern for first characters, etc. Otherwise nothing is done here and it is handled during the compiling process. [Historical note: Up to Perl 5.8, options settings at top level were always global settings, wherever they appeared in the pattern. That is, they were equivalent to an external setting. From 5.8 onwards, they apply only to what follows (which is what you might expect).] */ case ')': if (item_count == 0) { options = (options | set) & (~unset); set = unset = 0; /* To save length */ item_count--; /* To allow for several */ } /* Fall through */ /* A termination by ':' indicates the start of a nested group with the given options set. This is again handled at compile time, but we must allow for compiled space if any of the ims options are set. We also have to allow for resetting space at the end of the group, which is why 4 is added to the length and not just 2. If there are several changes of options within the same group, this will lead to an over-estimate on the length, but this shouldn't matter very much. We also have to allow for resetting options at the start of any alternations, which we do by setting branch_newextra to 2. Finally, we record whether the case-dependent flag ever changes within the regex. This is used by the "required character" code. */ case ':': if (((set|unset) & PCRE_IMS) != 0) { length += 4; branch_newextra = 2; if (((set|unset) & PCRE_CASELESS) != 0) options |= PCRE_ICHANGED; } goto END_OPTIONS; /* Unrecognized option character */ default: *errorptr = ERR12; goto PCRE_ERROR_RETURN; } } /* If we hit a closing bracket, that's it - this is a freestanding option-setting. We need to ensure that branch_extra is updated if necessary. The only values branch_newextra can have here are 0 or 2. If the value is 2, then branch_extra must either be 2 or 5, depending on whether this is a lookbehind group or not. */ END_OPTIONS: if (c == ')') { if (branch_newextra == 2 && (branch_extra == 0 || branch_extra == 1+LINK_SIZE)) branch_extra += branch_newextra; continue; } /* If options were terminated by ':' control comes here. Fall through to handle the group below. */ } } /* Extracting brackets must be counted so we can process escapes in a Perlish way. If the number exceeds EXTRACT_BASIC_MAX we are going to need an additional 3 bytes of store per extracting bracket. However, if PCRE_NO_AUTO)CAPTURE is set, unadorned brackets become non-capturing, so we must leave the count alone (it will aways be zero). */ else if ((options & PCRE_NO_AUTO_CAPTURE) == 0) { bracount++; if (bracount > EXTRACT_BASIC_MAX) bracket_length += 3; } /* Save length for computing whole length at end if there's a repeat that requires duplication of the group. Also save the current value of branch_extra, and start the new group with the new value. If non-zero, this will either be 2 for a (?imsx: group, or 3 for a lookbehind assertion. */ if (brastackptr >= sizeof(brastack)/sizeof(int)) { *errorptr = ERR19; goto PCRE_ERROR_RETURN; } bralenstack[brastackptr] = branch_extra; branch_extra = branch_newextra; brastack[brastackptr++] = length; length += bracket_length; continue; /* Handle ket. Look for subsequent max/min; for certain sets of values we have to replicate this bracket up to that many times. If brastackptr is 0 this is an unmatched bracket which will generate an error, but take care not to try to access brastack[-1] when computing the length and restoring the branch_extra value. */ case ')': length += 1 + LINK_SIZE; if (brastackptr > 0) { duplength = length - brastack[--brastackptr]; branch_extra = bralenstack[brastackptr]; } else duplength = 0; /* The following code is also used when a recursion such as (?3) is followed by a quantifier, because in that case, it has to be wrapped inside brackets so that the quantifier works. The value of duplength must be set before arrival. */ HANDLE_QUANTIFIED_BRACKETS: /* Leave ptr at the final char; for read_repeat_counts this happens automatically; for the others we need an increment. */ if ((c = ptr[1]) == '{' && is_counted_repeat(ptr+2)) { ptr = read_repeat_counts(ptr+2, &min, &max, errorptr); if (*errorptr != NULL) goto PCRE_ERROR_RETURN; } else if (c == '*') { min = 0; max = -1; ptr++; } else if (c == '+') { min = 1; max = -1; ptr++; } else if (c == '?') { min = 0; max = 1; ptr++; } else { min = 1; max = 1; } /* If the minimum is zero, we have to allow for an OP_BRAZERO before the group, and if the maximum is greater than zero, we have to replicate maxval-1 times; each replication acquires an OP_BRAZERO plus a nesting bracket set. */ if (min == 0) { length++; if (max > 0) length += (max - 1) * (duplength + 3 + 2*LINK_SIZE); } /* When the minimum is greater than zero, we have to replicate up to minval-1 times, with no additions required in the copies. Then, if there is a limited maximum we have to replicate up to maxval-1 times allowing for a BRAZERO item before each optional copy and nesting brackets for all but one of the optional copies. */ else { length += (min - 1) * duplength; if (max > min) /* Need this test as max=-1 means no limit */ length += (max - min) * (duplength + 3 + 2*LINK_SIZE) - (2 + 2*LINK_SIZE); } /* Allow space for once brackets for "possessive quantifier" */ if (ptr[1] == '+') { ptr++; length += 2 + 2*LINK_SIZE; } continue; /* Non-special character. It won't be space or # in extended mode, so it is always a genuine character. If we are in a \Q...\E sequence, check for the end; if not, we have a literal. */ default: NORMAL_CHAR: if (inescq && c == '\\' && ptr[1] == 'E') { inescq = FALSE; ptr++; continue; } length += 2; /* For a one-byte character */ lastitemlength = 1; /* Default length of last item for repeats */ /* In UTF-8 mode, check for additional bytes. */ #ifdef SUPPORT_UTF8 if (utf8 && (c & 0xc0) == 0xc0) { while ((ptr[1] & 0xc0) == 0x80) /* Can't flow over the end */ { /* because the end is marked */ lastitemlength++; /* by a zero byte. */ length++; ptr++; } } #endif continue; } } length += 2 + LINK_SIZE; /* For final KET and END */ if ((options & PCRE_AUTO_CALLOUT) != 0) length += 2 + 2*LINK_SIZE; /* For final callout */ if (length > MAX_PATTERN_SIZE) { *errorptr = ERR20; return NULL; } /* Compute the size of data block needed and get it, either from malloc or externally provided function. */ size = length + sizeof(real_pcre) + name_count * (max_name_size + 3); re = (real_pcre *)(pcre_malloc)(size); if (re == NULL) { *errorptr = ERR21; return NULL; } /* Put in the magic number, and save the sizes, options, and character table pointer. NULL is used for the default character tables. The nullpad field is at the end; it's there to help in the case when a regex compiled on a system with 4-byte pointers is run on another with 8-byte pointers. */ re->magic_number = MAGIC_NUMBER; re->size = size; re->options = options; re->dummy1 = re->dummy2 = 0; re->name_table_offset = sizeof(real_pcre); re->name_entry_size = max_name_size + 3; re->name_count = name_count; re->tables = (tables == pcre_default_tables)? NULL : tables; re->nullpad = NULL; /* The starting points of the name/number translation table and of the code are passed around in the compile data block. */ compile_block.names_found = 0; compile_block.name_entry_size = max_name_size + 3; compile_block.name_table = (uschar *)re + re->name_table_offset; codestart = compile_block.name_table + re->name_entry_size * re->name_count; compile_block.start_code = codestart; compile_block.start_pattern = (const uschar *)pattern; compile_block.req_varyopt = 0; compile_block.nopartial = FALSE; /* Set up a starting, non-extracting bracket, then compile the expression. On error, *errorptr will be set non-NULL, so we don't need to look at the result of the function here. */ ptr = (const uschar *)pattern; code = (uschar *)codestart; *code = OP_BRA; bracount = 0; (void)compile_regex(options, options & PCRE_IMS, &bracount, &code, &ptr, errorptr, FALSE, 0, &firstbyte, &reqbyte, NULL, &compile_block); re->top_bracket = bracount; re->top_backref = compile_block.top_backref; if (compile_block.nopartial) re->options |= PCRE_NOPARTIAL; /* If not reached end of pattern on success, there's an excess bracket. */ if (*errorptr == NULL && *ptr != 0) *errorptr = ERR22; /* Fill in the terminating state and check for disastrous overflow, but if debugging, leave the test till after things are printed out. */ *code++ = OP_END; #ifndef DEBUG if (code - codestart > length) *errorptr = ERR23; #endif /* Give an error if there's back reference to a non-existent capturing subpattern. */ if (re->top_backref > re->top_bracket) *errorptr = ERR15; /* Failed to compile, or error while post-processing */ if (*errorptr != NULL) { (pcre_free)(re); PCRE_ERROR_RETURN: *erroroffset = ptr - (const uschar *)pattern; return NULL; } /* If the anchored option was not passed, set the flag if we can determine that the pattern is anchored by virtue of ^ characters or \A or anything else (such as starting with .* when DOTALL is set). Otherwise, if we know what the first character has to be, save it, because that speeds up unanchored matches no end. If not, see if we can set the PCRE_STARTLINE flag. This is helpful for multiline matches when all branches start with ^. and also when all branches start with .* for non-DOTALL matches. */ if ((options & PCRE_ANCHORED) == 0) { int temp_options = options; if (is_anchored(codestart, &temp_options, 0, compile_block.backref_map)) re->options |= PCRE_ANCHORED; else { if (firstbyte < 0) firstbyte = find_firstassertedchar(codestart, &temp_options, FALSE); if (firstbyte >= 0) /* Remove caseless flag for non-caseable chars */ { int ch = firstbyte & 255; re->first_byte = ((firstbyte & REQ_CASELESS) != 0 && compile_block.fcc[ch] == ch)? ch : firstbyte; re->options |= PCRE_FIRSTSET; } else if (is_startline(codestart, 0, compile_block.backref_map)) re->options |= PCRE_STARTLINE; } } /* For an anchored pattern, we use the "required byte" only if it follows a variable length item in the regex. Remove the caseless flag for non-caseable bytes. */ if (reqbyte >= 0 && ((re->options & PCRE_ANCHORED) == 0 || (reqbyte & REQ_VARY) != 0)) { int ch = reqbyte & 255; re->req_byte = ((reqbyte & REQ_CASELESS) != 0 && compile_block.fcc[ch] == ch)? (reqbyte & ~REQ_CASELESS) : reqbyte; re->options |= PCRE_REQCHSET; } /* Print out the compiled data for debugging */ #ifdef DEBUG printf("Length = %d top_bracket = %d top_backref = %d\n", length, re->top_bracket, re->top_backref); if (re->options != 0) { printf("%s%s%s%s%s%s%s%s%s%s\n", ((re->options & PCRE_NOPARTIAL) != 0)? "nopartial " : "", ((re->options & PCRE_ANCHORED) != 0)? "anchored " : "", ((re->options & PCRE_CASELESS) != 0)? "caseless " : "", ((re->options & PCRE_ICHANGED) != 0)? "case state changed " : "", ((re->options & PCRE_EXTENDED) != 0)? "extended " : "", ((re->options & PCRE_MULTILINE) != 0)? "multiline " : "", ((re->options & PCRE_DOTALL) != 0)? "dotall " : "", ((re->options & PCRE_DOLLAR_ENDONLY) != 0)? "endonly " : "", ((re->options & PCRE_EXTRA) != 0)? "extra " : "", ((re->options & PCRE_UNGREEDY) != 0)? "ungreedy " : ""); } if ((re->options & PCRE_FIRSTSET) != 0) { int ch = re->first_byte & 255; const char *caseless = ((re->first_byte & REQ_CASELESS) == 0)? "" : " (caseless)"; if (isprint(ch)) printf("First char = %c%s\n", ch, caseless); else printf("First char = \\x%02x%s\n", ch, caseless); } if ((re->options & PCRE_REQCHSET) != 0) { int ch = re->req_byte & 255; const char *caseless = ((re->req_byte & REQ_CASELESS) == 0)? "" : " (caseless)"; if (isprint(ch)) printf("Req char = %c%s\n", ch, caseless); else printf("Req char = \\x%02x%s\n", ch, caseless); } print_internals(re, stdout); /* This check is done here in the debugging case so that the code that was compiled can be seen. */ if (code - codestart > length) { *errorptr = ERR23; (pcre_free)(re); *erroroffset = ptr - (uschar *)pattern; return NULL; } #endif return (pcre *)re; } /************************************************* * Match a back-reference * *************************************************/ /* If a back reference hasn't been set, the length that is passed is greater than the number of characters left in the string, so the match fails. Arguments: offset index into the offset vector eptr points into the subject length length to be matched md points to match data block ims the ims flags Returns: TRUE if matched */ static BOOL match_ref(int offset, register const uschar *eptr, int length, match_data *md, unsigned long int ims) { const uschar *p = md->start_subject + md->offset_vector[offset]; #ifdef DEBUG if (eptr >= md->end_subject) printf("matching subject "); else { printf("matching subject "); pchars(eptr, length, TRUE, md); } printf(" against backref "); pchars(p, length, FALSE, md); printf("\n"); #endif /* Always fail if not enough characters left */ if (length > md->end_subject - eptr) return FALSE; /* Separate the caselesss case for speed */ if ((ims & PCRE_CASELESS) != 0) { while (length-- > 0) if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE; } else { while (length-- > 0) if (*p++ != *eptr++) return FALSE; } return TRUE; } #ifdef SUPPORT_UTF8 /************************************************* * Match character against an XCLASS * *************************************************/ /* This function is called from within the XCLASS code below, to match a character against an extended class which might match values > 255. Arguments: c the character data points to the flag byte of the XCLASS data Returns: TRUE if character matches, else FALSE */ static BOOL match_xclass(int c, const uschar *data) { int t; BOOL negated = (*data & XCL_NOT) != 0; /* Character values < 256 are matched against a bitmap, if one is present. If not, we still carry on, because there may be ranges that start below 256 in the additional data. */ if (c < 256) { if ((*data & XCL_MAP) != 0 && (data[1 + c/8] & (1 << (c&7))) != 0) return !negated; /* char found */ } /* First skip the bit map if present. Then match against the list of Unicode properties or large chars or ranges that end with a large char. We won't ever encounter XCL_PROP or XCL_NOTPROP when UCP support is not compiled. */ if ((*data++ & XCL_MAP) != 0) data += 32; while ((t = *data++) != XCL_END) { int x, y; if (t == XCL_SINGLE) { GETCHARINC(x, data); if (c == x) return !negated; } else if (t == XCL_RANGE) { GETCHARINC(x, data); GETCHARINC(y, data); if (c >= x && c <= y) return !negated; } #ifdef SUPPORT_UCP else /* XCL_PROP & XCL_NOTPROP */ { int chartype, othercase; int rqdtype = *data++; int category = ucp_findchar(c, &chartype, &othercase); if (rqdtype >= 128) { if ((rqdtype - 128 == category) == (t == XCL_PROP)) return !negated; } else { if ((rqdtype == chartype) == (t == XCL_PROP)) return !negated; } } #endif /* SUPPORT_UCP */ } return negated; /* char did not match */ } #endif /*************************************************************************** **************************************************************************** RECURSION IN THE match() FUNCTION The match() function is highly recursive. Some regular expressions can cause it to recurse thousands of times. I was writing for Unix, so I just let it call itself recursively. This uses the stack for saving everything that has to be saved for a recursive call. On Unix, the stack can be large, and this works fine. It turns out that on non-Unix systems there are problems with programs that use a lot of stack. (This despite the fact that every last chip has oodles of memory these days, and techniques for extending the stack have been known for decades.) So.... There is a fudge, triggered by defining NO_RECURSE, which avoids recursive calls by keeping local variables that need to be preserved in blocks of memory obtained from malloc instead instead of on the stack. Macros are used to achieve this so that the actual code doesn't look very different to what it always used to. **************************************************************************** ***************************************************************************/ /* These versions of the macros use the stack, as normal */ #ifndef NO_RECURSE #define REGISTER register #define RMATCH(rx,ra,rb,rc,rd,re,rf,rg) rx = match(ra,rb,rc,rd,re,rf,rg) #define RRETURN(ra) return ra #else /* These versions of the macros manage a private stack on the heap. Note that the rd argument of RMATCH isn't actually used. It's the md argument of match(), which never changes. */ #define REGISTER #define RMATCH(rx,ra,rb,rc,rd,re,rf,rg)\ {\ heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\ if (setjmp(frame->Xwhere) == 0)\ {\ newframe->Xeptr = ra;\ newframe->Xecode = rb;\ newframe->Xoffset_top = rc;\ newframe->Xims = re;\ newframe->Xeptrb = rf;\ newframe->Xflags = rg;\ newframe->Xprevframe = frame;\ frame = newframe;\ DPRINTF(("restarting from line %d\n", __LINE__));\ goto HEAP_RECURSE;\ }\ else\ {\ DPRINTF(("longjumped back to line %d\n", __LINE__));\ frame = md->thisframe;\ rx = frame->Xresult;\ }\ } #define RRETURN(ra)\ {\ heapframe *newframe = frame;\ frame = newframe->Xprevframe;\ (pcre_stack_free)(newframe);\ if (frame != NULL)\ {\ frame->Xresult = ra;\ md->thisframe = frame;\ longjmp(frame->Xwhere, 1);\ }\ return ra;\ } /* Structure for remembering the local variables in a private frame */ typedef struct heapframe { struct heapframe *Xprevframe; /* Function arguments that may change */ const uschar *Xeptr; const uschar *Xecode; int Xoffset_top; long int Xims; eptrblock *Xeptrb; int Xflags; /* Function local variables */ const uschar *Xcallpat; const uschar *Xcharptr; const uschar *Xdata; const uschar *Xnext; const uschar *Xpp; const uschar *Xprev; const uschar *Xsaved_eptr; recursion_info Xnew_recursive; BOOL Xcur_is_word; BOOL Xcondition; BOOL Xminimize; BOOL Xprev_is_word; unsigned long int Xoriginal_ims; #ifdef SUPPORT_UCP int Xprop_type; int Xprop_fail_result; int Xprop_category; int Xprop_chartype; int Xprop_othercase; int Xprop_test_against; int *Xprop_test_variable; #endif int Xctype; int Xfc; int Xfi; int Xlength; int Xmax; int Xmin; int Xnumber; int Xoffset; int Xop; int Xsave_capture_last; int Xsave_offset1, Xsave_offset2, Xsave_offset3; int Xstacksave[REC_STACK_SAVE_MAX]; eptrblock Xnewptrb; /* Place to pass back result, and where to jump back to */ int Xresult; jmp_buf Xwhere; } heapframe; #endif /*************************************************************************** ***************************************************************************/ /************************************************* * Match from current position * *************************************************/ /* On entry ecode points to the first opcode, and eptr to the first character in the subject string, while eptrb holds the value of eptr at the start of the last bracketed group - used for breaking infinite loops matching zero-length strings. This function is called recursively in many circumstances. Whenever it returns a negative (error) response, the outer incarnation must also return the same response. Performance note: It might be tempting to extract commonly used fields from the md structure (e.g. utf8, end_subject) into individual variables to improve performance. Tests using gcc on a SPARC disproved this; in the first case, it made performance worse. Arguments: eptr pointer in subject ecode position in code offset_top current top pointer md pointer to "static" info for the match ims current /i, /m, and /s options eptrb pointer to chain of blocks containing eptr at start of brackets - for testing for empty matches flags can contain match_condassert - this is an assertion condition match_isgroup - this is the start of a bracketed group Returns: MATCH_MATCH if matched ) these values are >= 0 MATCH_NOMATCH if failed to match ) a negative PCRE_ERROR_xxx value if aborted by an error condition (e.g. stopped by recursion limit) */ static int match(REGISTER const uschar *eptr, REGISTER const uschar *ecode, int offset_top, match_data *md, unsigned long int ims, eptrblock *eptrb, int flags) { /* These variables do not need to be preserved over recursion in this function, so they can be ordinary variables in all cases. Mark them with "register" because they are used a lot in loops. */ register int rrc; /* Returns from recursive calls */ register int i; /* Used for loops not involving calls to RMATCH() */ register int c; /* Character values not kept over RMATCH() calls */ /* When recursion is not being used, all "local" variables that have to be preserved over calls to RMATCH() are part of a "frame" which is obtained from heap storage. Set up the top-level frame here; others are obtained from the heap whenever RMATCH() does a "recursion". See the macro definitions above. */ #ifdef NO_RECURSE heapframe *frame = (pcre_stack_malloc)(sizeof(heapframe)); frame->Xprevframe = NULL; /* Marks the top level */ /* Copy in the original argument variables */ frame->Xeptr = eptr; frame->Xecode = ecode; frame->Xoffset_top = offset_top; frame->Xims = ims; frame->Xeptrb = eptrb; frame->Xflags = flags; /* This is where control jumps back to to effect "recursion" */ HEAP_RECURSE: /* Macros make the argument variables come from the current frame */ #define eptr frame->Xeptr #define ecode frame->Xecode #define offset_top frame->Xoffset_top #define ims frame->Xims #define eptrb frame->Xeptrb #define flags frame->Xflags /* Ditto for the local variables */ #ifdef SUPPORT_UTF8 #define charptr frame->Xcharptr #endif #define callpat frame->Xcallpat #define data frame->Xdata #define next frame->Xnext #define pp frame->Xpp #define prev frame->Xprev #define saved_eptr frame->Xsaved_eptr #define new_recursive frame->Xnew_recursive #define cur_is_word frame->Xcur_is_word #define condition frame->Xcondition #define minimize frame->Xminimize #define prev_is_word frame->Xprev_is_word #define original_ims frame->Xoriginal_ims #ifdef SUPPORT_UCP #define prop_type frame->Xprop_type #define prop_fail_result frame->Xprop_fail_result #define prop_category frame->Xprop_category #define prop_chartype frame->Xprop_chartype #define prop_othercase frame->Xprop_othercase #define prop_test_against frame->Xprop_test_against #define prop_test_variable frame->Xprop_test_variable #endif #define ctype frame->Xctype #define fc frame->Xfc #define fi frame->Xfi #define length frame->Xlength #define max frame->Xmax #define min frame->Xmin #define number frame->Xnumber #define offset frame->Xoffset #define op frame->Xop #define save_capture_last frame->Xsave_capture_last #define save_offset1 frame->Xsave_offset1 #define save_offset2 frame->Xsave_offset2 #define save_offset3 frame->Xsave_offset3 #define stacksave frame->Xstacksave #define newptrb frame->Xnewptrb /* When recursion is being used, local variables are allocated on the stack and get preserved during recursion in the normal way. In this environment, fi and i, and fc and c, can be the same variables. */ #else #define fi i #define fc c #ifdef SUPPORT_UTF8 /* Many of these variables are used ony */ const uschar *charptr; /* small blocks of the code. My normal */ #endif /* style of coding would have declared */ const uschar *callpat; /* them within each of those blocks. */ const uschar *data; /* However, in order to accommodate the */ const uschar *next; /* version of this code that uses an */ const uschar *pp; /* external "stack" implemented on the */ const uschar *prev; /* heap, it is easier to declare them */ const uschar *saved_eptr; /* all here, so the declarations can */ /* be cut out in a block. The only */ recursion_info new_recursive; /* declarations within blocks below are */ /* for variables that do not have to */ BOOL cur_is_word; /* be preserved over a recursive call */ BOOL condition; /* to RMATCH(). */ BOOL minimize; BOOL prev_is_word; unsigned long int original_ims; #ifdef SUPPORT_UCP int prop_type; int prop_fail_result; int prop_category; int prop_chartype; int prop_othercase; int prop_test_against; int *prop_test_variable; #endif int ctype; int length; int max; int min; int number; int offset; int op; int save_capture_last; int save_offset1, save_offset2, save_offset3; int stacksave[REC_STACK_SAVE_MAX]; eptrblock newptrb; #endif /* These statements are here to stop the compiler complaining about unitialized variables. */ #ifdef SUPPORT_UCP prop_fail_result = 0; prop_test_against = 0; prop_test_variable = NULL; #endif /* OK, now we can get on with the real code of the function. Recursion is specified by the macros RMATCH and RRETURN. When NO_RECURSE is *not* defined, these just turn into a recursive call to match() and a "return", respectively. However, RMATCH isn't like a function call because it's quite a complicated macro. It has to be used in one particular way. This shouldn't, however, impact performance when true recursion is being used. */ if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT); original_ims = ims; /* Save for resetting on ')' */ /* At the start of a bracketed group, add the current subject pointer to the stack of such pointers, to be re-instated at the end of the group when we hit the closing ket. When match() is called in other circumstances, we don't add to this stack. */ if ((flags & match_isgroup) != 0) { newptrb.epb_prev = eptrb; newptrb.epb_saved_eptr = eptr; eptrb = &newptrb; } /* Now start processing the operations. */ for (;;) { op = *ecode; minimize = FALSE; /* For partial matching, remember if we ever hit the end of the subject after matching at least one subject character. */ if (md->partial && eptr >= md->end_subject && eptr > md->start_match) md->hitend = TRUE; /* Opening capturing bracket. If there is space in the offset vector, save the current subject position in the working slot at the top of the vector. We mustn't change the current values of the data slot, because they may be set from a previous iteration of this group, and be referred to by a reference inside the group. If the bracket fails to match, we need to restore this value and also the values of the final offsets, in case they were set by a previous iteration of the same bracket. If there isn't enough space in the offset vector, treat this as if it were a non-capturing bracket. Don't worry about setting the flag for the error case here; that is handled in the code for KET. */ if (op > OP_BRA) { number = op - OP_BRA; /* For extended extraction brackets (large number), we have to fish out the number from a dummy opcode at the start. */ if (number > EXTRACT_BASIC_MAX) number = GET2(ecode, 2+LINK_SIZE); offset = number << 1; #ifdef DEBUG printf("start bracket %d subject=", number); pchars(eptr, 16, TRUE, md); printf("\n"); #endif if (offset < md->offset_max) { save_offset1 = md->offset_vector[offset]; save_offset2 = md->offset_vector[offset+1]; save_offset3 = md->offset_vector[md->offset_end - number]; save_capture_last = md->capture_last; DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3)); md->offset_vector[md->offset_end - number] = eptr - md->start_subject; do { RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, match_isgroup); if (rrc != MATCH_NOMATCH) RRETURN(rrc); md->capture_last = save_capture_last; ecode += GET(ecode, 1); } while (*ecode == OP_ALT); DPRINTF(("bracket %d failed\n", number)); md->offset_vector[offset] = save_offset1; md->offset_vector[offset+1] = save_offset2; md->offset_vector[md->offset_end - number] = save_offset3; RRETURN(MATCH_NOMATCH); } /* Insufficient room for saving captured contents */ else op = OP_BRA; } /* Other types of node can be handled by a switch */ switch(op) { case OP_BRA: /* Non-capturing bracket: optimized */ DPRINTF(("start bracket 0\n")); do { RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, match_isgroup); if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode += GET(ecode, 1); } while (*ecode == OP_ALT); DPRINTF(("bracket 0 failed\n")); RRETURN(MATCH_NOMATCH); /* Conditional group: compilation checked that there are no more than two branches. If the condition is false, skipping the first branch takes us past the end if there is only one branch, but that's OK because that is exactly what going to the ket would do. */ case OP_COND: if (ecode[LINK_SIZE+1] == OP_CREF) /* Condition extract or recurse test */ { offset = GET2(ecode, LINK_SIZE+2) << 1; /* Doubled ref number */ condition = (offset == CREF_RECURSE * 2)? (md->recursive != NULL) : (offset < offset_top && md->offset_vector[offset] >= 0); RMATCH(rrc, eptr, ecode + (condition? (LINK_SIZE + 4) : (LINK_SIZE + 1 + GET(ecode, 1))), offset_top, md, ims, eptrb, match_isgroup); RRETURN(rrc); } /* The condition is an assertion. Call match() to evaluate it - setting the final argument TRUE causes it to stop at the end of an assertion. */ else { RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, match_condassert | match_isgroup); if (rrc == MATCH_MATCH) { ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE+2); while (*ecode == OP_ALT) ecode += GET(ecode, 1); } else if (rrc != MATCH_NOMATCH) { RRETURN(rrc); /* Need braces because of following else */ } else ecode += GET(ecode, 1); RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, match_isgroup); RRETURN(rrc); } /* Control never reaches here */ /* Skip over conditional reference or large extraction number data if encountered. */ case OP_CREF: case OP_BRANUMBER: ecode += 3; break; /* End of the pattern. If we are in a recursion, we should restore the offsets appropriately and continue from after the call. */ case OP_END: if (md->recursive != NULL && md->recursive->group_num == 0) { recursion_info *rec = md->recursive; DPRINTF(("Hit the end in a (?0) recursion\n")); md->recursive = rec->prevrec; memmove(md->offset_vector, rec->offset_save, rec->saved_max * sizeof(int)); md->start_match = rec->save_start; ims = original_ims; ecode = rec->after_call; break; } /* Otherwise, if PCRE_NOTEMPTY is set, fail if we have matched an empty string - backtracking will then try other alternatives, if any. */ if (md->notempty && eptr == md->start_match) RRETURN(MATCH_NOMATCH); md->end_match_ptr = eptr; /* Record where we ended */ md->end_offset_top = offset_top; /* and how many extracts were taken */ RRETURN(MATCH_MATCH); /* Change option settings */ case OP_OPT: ims = ecode[1]; ecode += 2; DPRINTF(("ims set to %02lx\n", ims)); break; /* Assertion brackets. Check the alternative branches in turn - the matching won't pass the KET for an assertion. If any one branch matches, the assertion is true. Lookbehind assertions have an OP_REVERSE item at the start of each branch to move the current point backwards, so the code at this level is identical to the lookahead case. */ case OP_ASSERT: case OP_ASSERTBACK: do { RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, match_isgroup); if (rrc == MATCH_MATCH) break; if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode += GET(ecode, 1); } while (*ecode == OP_ALT); if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH); /* If checking an assertion for a condition, return MATCH_MATCH. */ if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH); /* Continue from after the assertion, updating the offsets high water mark, since extracts may have been taken during the assertion. */ do ecode += GET(ecode,1); while (*ecode == OP_ALT); ecode += 1 + LINK_SIZE; offset_top = md->end_offset_top; continue; /* Negative assertion: all branches must fail to match */ case OP_ASSERT_NOT: case OP_ASSERTBACK_NOT: do { RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, match_isgroup); if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH); if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode += GET(ecode,1); } while (*ecode == OP_ALT); if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH); ecode += 1 + LINK_SIZE; continue; /* Move the subject pointer back. This occurs only at the start of each branch of a lookbehind assertion. If we are too close to the start to move back, this match function fails. When working with UTF-8 we move back a number of characters, not bytes. */ case OP_REVERSE: #ifdef SUPPORT_UTF8 if (md->utf8) { c = GET(ecode,1); for (i = 0; i < c; i++) { eptr--; if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH); BACKCHAR(eptr) } } else #endif /* No UTF-8 support, or not in UTF-8 mode: count is byte count */ { eptr -= GET(ecode,1); if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH); } /* Skip to next op code */ ecode += 1 + LINK_SIZE; break; /* The callout item calls an external function, if one is provided, passing details of the match so far. This is mainly for debugging, though the function is able to force a failure. */ case OP_CALLOUT: if (pcre_callout != NULL) { pcre_callout_block cb; cb.version = 1; /* Version 1 of the callout block */ cb.callout_number = ecode[1]; cb.offset_vector = md->offset_vector; cb.subject = (const char *)md->start_subject; cb.subject_length = md->end_subject - md->start_subject; cb.start_match = md->start_match - md->start_subject; cb.current_position = eptr - md->start_subject; cb.pattern_position = GET(ecode, 2); cb.next_item_length = GET(ecode, 2 + LINK_SIZE); cb.capture_top = offset_top/2; cb.capture_last = md->capture_last; cb.callout_data = md->callout_data; if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH); if (rrc < 0) RRETURN(rrc); } ecode += 2 + 2*LINK_SIZE; break; /* Recursion either matches the current regex, or some subexpression. The offset data is the offset to the starting bracket from the start of the whole pattern. (This is so that it works from duplicated subpatterns.) If there are any capturing brackets started but not finished, we have to save their starting points and reinstate them after the recursion. However, we don't know how many such there are (offset_top records the completed total) so we just have to save all the potential data. There may be up to 65535 such values, which is too large to put on the stack, but using malloc for small numbers seems expensive. As a compromise, the stack is used when there are no more than REC_STACK_SAVE_MAX values to store; otherwise malloc is used. A problem is what to do if the malloc fails ... there is no way of returning to the top level with an error. Save the top REC_STACK_SAVE_MAX values on the stack, and accept that the rest may be wrong. There are also other values that have to be saved. We use a chained sequence of blocks that actually live on the stack. Thanks to Robin Houston for the original version of this logic. */ case OP_RECURSE: { callpat = md->start_code + GET(ecode, 1); new_recursive.group_num = *callpat - OP_BRA; /* For extended extraction brackets (large number), we have to fish out the number from a dummy opcode at the start. */ if (new_recursive.group_num > EXTRACT_BASIC_MAX) new_recursive.group_num = GET2(callpat, 2+LINK_SIZE); /* Add to "recursing stack" */ new_recursive.prevrec = md->recursive; md->recursive = &new_recursive; /* Find where to continue from afterwards */ ecode += 1 + LINK_SIZE; new_recursive.after_call = ecode; /* Now save the offset data. */ new_recursive.saved_max = md->offset_end; if (new_recursive.saved_max <= REC_STACK_SAVE_MAX) new_recursive.offset_save = stacksave; else { new_recursive.offset_save = (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int)); if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY); } memcpy(new_recursive.offset_save, md->offset_vector, new_recursive.saved_max * sizeof(int)); new_recursive.save_start = md->start_match; md->start_match = eptr; /* OK, now we can do the recursion. For each top-level alternative we restore the offset and recursion data. */ DPRINTF(("Recursing into group %d\n", new_recursive.group_num)); do { RMATCH(rrc, eptr, callpat + 1 + LINK_SIZE, offset_top, md, ims, eptrb, match_isgroup); if (rrc == MATCH_MATCH) { md->recursive = new_recursive.prevrec; if (new_recursive.offset_save != stacksave) (pcre_free)(new_recursive.offset_save); RRETURN(MATCH_MATCH); } else if (rrc != MATCH_NOMATCH) RRETURN(rrc); md->recursive = &new_recursive; memcpy(md->offset_vector, new_recursive.offset_save, new_recursive.saved_max * sizeof(int)); callpat += GET(callpat, 1); } while (*callpat == OP_ALT); DPRINTF(("Recursion didn't match\n")); md->recursive = new_recursive.prevrec; if (new_recursive.offset_save != stacksave) (pcre_free)(new_recursive.offset_save); RRETURN(MATCH_NOMATCH); } /* Control never reaches here */ /* "Once" brackets are like assertion brackets except that after a match, the point in the subject string is not moved back. Thus there can never be a move back into the brackets. Friedl calls these "atomic" subpatterns. Check the alternative branches in turn - the matching won't pass the KET for this kind of subpattern. If any one branch matches, we carry on as at the end of a normal bracket, leaving the subject pointer. */ case OP_ONCE: { prev = ecode; saved_eptr = eptr; do { RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, match_isgroup); if (rrc == MATCH_MATCH) break; if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode += GET(ecode,1); } while (*ecode == OP_ALT); /* If hit the end of the group (which could be repeated), fail */ if (*ecode != OP_ONCE && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH); /* Continue as from after the assertion, updating the offsets high water mark, since extracts may have been taken. */ do ecode += GET(ecode,1); while (*ecode == OP_ALT); offset_top = md->end_offset_top; eptr = md->end_match_ptr; /* For a non-repeating ket, just continue at this level. This also happens for a repeating ket if no characters were matched in the group. This is the forcible breaking of infinite loops as implemented in Perl 5.005. If there is an options reset, it will get obeyed in the normal course of events. */ if (*ecode == OP_KET || eptr == saved_eptr) { ecode += 1+LINK_SIZE; break; } /* The repeating kets try the rest of the pattern or restart from the preceding bracket, in the appropriate order. We need to reset any options that changed within the bracket before re-running it, so check the next opcode. */ if (ecode[1+LINK_SIZE] == OP_OPT) { ims = (ims & ~PCRE_IMS) | ecode[4]; DPRINTF(("ims set to %02lx at group repeat\n", ims)); } if (*ecode == OP_KETRMIN) { RMATCH(rrc, eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup); if (rrc != MATCH_NOMATCH) RRETURN(rrc); } else /* OP_KETRMAX */ { RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup); if (rrc != MATCH_NOMATCH) RRETURN(rrc); RMATCH(rrc, eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); } } RRETURN(MATCH_NOMATCH); /* An alternation is the end of a branch; scan along to find the end of the bracketed group and go to there. */ case OP_ALT: do ecode += GET(ecode,1); while (*ecode == OP_ALT); break; /* BRAZERO and BRAMINZERO occur just before a bracket group, indicating that it may occur zero times. It may repeat infinitely, or not at all - i.e. it could be ()* or ()? in the pattern. Brackets with fixed upper repeat limits are compiled as a number of copies, with the optional ones preceded by BRAZERO or BRAMINZERO. */ case OP_BRAZERO: { next = ecode+1; RMATCH(rrc, eptr, next, offset_top, md, ims, eptrb, match_isgroup); if (rrc != MATCH_NOMATCH) RRETURN(rrc); do next += GET(next,1); while (*next == OP_ALT); ecode = next + 1+LINK_SIZE; } break; case OP_BRAMINZERO: { next = ecode+1; do next += GET(next,1); while (*next == OP_ALT); RMATCH(rrc, eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, match_isgroup); if (rrc != MATCH_NOMATCH) RRETURN(rrc); ecode++; } break; /* End of a group, repeated or non-repeating. If we are at the end of an assertion "group", stop matching and return MATCH_MATCH, but record the current high water mark for use by positive assertions. Do this also for the "once" (not-backup up) groups. */ case OP_KET: case OP_KETRMIN: case OP_KETRMAX: { prev = ecode - GET(ecode, 1); saved_eptr = eptrb->epb_saved_eptr; /* Back up the stack of bracket start pointers. */ eptrb = eptrb->epb_prev; if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT || *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT || *prev == OP_ONCE) { md->end_match_ptr = eptr; /* For ONCE */ md->end_offset_top = offset_top; RRETURN(MATCH_MATCH); } /* In all other cases except a conditional group we have to check the group number back at the start and if necessary complete handling an extraction by setting the offsets and bumping the high water mark. */ if (*prev != OP_COND) { number = *prev - OP_BRA; /* For extended extraction brackets (large number), we have to fish out the number from a dummy opcode at the start. */ if (number > EXTRACT_BASIC_MAX) number = GET2(prev, 2+LINK_SIZE); offset = number << 1; #ifdef DEBUG printf("end bracket %d", number); printf("\n"); #endif /* Test for a numbered group. This includes groups called as a result of recursion. Note that whole-pattern recursion is coded as a recurse into group 0, so it won't be picked up here. Instead, we catch it when the OP_END is reached. */ if (number > 0) { md->capture_last = number; if (offset >= md->offset_max) md->offset_overflow = TRUE; else { md->offset_vector[offset] = md->offset_vector[md->offset_end - number]; md->offset_vector[offset+1] = eptr - md->start_subject; if (offset_top <= offset) offset_top = offset + 2; } /* Handle a recursively called group. Restore the offsets appropriately and continue from after the call. */ if (md->recursive != NULL && md->recursive->group_num == number) { recursion_info *rec = md->recursive; DPRINTF(("Recursion (%d) succeeded - continuing\n", number)); md->recursive = rec->prevrec; md->start_match = rec->save_start; memcpy(md->offset_vector, rec->offset_save, rec->saved_max * sizeof(int)); ecode = rec->after_call; ims = original_ims; break; } } } /* Reset the value of the ims flags, in case they got changed during the group. */ ims = original_ims; DPRINTF(("ims reset to %02lx\n", ims)); /* For a non-repeating ket, just continue at this level. This also happens for a repeating ket if no characters were matched in the group. This is the forcible breaking of infinite loops as implemented in Perl 5.005. If there is an options reset, it will get obeyed in the normal course of events. */ if (*ecode == OP_KET || eptr == saved_eptr) { ecode += 1 + LINK_SIZE; break; } /* The repeating kets try the rest of the pattern or restart from the preceding bracket, in the appropriate order. */ if (*ecode == OP_KETRMIN) { RMATCH(rrc, eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup); if (rrc != MATCH_NOMATCH) RRETURN(rrc); } else /* OP_KETRMAX */ { RMATCH(rrc, eptr, prev, offset_top, md, ims, eptrb, match_isgroup); if (rrc != MATCH_NOMATCH) RRETURN(rrc); RMATCH(rrc, eptr, ecode + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); } } RRETURN(MATCH_NOMATCH); /* Start of subject unless notbol, or after internal newline if multiline */ case OP_CIRC: if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH); if ((ims & PCRE_MULTILINE) != 0) { if (eptr != md->start_subject && eptr[-1] != NEWLINE) RRETURN(MATCH_NOMATCH); ecode++; break; } /* ... else fall through */ /* Start of subject assertion */ case OP_SOD: if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH); ecode++; break; /* Start of match assertion */ case OP_SOM: if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH); ecode++; break; /* Assert before internal newline if multiline, or before a terminating newline unless endonly is set, else end of subject unless noteol is set. */ case OP_DOLL: if ((ims & PCRE_MULTILINE) != 0) { if (eptr < md->end_subject) { if (*eptr != NEWLINE) RRETURN(MATCH_NOMATCH); } else { if (md->noteol) RRETURN(MATCH_NOMATCH); } ecode++; break; } else { if (md->noteol) RRETURN(MATCH_NOMATCH); if (!md->endonly) { if (eptr < md->end_subject - 1 || (eptr == md->end_subject - 1 && *eptr != NEWLINE)) RRETURN(MATCH_NOMATCH); ecode++; break; } } /* ... else fall through */ /* End of subject assertion (\z) */ case OP_EOD: if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH); ecode++; break; /* End of subject or ending \n assertion (\Z) */ case OP_EODN: if (eptr < md->end_subject - 1 || (eptr == md->end_subject - 1 && *eptr != NEWLINE)) RRETURN(MATCH_NOMATCH); ecode++; break; /* Word boundary assertions */ case OP_NOT_WORD_BOUNDARY: case OP_WORD_BOUNDARY: { /* Find out if the previous and current characters are "word" characters. It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to be "non-word" characters. */ #ifdef SUPPORT_UTF8 if (md->utf8) { if (eptr == md->start_subject) prev_is_word = FALSE; else { const uschar *lastptr = eptr - 1; while((*lastptr & 0xc0) == 0x80) lastptr--; GETCHAR(c, lastptr); prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0; } if (eptr >= md->end_subject) cur_is_word = FALSE; else { GETCHAR(c, eptr); cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0; } } else #endif /* More streamlined when not in UTF-8 mode */ { prev_is_word = (eptr != md->start_subject) && ((md->ctypes[eptr[-1]] & ctype_word) != 0); cur_is_word = (eptr < md->end_subject) && ((md->ctypes[*eptr] & ctype_word) != 0); } /* Now see if the situation is what we want */ if ((*ecode++ == OP_WORD_BOUNDARY)? cur_is_word == prev_is_word : cur_is_word != prev_is_word) RRETURN(MATCH_NOMATCH); } break; /* Match a single character type; inline for speed */ case OP_ANY: if ((ims & PCRE_DOTALL) == 0 && eptr < md->end_subject && *eptr == NEWLINE) RRETURN(MATCH_NOMATCH); if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH); #ifdef SUPPORT_UTF8 if (md->utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; #endif ecode++; break; /* Match a single byte, even in UTF-8 mode. This opcode really does match any byte, even newline, independent of the setting of PCRE_DOTALL. */ case OP_ANYBYTE: if (eptr++ >= md->end_subject) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_NOT_DIGIT: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); if ( #ifdef SUPPORT_UTF8 c < 256 && #endif (md->ctypes[c] & ctype_digit) != 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_DIGIT: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); if ( #ifdef SUPPORT_UTF8 c >= 256 || #endif (md->ctypes[c] & ctype_digit) == 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_NOT_WHITESPACE: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); if ( #ifdef SUPPORT_UTF8 c < 256 && #endif (md->ctypes[c] & ctype_space) != 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_WHITESPACE: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); if ( #ifdef SUPPORT_UTF8 c >= 256 || #endif (md->ctypes[c] & ctype_space) == 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_NOT_WORDCHAR: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); if ( #ifdef SUPPORT_UTF8 c < 256 && #endif (md->ctypes[c] & ctype_word) != 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; case OP_WORDCHAR: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); if ( #ifdef SUPPORT_UTF8 c >= 256 || #endif (md->ctypes[c] & ctype_word) == 0 ) RRETURN(MATCH_NOMATCH); ecode++; break; #ifdef SUPPORT_UCP /* Check the next character by Unicode property. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ case OP_PROP: case OP_NOTPROP: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); { int chartype, rqdtype; int othercase; int category = ucp_findchar(c, &chartype, &othercase); rqdtype = *(++ecode); ecode++; if (rqdtype >= 128) { if ((rqdtype - 128 != category) == (op == OP_PROP)) RRETURN(MATCH_NOMATCH); } else { if ((rqdtype != chartype) == (op == OP_PROP)) RRETURN(MATCH_NOMATCH); } } break; /* Match an extended Unicode sequence. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ case OP_EXTUNI: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); { int chartype; int othercase; int category = ucp_findchar(c, &chartype, &othercase); if (category == ucp_M) RRETURN(MATCH_NOMATCH); while (eptr < md->end_subject) { int len = 1; if (!md->utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } category = ucp_findchar(c, &chartype, &othercase); if (category != ucp_M) break; eptr += len; } } ecode++; break; #endif /* Match a back reference, possibly repeatedly. Look past the end of the item to see if there is repeat information following. The code is similar to that for character classes, but repeated for efficiency. Then obey similar code to character type repeats - written out again for speed. However, if the referenced string is the empty string, always treat it as matched, any number of times (otherwise there could be infinite loops). */ case OP_REF: { offset = GET2(ecode, 1) << 1; /* Doubled ref number */ ecode += 3; /* Advance past item */ /* If the reference is unset, set the length to be longer than the amount of subject left; this ensures that every attempt at a match fails. We can't just fail here, because of the possibility of quantifiers with zero minima. */ length = (offset >= offset_top || md->offset_vector[offset] < 0)? md->end_subject - eptr + 1 : md->offset_vector[offset+1] - md->offset_vector[offset]; /* Set up for repetition, or handle the non-repeated case */ switch (*ecode) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRPLUS: case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: c = *ecode++ - OP_CRSTAR; minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; break; case OP_CRRANGE: case OP_CRMINRANGE: minimize = (*ecode == OP_CRMINRANGE); min = GET2(ecode, 1); max = GET2(ecode, 3); if (max == 0) max = INT_MAX; ecode += 5; break; default: /* No repeat follows */ if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH); eptr += length; continue; /* With the main loop */ } /* If the length of the reference is zero, just continue with the main loop. */ if (length == 0) continue; /* First, ensure the minimum number of matches are present. We get back the length of the reference string explicitly rather than passing the address of eptr, so that eptr can be a register variable. */ for (i = 1; i <= min; i++) { if (!match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH); eptr += length; } /* If min = max, continue at the same level without recursion. They are not both allowed to be zero. */ if (min == max) continue; /* If minimizing, keep trying and advancing the pointer */ if (minimize) { for (fi = min;; fi++) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || !match_ref(offset, eptr, length, md, ims)) RRETURN(MATCH_NOMATCH); eptr += length; } /* Control never gets here */ } /* If maximizing, find the longest string and work backwards */ else { pp = eptr; for (i = min; i < max; i++) { if (!match_ref(offset, eptr, length, md, ims)) break; eptr += length; } while (eptr >= pp) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr -= length; } RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ /* Match a bit-mapped character class, possibly repeatedly. This op code is used when all the characters in the class have values in the range 0-255, and either the matching is caseful, or the characters are in the range 0-127 when UTF-8 processing is enabled. The only difference between OP_CLASS and OP_NCLASS occurs when a data character outside the range is encountered. First, look past the end of the item to see if there is repeat information following. Then obey similar code to character type repeats - written out again for speed. */ case OP_NCLASS: case OP_CLASS: { data = ecode + 1; /* Save for matching */ ecode += 33; /* Advance past the item */ switch (*ecode) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRPLUS: case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: c = *ecode++ - OP_CRSTAR; minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; break; case OP_CRRANGE: case OP_CRMINRANGE: minimize = (*ecode == OP_CRMINRANGE); min = GET2(ecode, 1); max = GET2(ecode, 3); if (max == 0) max = INT_MAX; ecode += 5; break; default: /* No repeat follows */ min = max = 1; break; } /* First, ensure the minimum number of matches are present. */ #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (md->utf8) { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); if (c > 255) { if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); } else { if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } } else #endif /* Not UTF-8 mode */ { for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); c = *eptr++; if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } /* If max == min we can continue with the main loop without the need to recurse. */ if (min == max) continue; /* If minimizing, keep testing the rest of the expression and advancing the pointer while it matches the class. */ if (minimize) { #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (md->utf8) { for (fi = min;; fi++) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); if (c > 255) { if (op == OP_CLASS) RRETURN(MATCH_NOMATCH); } else { if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } } else #endif /* Not UTF-8 mode */ { for (fi = min;; fi++) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); c = *eptr++; if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ } /* If maximizing, find the longest possible run, then work backwards. */ else { pp = eptr; #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (md->utf8) { for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (c > 255) { if (op == OP_CLASS) break; } else { if ((data[c/8] & (1 << (c&7))) == 0) break; } eptr += len; } for (;;) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); } } else #endif /* Not UTF-8 mode */ { for (i = min; i < max; i++) { if (eptr >= md->end_subject) break; c = *eptr; if ((data[c/8] & (1 << (c&7))) == 0) break; eptr++; } while (eptr >= pp) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); eptr--; if (rrc != MATCH_NOMATCH) RRETURN(rrc); } } RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ /* Match an extended character class. This opcode is encountered only in UTF-8 mode, because that's the only time it is compiled. */ #ifdef SUPPORT_UTF8 case OP_XCLASS: { data = ecode + 1 + LINK_SIZE; /* Save for matching */ ecode += GET(ecode, 1); /* Advance past the item */ switch (*ecode) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRPLUS: case OP_CRMINPLUS: case OP_CRQUERY: case OP_CRMINQUERY: c = *ecode++ - OP_CRSTAR; minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; break; case OP_CRRANGE: case OP_CRMINRANGE: minimize = (*ecode == OP_CRMINRANGE); min = GET2(ecode, 1); max = GET2(ecode, 3); if (max == 0) max = INT_MAX; ecode += 5; break; default: /* No repeat follows */ min = max = 1; break; } /* First, ensure the minimum number of matches are present. */ for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); if (!match_xclass(c, data)) RRETURN(MATCH_NOMATCH); } /* If max == min we can continue with the main loop without the need to recurse. */ if (min == max) continue; /* If minimizing, keep testing the rest of the expression and advancing the pointer while it matches the class. */ if (minimize) { for (fi = min;; fi++) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); if (!match_xclass(c, data)) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } /* If maximizing, find the longest possible run, then work backwards. */ else { pp = eptr; for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (!match_xclass(c, data)) break; eptr += len; } for(;;) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr) } RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } #endif /* End of XCLASS */ /* Match a single character, casefully */ case OP_CHAR: #ifdef SUPPORT_UTF8 if (md->utf8) { length = 1; ecode++; GETCHARLEN(fc, ecode, length); if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH); } else #endif /* Non-UTF-8 mode */ { if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH); if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH); ecode += 2; } break; /* Match a single character, caselessly */ case OP_CHARNC: #ifdef SUPPORT_UTF8 if (md->utf8) { length = 1; ecode++; GETCHARLEN(fc, ecode, length); if (length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); /* If the pattern character's value is < 128, we have only one byte, and can use the fast lookup table. */ if (fc < 128) { if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); } /* Otherwise we must pick up the subject character */ else { int dc; GETCHARINC(dc, eptr); ecode += length; /* If we have Unicode property support, we can use it to test the other case of the character, if there is one. The result of ucp_findchar() is < 0 if the char isn't found, and othercase is returned as zero if there isn't one. */ if (fc != dc) { #ifdef SUPPORT_UCP int chartype; int othercase; if (ucp_findchar(fc, &chartype, &othercase) < 0 || dc != othercase) #endif RRETURN(MATCH_NOMATCH); } } } else #endif /* SUPPORT_UTF8 */ /* Non-UTF-8 mode */ { if (md->end_subject - eptr < 1) RRETURN(MATCH_NOMATCH); if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); ecode += 2; } break; /* Match a single character repeatedly; different opcodes share code. */ case OP_EXACT: min = max = GET2(ecode, 1); ecode += 3; goto REPEATCHAR; case OP_UPTO: case OP_MINUPTO: min = 0; max = GET2(ecode, 1); minimize = *ecode == OP_MINUPTO; ecode += 3; goto REPEATCHAR; case OP_STAR: case OP_MINSTAR: case OP_PLUS: case OP_MINPLUS: case OP_QUERY: case OP_MINQUERY: c = *ecode++ - OP_STAR; minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; /* Common code for all repeated single-character matches. We can give up quickly if there are fewer than the minimum number of characters left in the subject. */ REPEATCHAR: #ifdef SUPPORT_UTF8 if (md->utf8) { length = 1; charptr = ecode; GETCHARLEN(fc, ecode, length); if (min * length > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); ecode += length; /* Handle multibyte character matching specially here. There is support for caseless matching if UCP support is present. */ if (length > 1) { int oclength = 0; uschar occhars[8]; #ifdef SUPPORT_UCP int othercase; int chartype; if ((ims & PCRE_CASELESS) != 0 && ucp_findchar(fc, &chartype, &othercase) >= 0 && othercase > 0) oclength = ord2utf8(othercase, occhars); #endif /* SUPPORT_UCP */ for (i = 1; i <= min; i++) { if (memcmp(eptr, charptr, length) == 0) eptr += length; /* Need braces because of following else */ else if (oclength == 0) { RRETURN(MATCH_NOMATCH); } else { if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH); eptr += oclength; } } if (min == max) continue; if (minimize) { for (fi = min;; fi++) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); if (memcmp(eptr, charptr, length) == 0) eptr += length; /* Need braces because of following else */ else if (oclength == 0) { RRETURN(MATCH_NOMATCH); } else { if (memcmp(eptr, occhars, oclength) != 0) RRETURN(MATCH_NOMATCH); eptr += oclength; } } /* Control never gets here */ } else { pp = eptr; for (i = min; i < max; i++) { if (eptr > md->end_subject - length) break; if (memcmp(eptr, charptr, length) == 0) eptr += length; else if (oclength == 0) break; else { if (memcmp(eptr, occhars, oclength) != 0) break; eptr += oclength; } } while (eptr >= pp) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr -= length; } RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } /* If the length of a UTF-8 character is 1, we fall through here, and obey the code as for non-UTF-8 characters below, though in this case the value of fc will always be < 128. */ } else #endif /* SUPPORT_UTF8 */ /* When not in UTF-8 mode, load a single-byte character. */ { if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); fc = *ecode++; } /* The value of fc at this point is always less than 256, though we may or may not be in UTF-8 mode. The code is duplicated for the caseless and caseful cases, for speed, since matching characters is likely to be quite common. First, ensure the minimum number of matches are present. If min = max, continue at the same level without recursing. Otherwise, if minimizing, keep trying the rest of the expression and advancing one matching character if failing, up to the maximum. Alternatively, if maximizing, find the maximum number of characters and work backwards. */ DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max, max, eptr)); if ((ims & PCRE_CASELESS) != 0) { fc = md->lcc[fc]; for (i = 1; i <= min; i++) if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); if (min == max) continue; if (minimize) { for (fi = min;; fi++) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject || fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } else { pp = eptr; for (i = min; i < max; i++) { if (eptr >= md->end_subject || fc != md->lcc[*eptr]) break; eptr++; } while (eptr >= pp) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); eptr--; if (rrc != MATCH_NOMATCH) RRETURN(rrc); } RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } /* Caseful comparisons (includes all multi-byte characters) */ else { for (i = 1; i <= min; i++) if (fc != *eptr++) RRETURN(MATCH_NOMATCH); if (min == max) continue; if (minimize) { for (fi = min;; fi++) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject || fc != *eptr++) RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } else { pp = eptr; for (i = min; i < max; i++) { if (eptr >= md->end_subject || fc != *eptr) break; eptr++; } while (eptr >= pp) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); eptr--; if (rrc != MATCH_NOMATCH) RRETURN(rrc); } RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ /* Match a negated single one-byte character. The character we are checking can be multibyte. */ case OP_NOT: if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); ecode++; GETCHARINCTEST(c, eptr); if ((ims & PCRE_CASELESS) != 0) { #ifdef SUPPORT_UTF8 if (c < 256) #endif c = md->lcc[c]; if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH); } else { if (*ecode++ == c) RRETURN(MATCH_NOMATCH); } break; /* Match a negated single one-byte character repeatedly. This is almost a repeat of the code for a repeated single character, but I haven't found a nice way of commoning these up that doesn't require a test of the positive/negative option for each character match. Maybe that wouldn't add very much to the time taken, but character matching *is* what this is all about... */ case OP_NOTEXACT: min = max = GET2(ecode, 1); ecode += 3; goto REPEATNOTCHAR; case OP_NOTUPTO: case OP_NOTMINUPTO: min = 0; max = GET2(ecode, 1); minimize = *ecode == OP_NOTMINUPTO; ecode += 3; goto REPEATNOTCHAR; case OP_NOTSTAR: case OP_NOTMINSTAR: case OP_NOTPLUS: case OP_NOTMINPLUS: case OP_NOTQUERY: case OP_NOTMINQUERY: c = *ecode++ - OP_NOTSTAR; minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; /* Common code for all repeated single-byte matches. We can give up quickly if there are fewer than the minimum number of bytes left in the subject. */ REPEATNOTCHAR: if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); fc = *ecode++; /* The code is duplicated for the caseless and caseful cases, for speed, since matching characters is likely to be quite common. First, ensure the minimum number of matches are present. If min = max, continue at the same level without recursing. Otherwise, if minimizing, keep trying the rest of the expression and advancing one matching character if failing, up to the maximum. Alternatively, if maximizing, find the maximum number of characters and work backwards. */ DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max, max, eptr)); if ((ims & PCRE_CASELESS) != 0) { fc = md->lcc[fc]; #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (md->utf8) { register int d; for (i = 1; i <= min; i++) { GETCHARINC(d, eptr); if (d < 256) d = md->lcc[d]; if (fc == d) RRETURN(MATCH_NOMATCH); } } else #endif /* Not UTF-8 mode */ { for (i = 1; i <= min; i++) if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); } if (min == max) continue; if (minimize) { #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (md->utf8) { register int d; for (fi = min;; fi++) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); GETCHARINC(d, eptr); if (d < 256) d = md->lcc[d]; if (fi >= max || eptr >= md->end_subject || fc == d) RRETURN(MATCH_NOMATCH); } } else #endif /* Not UTF-8 mode */ { for (fi = min;; fi++) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject || fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ } /* Maximize case */ else { pp = eptr; #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (md->utf8) { register int d; for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(d, eptr, len); if (d < 256) d = md->lcc[d]; if (fc == d) break; eptr += len; } for(;;) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); } } else #endif /* Not UTF-8 mode */ { for (i = min; i < max; i++) { if (eptr >= md->end_subject || fc == md->lcc[*eptr]) break; eptr++; } while (eptr >= pp) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; } } RRETURN(MATCH_NOMATCH); } /* Control never gets here */ } /* Caseful comparisons */ else { #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (md->utf8) { register int d; for (i = 1; i <= min; i++) { GETCHARINC(d, eptr); if (fc == d) RRETURN(MATCH_NOMATCH); } } else #endif /* Not UTF-8 mode */ { for (i = 1; i <= min; i++) if (fc == *eptr++) RRETURN(MATCH_NOMATCH); } if (min == max) continue; if (minimize) { #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (md->utf8) { register int d; for (fi = min;; fi++) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); GETCHARINC(d, eptr); if (fi >= max || eptr >= md->end_subject || fc == d) RRETURN(MATCH_NOMATCH); } } else #endif /* Not UTF-8 mode */ { for (fi = min;; fi++) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject || fc == *eptr++) RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ } /* Maximize case */ else { pp = eptr; #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (md->utf8) { register int d; for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(d, eptr, len); if (fc == d) break; eptr += len; } for(;;) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); } } else #endif /* Not UTF-8 mode */ { for (i = min; i < max; i++) { if (eptr >= md->end_subject || fc == *eptr) break; eptr++; } while (eptr >= pp) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); eptr--; } } RRETURN(MATCH_NOMATCH); } } /* Control never gets here */ /* Match a single character type repeatedly; several different opcodes share code. This is very similar to the code for single characters, but we repeat it in the interests of efficiency. */ case OP_TYPEEXACT: min = max = GET2(ecode, 1); minimize = TRUE; ecode += 3; goto REPEATTYPE; case OP_TYPEUPTO: case OP_TYPEMINUPTO: min = 0; max = GET2(ecode, 1); minimize = *ecode == OP_TYPEMINUPTO; ecode += 3; goto REPEATTYPE; case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEPLUS: case OP_TYPEMINPLUS: case OP_TYPEQUERY: case OP_TYPEMINQUERY: c = *ecode++ - OP_TYPESTAR; minimize = (c & 1) != 0; min = rep_min[c]; /* Pick up values from tables; */ max = rep_max[c]; /* zero for max => infinity */ if (max == 0) max = INT_MAX; /* Common code for all repeated single character type matches. Note that in UTF-8 mode, '.' matches a character of any length, but for the other character types, the valid characters are all one-byte long. */ REPEATTYPE: ctype = *ecode++; /* Code for the character type */ #ifdef SUPPORT_UCP if (ctype == OP_PROP || ctype == OP_NOTPROP) { prop_fail_result = ctype == OP_NOTPROP; prop_type = *ecode++; if (prop_type >= 128) { prop_test_against = prop_type - 128; prop_test_variable = &prop_category; } else { prop_test_against = prop_type; prop_test_variable = &prop_chartype; } } else prop_type = -1; #endif /* First, ensure the minimum number of matches are present. Use inline code for maximizing the speed, and do the type test once at the start (i.e. keep it out of the loop). Also we can test that there are at least the minimum number of bytes before we start. This isn't as effective in UTF-8 mode, but it does no harm. Separate the UTF-8 code completely as that is tidier. Also separate the UCP code, which can be the same for both UTF-8 and single-bytes. */ if (min > md->end_subject - eptr) RRETURN(MATCH_NOMATCH); if (min > 0) { #ifdef SUPPORT_UCP if (prop_type > 0) { for (i = 1; i <= min; i++) { GETCHARINC(c, eptr); prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); if ((*prop_test_variable == prop_test_against) == prop_fail_result) RRETURN(MATCH_NOMATCH); } } /* Match extended Unicode sequences. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ else if (ctype == OP_EXTUNI) { for (i = 1; i <= min; i++) { GETCHARINCTEST(c, eptr); prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH); while (eptr < md->end_subject) { int len = 1; if (!md->utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); if (prop_category != ucp_M) break; eptr += len; } } } else #endif /* SUPPORT_UCP */ /* Handle all other cases when the coding is UTF-8 */ #ifdef SUPPORT_UTF8 if (md->utf8) switch(ctype) { case OP_ANY: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject || (*eptr++ == NEWLINE && (ims & PCRE_DOTALL) == 0)) RRETURN(MATCH_NOMATCH); while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; } break; case OP_ANYBYTE: eptr += min; break; case OP_NOT_DIGIT: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); if (c < 128 && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); } break; case OP_DIGIT: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject || *eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); /* No need to skip more bytes - we know it's a 1-byte character */ } break; case OP_NOT_WHITESPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject || (*eptr < 128 && (md->ctypes[*eptr++] & ctype_space) != 0)) RRETURN(MATCH_NOMATCH); while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; } break; case OP_WHITESPACE: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject || *eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); /* No need to skip more bytes - we know it's a 1-byte character */ } break; case OP_NOT_WORDCHAR: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject || (*eptr < 128 && (md->ctypes[*eptr++] & ctype_word) != 0)) RRETURN(MATCH_NOMATCH); while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; } break; case OP_WORDCHAR: for (i = 1; i <= min; i++) { if (eptr >= md->end_subject || *eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); /* No need to skip more bytes - we know it's a 1-byte character */ } break; default: RRETURN(PCRE_ERROR_INTERNAL); } /* End switch(ctype) */ else #endif /* SUPPORT_UTF8 */ /* Code for the non-UTF-8 case for minimum matching of operators other than OP_PROP and OP_NOTPROP. */ switch(ctype) { case OP_ANY: if ((ims & PCRE_DOTALL) == 0) { for (i = 1; i <= min; i++) if (*eptr++ == NEWLINE) RRETURN(MATCH_NOMATCH); } else eptr += min; break; case OP_ANYBYTE: eptr += min; break; case OP_NOT_DIGIT: for (i = 1; i <= min; i++) if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); break; case OP_DIGIT: for (i = 1; i <= min; i++) if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WHITESPACE: for (i = 1; i <= min; i++) if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WHITESPACE: for (i = 1; i <= min; i++) if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WORDCHAR: for (i = 1; i <= min; i++) if ((md->ctypes[*eptr++] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WORDCHAR: for (i = 1; i <= min; i++) if ((md->ctypes[*eptr++] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); break; default: RRETURN(PCRE_ERROR_INTERNAL); } } /* If min = max, continue at the same level without recursing */ if (min == max) continue; /* If minimizing, we have to test the rest of the pattern before each subsequent match. Again, separate the UTF-8 case for speed, and also separate the UCP cases. */ if (minimize) { #ifdef SUPPORT_UCP if (prop_type > 0) { for (fi = min;; fi++) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); if ((*prop_test_variable == prop_test_against) == prop_fail_result) RRETURN(MATCH_NOMATCH); } } /* Match extended Unicode sequences. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ else if (ctype == OP_EXTUNI) { for (fi = min;; fi++) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINCTEST(c, eptr); prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH); while (eptr < md->end_subject) { int len = 1; if (!md->utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); if (prop_category != ucp_M) break; eptr += len; } } } else #endif /* SUPPORT_UCP */ #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (md->utf8) { for (fi = min;; fi++) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); GETCHARINC(c, eptr); switch(ctype) { case OP_ANY: if ((ims & PCRE_DOTALL) == 0 && c == NEWLINE) RRETURN(MATCH_NOMATCH); break; case OP_ANYBYTE: break; case OP_NOT_DIGIT: if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); break; case OP_DIGIT: if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WHITESPACE: if (c < 256 && (md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WHITESPACE: if (c >= 256 || (md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WORDCHAR: if (c < 256 && (md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WORDCHAR: if (c >= 256 && (md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); break; default: RRETURN(PCRE_ERROR_INTERNAL); } } } else #endif /* Not UTF-8 mode */ { for (fi = min;; fi++) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (fi >= max || eptr >= md->end_subject) RRETURN(MATCH_NOMATCH); c = *eptr++; switch(ctype) { case OP_ANY: if ((ims & PCRE_DOTALL) == 0 && c == NEWLINE) RRETURN(MATCH_NOMATCH); break; case OP_ANYBYTE: break; case OP_NOT_DIGIT: if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH); break; case OP_DIGIT: if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WHITESPACE: if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WHITESPACE: if ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH); break; case OP_NOT_WORDCHAR: if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH); break; case OP_WORDCHAR: if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH); break; default: RRETURN(PCRE_ERROR_INTERNAL); } } } /* Control never gets here */ } /* If maximizing it is worth using inline code for speed, doing the type test once at the start (i.e. keep it out of the loop). Again, keep the UTF-8 and UCP stuff separate. */ else { pp = eptr; /* Remember where we started */ #ifdef SUPPORT_UCP if (prop_type > 0) { for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); if ((*prop_test_variable == prop_test_against) == prop_fail_result) break; eptr+= len; } /* eptr is now past the end of the maximum run */ for(;;) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); } } /* Match extended Unicode sequences. We will get here only if the support is in the binary; otherwise a compile-time error occurs. */ else if (ctype == OP_EXTUNI) { for (i = min; i < max; i++) { if (eptr >= md->end_subject) break; GETCHARINCTEST(c, eptr); prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); if (prop_category == ucp_M) break; while (eptr < md->end_subject) { int len = 1; if (!md->utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); if (prop_category != ucp_M) break; eptr += len; } } /* eptr is now past the end of the maximum run */ for(;;) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ for (;;) /* Move back over one extended */ { int len = 1; BACKCHAR(eptr); if (!md->utf8) c = *eptr; else { GETCHARLEN(c, eptr, len); } prop_category = ucp_findchar(c, &prop_chartype, &prop_othercase); if (prop_category != ucp_M) break; eptr--; } } } else #endif /* SUPPORT_UCP */ #ifdef SUPPORT_UTF8 /* UTF-8 mode */ if (md->utf8) { switch(ctype) { case OP_ANY: /* Special code is required for UTF8, but when the maximum is unlimited we don't need it, so we repeat the non-UTF8 code. This is probably worth it, because .* is quite a common idiom. */ if (max < INT_MAX) { if ((ims & PCRE_DOTALL) == 0) { for (i = min; i < max; i++) { if (eptr >= md->end_subject || *eptr == NEWLINE) break; eptr++; while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; } } else { for (i = min; i < max; i++) { eptr++; while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++; } } } /* Handle unlimited UTF-8 repeat */ else { if ((ims & PCRE_DOTALL) == 0) { for (i = min; i < max; i++) { if (eptr >= md->end_subject || *eptr == NEWLINE) break; eptr++; } break; } else { c = max - min; if (c > md->end_subject - eptr) c = md->end_subject - eptr; eptr += c; } } break; /* The byte case is the same as non-UTF8 */ case OP_ANYBYTE: c = max - min; if (c > md->end_subject - eptr) c = md->end_subject - eptr; eptr += c; break; case OP_NOT_DIGIT: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break; eptr+= len; } break; case OP_DIGIT: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break; eptr+= len; } break; case OP_NOT_WHITESPACE: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break; eptr+= len; } break; case OP_WHITESPACE: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break; eptr+= len; } break; case OP_NOT_WORDCHAR: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break; eptr+= len; } break; case OP_WORDCHAR: for (i = min; i < max; i++) { int len = 1; if (eptr >= md->end_subject) break; GETCHARLEN(c, eptr, len); if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break; eptr+= len; } break; default: RRETURN(PCRE_ERROR_INTERNAL); } /* eptr is now past the end of the maximum run */ for(;;) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); if (rrc != MATCH_NOMATCH) RRETURN(rrc); if (eptr-- == pp) break; /* Stop if tried at original pos */ BACKCHAR(eptr); } } else #endif /* Not UTF-8 mode */ { switch(ctype) { case OP_ANY: if ((ims & PCRE_DOTALL) == 0) { for (i = min; i < max; i++) { if (eptr >= md->end_subject || *eptr == NEWLINE) break; eptr++; } break; } /* For DOTALL case, fall through and treat as \C */ case OP_ANYBYTE: c = max - min; if (c > md->end_subject - eptr) c = md->end_subject - eptr; eptr += c; break; case OP_NOT_DIGIT: for (i = min; i < max; i++) { if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) != 0) break; eptr++; } break; case OP_DIGIT: for (i = min; i < max; i++) { if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_digit) == 0) break; eptr++; } break; case OP_NOT_WHITESPACE: for (i = min; i < max; i++) { if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) != 0) break; eptr++; } break; case OP_WHITESPACE: for (i = min; i < max; i++) { if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_space) == 0) break; eptr++; } break; case OP_NOT_WORDCHAR: for (i = min; i < max; i++) { if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) != 0) break; eptr++; } break; case OP_WORDCHAR: for (i = min; i < max; i++) { if (eptr >= md->end_subject || (md->ctypes[*eptr] & ctype_word) == 0) break; eptr++; } break; default: RRETURN(PCRE_ERROR_INTERNAL); } /* eptr is now past the end of the maximum run */ while (eptr >= pp) { RMATCH(rrc, eptr, ecode, offset_top, md, ims, eptrb, 0); eptr--; if (rrc != MATCH_NOMATCH) RRETURN(rrc); } } /* Get here if we can't make it match with any permitted repetitions */ RRETURN(MATCH_NOMATCH); } /* Control never gets here */ /* There's been some horrible disaster. Since all codes > OP_BRA are for capturing brackets, and there shouldn't be any gaps between 0 and OP_BRA, arrival here can only mean there is something seriously wrong in the code above or the OP_xxx definitions. */ default: DPRINTF(("Unknown opcode %d\n", *ecode)); RRETURN(PCRE_ERROR_UNKNOWN_NODE); } /* Do not stick any code in here without much thought; it is assumed that "continue" in the code above comes out to here to repeat the main loop. */ } /* End of main loop */ /* Control never reaches here */ } /*************************************************************************** **************************************************************************** RECURSION IN THE match() FUNCTION Undefine all the macros that were defined above to handle this. */ #ifdef NO_RECURSE #undef eptr #undef ecode #undef offset_top #undef ims #undef eptrb #undef flags #undef callpat #undef charptr #undef data #undef next #undef pp #undef prev #undef saved_eptr #undef new_recursive #undef cur_is_word #undef condition #undef minimize #undef prev_is_word #undef original_ims #undef ctype #undef length #undef max #undef min #undef number #undef offset #undef op #undef save_capture_last #undef save_offset1 #undef save_offset2 #undef save_offset3 #undef stacksave #undef newptrb #endif /* These two are defined as macros in both cases */ #undef fc #undef fi /*************************************************************************** ***************************************************************************/ /************************************************* * Execute a Regular Expression * *************************************************/ /* This function applies a compiled re to a subject string and picks out portions of the string if it matches. Two elements in the vector are set for each substring: the offsets to the start and end of the substring. Arguments: argument_re points to the compiled expression extra_data points to extra data or is NULL subject points to the subject string length length of subject string (may contain binary zeros) start_offset where to start in the subject string options option bits offsets points to a vector of ints to be filled in with offsets offsetcount the number of elements in the vector Returns: > 0 => success; value is the number of elements filled in = 0 => success, but offsets is not big enough -1 => failed to match < -1 => some kind of unexpected problem */ EXPORT int pcre_exec(const pcre *argument_re, const pcre_extra *extra_data, const char *subject, int length, int start_offset, int options, int *offsets, int offsetcount) { int rc, resetcount, ocount; int first_byte = -1; int req_byte = -1; int req_byte2 = -1; unsigned long int ims = 0; BOOL using_temporary_offsets = FALSE; BOOL anchored; BOOL startline; BOOL first_byte_caseless = FALSE; BOOL req_byte_caseless = FALSE; match_data match_block; const uschar *tables; const uschar *start_bits = NULL; const uschar *start_match = (const uschar *)subject + start_offset; const uschar *end_subject; const uschar *req_byte_ptr = start_match - 1; pcre_study_data internal_study; const pcre_study_data *study; real_pcre internal_re; const real_pcre *external_re = (const real_pcre *)argument_re; const real_pcre *re = external_re; /* Plausibility checks */ if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION; if (re == NULL || subject == NULL || (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL; if (offsetcount < 0) return PCRE_ERROR_BADCOUNT; /* Fish out the optional data from the extra_data structure, first setting the default values. */ study = NULL; match_block.match_limit = MATCH_LIMIT; match_block.callout_data = NULL; /* The table pointer is always in native byte order. */ tables = external_re->tables; if (extra_data != NULL) { register unsigned int flags = extra_data->flags; if ((flags & PCRE_EXTRA_STUDY_DATA) != 0) study = (const pcre_study_data *)extra_data->study_data; if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0) match_block.match_limit = extra_data->match_limit; if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0) match_block.callout_data = extra_data->callout_data; if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables; } /* If the exec call supplied NULL for tables, use the inbuilt ones. This is a feature that makes it possible to save compiled regex and re-use them in other programs later. */ if (tables == NULL) tables = pcre_default_tables; /* Check that the first field in the block is the magic number. If it is not, test for a regex that was compiled on a host of opposite endianness. If this is the case, flipped values are put in internal_re and internal_study if there was study data too. */ if (re->magic_number != MAGIC_NUMBER) { re = try_flipped(re, &internal_re, study, &internal_study); if (re == NULL) return PCRE_ERROR_BADMAGIC; if (study != NULL) study = &internal_study; } /* Set up other data */ anchored = ((re->options | options) & PCRE_ANCHORED) != 0; startline = (re->options & PCRE_STARTLINE) != 0; /* The code starts after the real_pcre block and the capture name table. */ match_block.start_code = (const uschar *)external_re + re->name_table_offset + re->name_count * re->name_entry_size; match_block.start_subject = (const uschar *)subject; match_block.start_offset = start_offset; match_block.end_subject = match_block.start_subject + length; end_subject = match_block.end_subject; match_block.endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0; match_block.utf8 = (re->options & PCRE_UTF8) != 0; match_block.notbol = (options & PCRE_NOTBOL) != 0; match_block.noteol = (options & PCRE_NOTEOL) != 0; match_block.notempty = (options & PCRE_NOTEMPTY) != 0; match_block.partial = (options & PCRE_PARTIAL) != 0; match_block.hitend = FALSE; match_block.recursive = NULL; /* No recursion at top level */ match_block.lcc = tables + lcc_offset; match_block.ctypes = tables + ctypes_offset; /* Partial matching is supported only for a restricted set of regexes at the moment. */ if (match_block.partial && (re->options & PCRE_NOPARTIAL) != 0) return PCRE_ERROR_BADPARTIAL; /* Check a UTF-8 string if required. Unfortunately there's no way of passing back the character offset. */ #ifdef SUPPORT_UTF8 if (match_block.utf8 && (options & PCRE_NO_UTF8_CHECK) == 0) { if (valid_utf8((uschar *)subject, length) >= 0) return PCRE_ERROR_BADUTF8; if (start_offset > 0 && start_offset < length) { int tb = ((uschar *)subject)[start_offset]; if (tb > 127) { tb &= 0xc0; if (tb != 0 && tb != 0xc0) return PCRE_ERROR_BADUTF8_OFFSET; } } } #endif /* The ims options can vary during the matching as a result of the presence of (?ims) items in the pattern. They are kept in a local variable so that restoring at the exit of a group is easy. */ ims = re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL); /* If the expression has got more back references than the offsets supplied can hold, we get a temporary chunk of working store to use during the matching. Otherwise, we can use the vector supplied, rounding down its size to a multiple of 3. */ ocount = offsetcount - (offsetcount % 3); if (re->top_backref > 0 && re->top_backref >= ocount/3) { ocount = re->top_backref * 3 + 3; match_block.offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int)); if (match_block.offset_vector == NULL) return PCRE_ERROR_NOMEMORY; using_temporary_offsets = TRUE; DPRINTF(("Got memory to hold back references\n")); } else match_block.offset_vector = offsets; match_block.offset_end = ocount; match_block.offset_max = (2*ocount)/3; match_block.offset_overflow = FALSE; match_block.capture_last = -1; /* Compute the minimum number of offsets that we need to reset each time. Doing this makes a huge difference to execution time when there aren't many brackets in the pattern. */ resetcount = 2 + re->top_bracket * 2; if (resetcount > offsetcount) resetcount = ocount; /* Reset the working variable associated with each extraction. These should never be used unless previously set, but they get saved and restored, and so we initialize them to avoid reading uninitialized locations. */ if (match_block.offset_vector != NULL) { register int *iptr = match_block.offset_vector + ocount; register int *iend = iptr - resetcount/2 + 1; while (--iptr >= iend) *iptr = -1; } /* Set up the first character to match, if available. The first_byte value is never set for an anchored regular expression, but the anchoring may be forced at run time, so we have to test for anchoring. The first char may be unset for an unanchored pattern, of course. If there's no first char and the pattern was studied, there may be a bitmap of possible first characters. */ if (!anchored) { if ((re->options & PCRE_FIRSTSET) != 0) { first_byte = re->first_byte & 255; if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE) first_byte = match_block.lcc[first_byte]; } else if (!startline && study != NULL && (study->options & PCRE_STUDY_MAPPED) != 0) start_bits = study->start_bits; } /* For anchored or unanchored matches, there may be a "last known required character" set. */ if ((re->options & PCRE_REQCHSET) != 0) { req_byte = re->req_byte & 255; req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0; req_byte2 = (tables + fcc_offset)[req_byte]; /* case flipped */ } /* Loop for handling unanchored repeated matching attempts; for anchored regexs the loop runs just once. */ do { /* Reset the maximum number of extractions we might see. */ if (match_block.offset_vector != NULL) { register int *iptr = match_block.offset_vector; register int *iend = iptr + resetcount; while (iptr < iend) *iptr++ = -1; } /* Advance to a unique first char if possible */ if (first_byte >= 0) { if (first_byte_caseless) while (start_match < end_subject && match_block.lcc[*start_match] != first_byte) start_match++; else while (start_match < end_subject && *start_match != first_byte) start_match++; } /* Or to just after \n for a multiline match if possible */ else if (startline) { if (start_match > match_block.start_subject + start_offset) { while (start_match < end_subject && start_match[-1] != NEWLINE) start_match++; } } /* Or to a non-unique first char after study */ else if (start_bits != NULL) { while (start_match < end_subject) { register unsigned int c = *start_match; if ((start_bits[c/8] & (1 << (c&7))) == 0) start_match++; else break; } } #ifdef DEBUG /* Sigh. Some compilers never learn. */ printf(">>>> Match against: "); pchars(start_match, end_subject - start_match, TRUE, &match_block); printf("\n"); #endif /* If req_byte is set, we know that that character must appear in the subject for the match to succeed. If the first character is set, req_byte must be later in the subject; otherwise the test starts at the match point. This optimization can save a huge amount of backtracking in patterns with nested unlimited repeats that aren't going to match. Writing separate code for cased/caseless versions makes it go faster, as does using an autoincrement and backing off on a match. HOWEVER: when the subject string is very, very long, searching to its end can take a long time, and give bad performance on quite ordinary patterns. This showed up when somebody was matching /^C/ on a 32-megabyte string... so we don't do this when the string is sufficiently long. ALSO: this processing is disabled when partial matching is requested. */ if (req_byte >= 0 && end_subject - start_match < REQ_BYTE_MAX && !match_block.partial) { register const uschar *p = start_match + ((first_byte >= 0)? 1 : 0); /* We don't need to repeat the search if we haven't yet reached the place we found it at last time. */ if (p > req_byte_ptr) { if (req_byte_caseless) { while (p < end_subject) { register int pp = *p++; if (pp == req_byte || pp == req_byte2) { p--; break; } } } else { while (p < end_subject) { if (*p++ == req_byte) { p--; break; } } } /* If we can't find the required character, break the matching loop */ if (p >= end_subject) break; /* If we have found the required character, save the point where we found it, so that we don't search again next time round the loop if the start hasn't passed this character yet. */ req_byte_ptr = p; } } /* When a match occurs, substrings will be set for all internal extractions; we just need to set up the whole thing as substring 0 before returning. If there were too many extractions, set the return code to zero. In the case where we had to get some local store to hold offsets for backreferences, copy those back references that we can. In this case there need not be overflow if certain parts of the pattern were not used. */ match_block.start_match = start_match; match_block.match_call_count = 0; rc = match(start_match, match_block.start_code, 2, &match_block, ims, NULL, match_isgroup); if (rc == MATCH_NOMATCH) { start_match++; #ifdef SUPPORT_UTF8 if (match_block.utf8) while(start_match < end_subject && (*start_match & 0xc0) == 0x80) start_match++; #endif continue; } if (rc != MATCH_MATCH) { DPRINTF((">>>> error: returning %d\n", rc)); return rc; } /* We have a match! Copy the offset information from temporary store if necessary */ if (using_temporary_offsets) { if (offsetcount >= 4) { memcpy(offsets + 2, match_block.offset_vector + 2, (offsetcount - 2) * sizeof(int)); DPRINTF(("Copied offsets from temporary memory\n")); } if (match_block.end_offset_top > offsetcount) match_block.offset_overflow = TRUE; DPRINTF(("Freeing temporary memory\n")); (pcre_free)(match_block.offset_vector); } rc = match_block.offset_overflow? 0 : match_block.end_offset_top/2; if (offsetcount < 2) rc = 0; else { offsets[0] = start_match - match_block.start_subject; offsets[1] = match_block.end_match_ptr - match_block.start_subject; } DPRINTF((">>>> returning %d\n", rc)); return rc; } /* This "while" is the end of the "do" above */ while (!anchored && start_match <= end_subject); if (using_temporary_offsets) { DPRINTF(("Freeing temporary memory\n")); (pcre_free)(match_block.offset_vector); } if (match_block.partial && match_block.hitend) { DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n")); return PCRE_ERROR_PARTIAL; } else { DPRINTF((">>>> returning PCRE_ERROR_NOMATCH\n")); return PCRE_ERROR_NOMATCH; } } /* End of pcre.c */ tomcat-connectors-1.2.41-src/native/iis/pcre/pcregrep.c0000644000000000000020000004124510517277132021304 0ustar rootbin/************************************************* * pcregrep program * *************************************************/ /* This is a grep program that uses the PCRE regular expression library to do its pattern matching. On a Unix or Win32 system it can recurse into directories. Copyright (c) 1997-2004 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. ----------------------------------------------------------------------------- */ #include #include #include #include #include #include "config.h" #include "pcre.h" #define FALSE 0 #define TRUE 1 typedef int BOOL; #define VERSION "3.0 14-Jan-2003" #define MAX_PATTERN_COUNT 100 /************************************************* * Global variables * *************************************************/ static char *pattern_filename = NULL; static int pattern_count = 0; static pcre **pattern_list; static pcre_extra **hints_list; static BOOL count_only = FALSE; static BOOL filenames = TRUE; static BOOL filenames_only = FALSE; static BOOL invert = FALSE; static BOOL number = FALSE; static BOOL recurse = FALSE; static BOOL silent = FALSE; static BOOL whole_lines = FALSE; /* Structure for options and list of them */ typedef struct option_item { int one_char; const char *long_name; const char *help_text; } option_item; static option_item optionlist[] = { { -1, "help", "display this help and exit" }, { 'c', "count", "print only a count of matching lines per FILE" }, { 'h', "no-filename", "suppress the prefixing filename on output" }, { 'i', "ignore-case", "ignore case distinctions" }, { 'l', "files-with-matches", "print only FILE names containing matches" }, { 'n', "line-number", "print line number with output lines" }, { 'r', "recursive", "recursively scan sub-directories" }, { 's', "no-messages", "suppress error messages" }, { 'u', "utf-8", "use UTF-8 mode" }, { 'V', "version", "print version information and exit" }, { 'v', "invert-match", "select non-matching lines" }, { 'x', "line-regex", "force PATTERN to match only whole lines" }, { 'x', "line-regexp", "force PATTERN to match only whole lines" }, { 0, NULL, NULL } }; /************************************************* * Functions for directory scanning * *************************************************/ /* These functions are defined so that they can be made system specific, although at present the only ones are for Unix, Win32, and for "no directory recursion support". */ /************* Directory scanning in Unix ***********/ #if IS_UNIX #include #include #include typedef DIR directory_type; static int isdirectory(char *filename) { struct stat statbuf; if (stat(filename, &statbuf) < 0) return 0; /* In the expectation that opening as a file will fail */ return ((statbuf.st_mode & S_IFMT) == S_IFDIR)? '/' : 0; } static directory_type * opendirectory(char *filename) { return opendir(filename); } static char * readdirectory(directory_type *dir) { for (;;) { struct dirent *dent = readdir(dir); if (dent == NULL) return NULL; if (strcmp(dent->d_name, ".") != 0 && strcmp(dent->d_name, "..") != 0) return dent->d_name; } return NULL; /* Keep compiler happy; never executed */ } static void closedirectory(directory_type *dir) { closedir(dir); } /************* Directory scanning in Win32 ***********/ /* I (Philip Hazel) have no means of testing this code. It was contributed by Lionel Fourquaux. */ #elif HAVE_WIN32API #ifndef STRICT # define STRICT #endif #ifndef WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN #endif #include typedef struct directory_type { HANDLE handle; BOOL first; WIN32_FIND_DATA data; } directory_type; int isdirectory(char *filename) { DWORD attr = GetFileAttributes(filename); if (attr == INVALID_FILE_ATTRIBUTES) return 0; return ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) ? '/' : 0; } directory_type * opendirectory(char *filename) { size_t len; char *pattern; directory_type *dir; DWORD err; len = strlen(filename); pattern = (char *) malloc(len + 3); dir = (directory_type *) malloc(sizeof(*dir)); if ((pattern == NULL) || (dir == NULL)) { fprintf(stderr, "pcregrep: malloc failed\n"); exit(2); } memcpy(pattern, filename, len); memcpy(&(pattern[len]), "\\*", 3); dir->handle = FindFirstFile(pattern, &(dir->data)); if (dir->handle != INVALID_HANDLE_VALUE) { free(pattern); dir->first = TRUE; return dir; } err = GetLastError(); free(pattern); free(dir); errno = (err == ERROR_ACCESS_DENIED) ? EACCES : ENOENT; return NULL; } char * readdirectory(directory_type *dir) { for (;;) { if (!dir->first) { if (!FindNextFile(dir->handle, &(dir->data))) return NULL; } else { dir->first = FALSE; } if (strcmp(dir->data.cFileName, ".") != 0 && strcmp(dir->data.cFileName, "..") != 0) return dir->data.cFileName; } #ifndef _MSC_VER return NULL; /* Keep compiler happy; never executed */ #endif } void closedirectory(directory_type *dir) { FindClose(dir->handle); free(dir); } /************* Directory scanning when we can't do it ***********/ /* The type is void, and apart from isdirectory(), the functions do nothing. */ #else typedef void directory_type; int isdirectory(char *filename) { return FALSE; } directory_type * opendirectory(char *filename) {} char *readdirectory(directory_type *dir) {} void closedirectory(directory_type *dir) {} #endif #if ! HAVE_STRERROR /************************************************* * Provide strerror() for non-ANSI libraries * *************************************************/ /* Some old-fashioned systems still around (e.g. SunOS4) don't have strerror() in their libraries, but can provide the same facility by this simple alternative function. */ extern int sys_nerr; extern char *sys_errlist[]; char * strerror(int n) { if (n < 0 || n >= sys_nerr) return "unknown error number"; return sys_errlist[n]; } #endif /* HAVE_STRERROR */ /************************************************* * Grep an individual file * *************************************************/ static int pcregrep(FILE *in, char *name) { int rc = 1; int linenumber = 0; int count = 0; int offsets[99]; char buffer[BUFSIZ]; while (fgets(buffer, sizeof(buffer), in) != NULL) { BOOL match = FALSE; int i; int length = (int)strlen(buffer); if (length > 0 && buffer[length-1] == '\n') buffer[--length] = 0; linenumber++; for (i = 0; !match && i < pattern_count; i++) { match = pcre_exec(pattern_list[i], hints_list[i], buffer, length, 0, 0, offsets, 99) >= 0; if (match && whole_lines && offsets[1] != length) match = FALSE; } if (match != invert) { if (count_only) count++; else if (filenames_only) { fprintf(stdout, "%s\n", (name == NULL)? "" : name); return 0; } else if (silent) return 0; else { if (name != NULL) fprintf(stdout, "%s:", name); if (number) fprintf(stdout, "%d:", linenumber); fprintf(stdout, "%s\n", buffer); } rc = 0; } } if (count_only) { if (name != NULL) fprintf(stdout, "%s:", name); fprintf(stdout, "%d\n", count); } return rc; } /************************************************* * Grep a file or recurse into a directory * *************************************************/ static int grep_or_recurse(char *filename, BOOL dir_recurse, BOOL show_filenames, BOOL only_one_at_top) { int rc = 1; int sep; FILE *in; /* If the file is a directory and we are recursing, scan each file within it. The scanning code is localized so it can be made system-specific. */ if ((sep = isdirectory(filename)) != 0 && dir_recurse) { char buffer[1024]; char *nextfile; directory_type *dir = opendirectory(filename); if (dir == NULL) { fprintf(stderr, "pcregrep: Failed to open directory %s: %s\n", filename, strerror(errno)); return 2; } while ((nextfile = readdirectory(dir)) != NULL) { int frc; sprintf(buffer, "%.512s%c%.128s", filename, sep, nextfile); frc = grep_or_recurse(buffer, dir_recurse, TRUE, FALSE); if (frc == 0 && rc == 1) rc = 0; } closedirectory(dir); return rc; } /* If the file is not a directory, or we are not recursing, scan it. If this is the first and only argument at top level, we don't show the file name (unless we are only showing the file name). Otherwise, control is via the show_filenames variable. */ in = fopen(filename, "r"); if (in == NULL) { fprintf(stderr, "pcregrep: Failed to open %s: %s\n", filename, strerror(errno)); return 2; } rc = pcregrep(in, (filenames_only || (show_filenames && !only_one_at_top))? filename : NULL); fclose(in); return rc; } /************************************************* * Usage function * *************************************************/ static int usage(int rc) { fprintf(stderr, "Usage: pcregrep [-Vcfhilnrsvx] [long-options] [pattern] [file1 file2 ...]\n"); fprintf(stderr, "Type `pcregrep --help' for more information.\n"); return rc; } /************************************************* * Help function * *************************************************/ static void help(void) { option_item *op; printf("Usage: pcregrep [OPTION]... [PATTERN] [FILE1 FILE2 ...]\n"); printf("Search for PATTERN in each FILE or standard input.\n"); printf("PATTERN must be present if -f is not used.\n"); printf("Example: pcregrep -i 'hello.*world' menu.h main.c\n\n"); printf("Options:\n"); for (op = optionlist; op->one_char != 0; op++) { int n; char s[4]; if (op->one_char > 0) sprintf(s, "-%c,", op->one_char); else strcpy(s, " "); printf(" %s --%s%n", s, op->long_name, &n); n = 30 - n; if (n < 1) n = 1; printf("%.*s%s\n", n, " ", op->help_text); } printf("\n -f or --file=\n"); printf(" Read patterns from instead of using a command line option.\n"); printf(" Trailing white space is removed; blanks lines are ignored.\n"); printf(" There is a maximum of %d patterns.\n", MAX_PATTERN_COUNT); printf("\nWith no FILE, read standard input. If fewer than two FILEs given, assume -h.\n"); printf("Exit status is 0 if any matches, 1 if no matches, and 2 if trouble.\n"); } /************************************************* * Handle an option * *************************************************/ static int handle_option(int letter, int options) { switch(letter) { case -1: help(); exit(0); case 'c': count_only = TRUE; break; case 'h': filenames = FALSE; break; case 'i': options |= PCRE_CASELESS; break; case 'l': filenames_only = TRUE; case 'n': number = TRUE; break; case 'r': recurse = TRUE; break; case 's': silent = TRUE; break; case 'u': options |= PCRE_UTF8; break; case 'v': invert = TRUE; break; case 'x': whole_lines = TRUE; options |= PCRE_ANCHORED; break; case 'V': fprintf(stderr, "pcregrep version %s using ", VERSION); fprintf(stderr, "PCRE version %s\n", pcre_version()); exit(0); break; default: fprintf(stderr, "pcregrep: Unknown option -%c\n", letter); exit(usage(2)); } return options; } /************************************************* * Main program * *************************************************/ int main(int argc, char **argv) { int i, j; int rc = 1; int options = 0; int errptr; const char *error; BOOL only_one_at_top; /* Process the options */ for (i = 1; i < argc; i++) { if (argv[i][0] != '-') break; /* Missing options */ if (argv[i][1] == 0) exit(usage(2)); /* Long name options */ if (argv[i][1] == '-') { option_item *op; if (strncmp(argv[i]+2, "file=", 5) == 0) { pattern_filename = argv[i] + 7; continue; } for (op = optionlist; op->one_char != 0; op++) { if (strcmp(argv[i]+2, op->long_name) == 0) { options = handle_option(op->one_char, options); break; } } if (op->one_char == 0) { fprintf(stderr, "pcregrep: Unknown option %s\n", argv[i]); exit(usage(2)); } } /* One-char options */ else { char *s = argv[i] + 1; while (*s != 0) { if (*s == 'f') { pattern_filename = s + 1; if (pattern_filename[0] == 0) { if (i >= argc - 1) { fprintf(stderr, "pcregrep: File name missing after -f\n"); exit(usage(2)); } pattern_filename = argv[++i]; } break; } else options = handle_option(*s++, options); } } } pattern_list = (pcre **)malloc(MAX_PATTERN_COUNT * sizeof(pcre *)); hints_list = (pcre_extra **)malloc(MAX_PATTERN_COUNT * sizeof(pcre_extra *)); if (pattern_list == NULL || hints_list == NULL) { fprintf(stderr, "pcregrep: malloc failed\n"); return 2; } /* Compile the regular expression(s). */ if (pattern_filename != NULL) { FILE *f = fopen(pattern_filename, "r"); char buffer[BUFSIZ]; if (f == NULL) { fprintf(stderr, "pcregrep: Failed to open %s: %s\n", pattern_filename, strerror(errno)); return 2; } while (fgets(buffer, sizeof(buffer), f) != NULL) { char *s = buffer + (int)strlen(buffer); if (pattern_count >= MAX_PATTERN_COUNT) { fprintf(stderr, "pcregrep: Too many patterns in file (max %d)\n", MAX_PATTERN_COUNT); return 2; } while (s > buffer && isspace((unsigned char)(s[-1]))) s--; if (s == buffer) continue; *s = 0; pattern_list[pattern_count] = pcre_compile(buffer, options, &error, &errptr, NULL); if (pattern_list[pattern_count++] == NULL) { fprintf(stderr, "pcregrep: Error in regex number %d at offset %d: %s\n", pattern_count, errptr, error); return 2; } } fclose(f); } /* If no file name, a single regex must be given inline */ else { if (i >= argc) return usage(2); pattern_list[0] = pcre_compile(argv[i++], options, &error, &errptr, NULL); if (pattern_list[0] == NULL) { fprintf(stderr, "pcregrep: Error in regex at offset %d: %s\n", errptr, error); return 2; } pattern_count++; } /* Study the regular expressions, as we will be running them may times */ for (j = 0; j < pattern_count; j++) { hints_list[j] = pcre_study(pattern_list[j], 0, &error); if (error != NULL) { char s[16]; if (pattern_count == 1) s[0] = 0; else sprintf(s, " number %d", j); fprintf(stderr, "pcregrep: Error while studying regex%s: %s\n", s, error); return 2; } } /* If there are no further arguments, do the business on stdin and exit */ if (i >= argc) return pcregrep(stdin, NULL); /* Otherwise, work through the remaining arguments as files or directories. Pass in the fact that there is only one argument at top level - this suppresses the file name if the argument is not a directory. */ only_one_at_top = (i == argc - 1); if (filenames_only) filenames = TRUE; for (; i < argc; i++) { int frc = grep_or_recurse(argv[i], recurse, filenames, only_one_at_top); if (frc == 0 && rc == 1) rc = 0; } return rc; } /* End */ tomcat-connectors-1.2.41-src/native/iis/pcre/mkinstalldirs0000755000000000000020000000132110517277132022126 0ustar rootbin#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id: mkinstalldirs 467206 2006-10-24 02:45:46Z markt $ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here tomcat-connectors-1.2.41-src/native/iis/pcre/pcre.amd640000644000000000000020000000613711726114766021126 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Microsoft Developer Studio Generated NMAKE File, Based on pcre.dsp # Use Platform SDK: # SetEnv.cmd /X64 /RETAIL # nmake -f pcre.amd64 # CPP=cl.exe RSC=rc.exe OUTDIR=.\Release_amd64 INTDIR=.\Release_amd64 # Begin Custom Macros OutDir=.\Release_amd64 # End Custom Macros ALL : "$(OUTDIR)\pcre.lib" CLEAN : -@erase "$(INTDIR)\get.obj" -@erase "$(INTDIR)\maketables.obj" -@erase "$(INTDIR)\pcre.obj" -@erase "$(INTDIR)\pcre_src.idb" -@erase "$(INTDIR)\pcre_src.pdb" -@erase "$(INTDIR)\study.obj" -@erase "$(OUTDIR)\pcre.lib" "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\pcre.bsc" BSC32_SBRS= \ LIB32=link.exe -lib LIB32_FLAGS=kernel32.lib /nologo /out:"$(OUTDIR)\pcre.lib" LIB32_OBJS= \ "$(INTDIR)\get.obj" \ "$(INTDIR)\maketables.obj" \ "$(INTDIR)\pcre.obj" \ "$(INTDIR)\study.obj" "$(OUTDIR)\pcre.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) $(LIB32) @<< $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) << CPP_PROJ=-nologo -MD -W3 -O2 -Ob2 -Oy- -Zi -EHsc /D "_WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AMD64_=1" -DWIN64 /D "_WIN64" /D "PCRE_STATIC" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\pcre_src" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << SOURCE=.\chartables.hw InputPath=.\chartables.hw ".\chartables.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" < .\chartables.c << SOURCE=.\get.c "$(INTDIR)\get.obj" : $(SOURCE) "$(INTDIR)" ".\config.h" ".\pcre.h" SOURCE=.\maketables.c "$(INTDIR)\maketables.obj" : $(SOURCE) "$(INTDIR)" ".\config.h" ".\pcre.h" SOURCE=.\pcre.c "$(INTDIR)\pcre.obj" : $(SOURCE) "$(INTDIR)" ".\chartables.c" ".\config.h" ".\pcre.h" SOURCE=.\study.c "$(INTDIR)\study.obj" : $(SOURCE) "$(INTDIR)" ".\config.h" ".\pcre.h" SOURCE=.\config.hw InputPath=.\config.hw ".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" < .\config.h << SOURCE=.\pcre.hw InputPath=.\pcre.hw ".\pcre.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" < .\pcre.h << tomcat-connectors-1.2.41-src/native/iis/pcre/dftables.c0000644000000000000020000001326010517277132021255 0ustar rootbin/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* PCRE is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. Written by: Philip Hazel Copyright (c) 1997-2004 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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 is a support program to generate the file chartables.c, containing character tables of various kinds. They are built according to the default C locale and used as the default tables by PCRE. Now that pcre_maketables is a function visible to the outside world, we make use of its code from here in order to be consistent. */ #include #include #include #include "internal.h" #define DFTABLES /* maketables.c notices this */ #include "maketables.c" int main(int argc, char **argv) { int i; FILE *f; const unsigned char *tables = pcre_maketables(); if (argc != 2) { fprintf(stderr, "dftables: one filename argument is required\n"); return 1; } f = fopen(argv[1], "w"); if (f == NULL) { fprintf(stderr, "dftables: failed to open %s for writing\n", argv[1]); return 1; } /* There are two fprintf() calls here, because gcc in pedantic mode complains about the very long string otherwise. */ fprintf(f, "/*************************************************\n" "* Perl-Compatible Regular Expressions *\n" "*************************************************/\n\n" "/* This file is automatically written by the dftables auxiliary \n" "program. If you edit it by hand, you might like to edit the Makefile to \n" "prevent its ever being regenerated.\n\n"); fprintf(f, "This file is #included in the compilation of pcre.c to build the default\n" "character tables which are used when no tables are passed to the compile\n" "function. */\n\n" "static unsigned char pcre_default_tables[] = {\n\n" "/* This table is a lower casing table. */\n\n"); fprintf(f, " "); for (i = 0; i < 256; i++) { if ((i & 7) == 0 && i != 0) fprintf(f, "\n "); fprintf(f, "%3d", *tables++); if (i != 255) fprintf(f, ","); } fprintf(f, ",\n\n"); fprintf(f, "/* This table is a case flipping table. */\n\n"); fprintf(f, " "); for (i = 0; i < 256; i++) { if ((i & 7) == 0 && i != 0) fprintf(f, "\n "); fprintf(f, "%3d", *tables++); if (i != 255) fprintf(f, ","); } fprintf(f, ",\n\n"); fprintf(f, "/* This table contains bit maps for various character classes.\n" "Each map is 32 bytes long and the bits run from the least\n" "significant end of each byte. The classes that have their own\n" "maps are: space, xdigit, digit, upper, lower, word, graph\n" "print, punct, and cntrl. Other classes are built from combinations. */\n\n"); fprintf(f, " "); for (i = 0; i < cbit_length; i++) { if ((i & 7) == 0 && i != 0) { if ((i & 31) == 0) fprintf(f, "\n"); fprintf(f, "\n "); } fprintf(f, "0x%02x", *tables++); if (i != cbit_length - 1) fprintf(f, ","); } fprintf(f, ",\n\n"); fprintf(f, "/* This table identifies various classes of character by individual bits:\n" " 0x%02x white space character\n" " 0x%02x letter\n" " 0x%02x decimal digit\n" " 0x%02x hexadecimal digit\n" " 0x%02x alphanumeric or '_'\n" " 0x%02x regular expression metacharacter or binary zero\n*/\n\n", ctype_space, ctype_letter, ctype_digit, ctype_xdigit, ctype_word, ctype_meta); fprintf(f, " "); for (i = 0; i < 256; i++) { if ((i & 7) == 0 && i != 0) { fprintf(f, " /* "); if (isprint(i-8)) fprintf(f, " %c -", i-8); else fprintf(f, "%3d-", i-8); if (isprint(i-1)) fprintf(f, " %c ", i-1); else fprintf(f, "%3d", i-1); fprintf(f, " */\n "); } fprintf(f, "0x%02x", *tables++); if (i != 255) fprintf(f, ","); } fprintf(f, "};/* "); if (isprint(i-8)) fprintf(f, " %c -", i-8); else fprintf(f, "%3d-", i-8); if (isprint(i-1)) fprintf(f, " %c ", i-1); else fprintf(f, "%3d", i-1); fprintf(f, " */\n\n/* End of chartables.c */\n"); fclose(f); return 0; } /* End of dftables.c */ tomcat-connectors-1.2.41-src/native/iis/pcre/libpcre.pc.in0000644000000000000020000000042210517277132021672 0ustar rootbin# Package Information for pkg-config prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libpcre Description: PCRE - Perl compatible regular expressions C library Version: @PCRE_VERSION@ Libs: -L${libdir} -lpcre Cflags: -I${includedir} tomcat-connectors-1.2.41-src/native/iis/pcre/ucp.h0000644000000000000020000000344710517277132020273 0ustar rootbin/************************************************* * libucp - Unicode Property Table handler * *************************************************/ /* These are the character categories that are returned by ucp_findchar */ enum { ucp_C, /* Other */ ucp_L, /* Letter */ ucp_M, /* Mark */ ucp_N, /* Number */ ucp_P, /* Punctuation */ ucp_S, /* Symbol */ ucp_Z /* Separator */ }; /* These are the detailed character types that are returned by ucp_findchar */ enum { ucp_Cc, /* Control */ ucp_Cf, /* Format */ ucp_Cn, /* Unassigned */ ucp_Co, /* Private use */ ucp_Cs, /* Surrogate */ ucp_Ll, /* Lower case letter */ ucp_Lm, /* Modifier letter */ ucp_Lo, /* Other letter */ ucp_Lt, /* Title case letter */ ucp_Lu, /* Upper case letter */ ucp_Mc, /* Spacing mark */ ucp_Me, /* Enclosing mark */ ucp_Mn, /* Non-spacing mark */ ucp_Nd, /* Decimal number */ ucp_Nl, /* Letter number */ ucp_No, /* Other number */ ucp_Pc, /* Connector punctuation */ ucp_Pd, /* Dash punctuation */ ucp_Pe, /* Close punctuation */ ucp_Pf, /* Final punctuation */ ucp_Pi, /* Initial punctuation */ ucp_Po, /* Other punctuation */ ucp_Ps, /* Open punctuation */ ucp_Sc, /* Currency symbol */ ucp_Sk, /* Modifier symbol */ ucp_Sm, /* Mathematical symbol */ ucp_So, /* Other symbol */ ucp_Zl, /* Line separator */ ucp_Zp, /* Paragraph separator */ ucp_Zs /* Space separator */ }; /* For use in PCRE we make this function static so that there is no conflict if PCRE is linked with an application that makes use of an external version - assuming an external version is ever released... */ static int ucp_findchar(const int, int *, int *); /* End of ucp.h */ tomcat-connectors-1.2.41-src/native/iis/pcre/pcreposix.h0000644000000000000020000000500210517277132021505 0ustar rootbin/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* Copyright (c) 1997-2000 University of Cambridge */ /** * @file include/pcreposix.h * @brief PCRE definitions */ #ifndef _PCREPOSIX_H #define _PCREPOSIX_H /* This is the header for the POSIX wrapper interface to the PCRE Perl- Compatible Regular Expression library. It defines the things POSIX says should be there. I hope. */ /* Have to include stdlib.h in order to ensure that size_t is defined. */ #include /* Allow for C++ users */ #ifdef __cplusplus extern "C" { #endif /* Options defined by POSIX. */ /** Ignore case */ #define REG_ICASE 0x01 /** Don't match newlines with wildcards */ #define REG_NEWLINE 0x02 /** Don't match BOL */ #define REG_NOTBOL 0x04 /** Don't match EOL */ #define REG_NOTEOL 0x08 /* These are not used by PCRE, but by defining them we make it easier to slot PCRE into existing programs that make POSIX calls. */ /** UNUSED! */ #define REG_EXTENDED 0 /** UNUSED! */ #define REG_NOSUB 0 /* Error values. Not all these are relevant or used by the wrapper. */ enum { REG_ASSERT = 1, /* internal error ? */ REG_BADBR, /* invalid repeat counts in {} */ REG_BADPAT, /* pattern error */ REG_BADRPT, /* ? * + invalid */ REG_EBRACE, /* unbalanced {} */ REG_EBRACK, /* unbalanced [] */ REG_ECOLLATE, /* collation error - not relevant */ REG_ECTYPE, /* bad class */ REG_EESCAPE, /* bad escape sequence */ REG_EMPTY, /* empty expression */ REG_EPAREN, /* unbalanced () */ REG_ERANGE, /* bad range inside [] */ REG_ESIZE, /* expression too big */ REG_ESPACE, /* failed to get memory */ REG_ESUBREG, /* bad back reference */ REG_INVARG, /* bad argument */ REG_NOMATCH /* match failed */ }; /* The structure representing a compiled regular expression. */ typedef struct { void *re_pcre; size_t re_nsub; size_t re_erroffset; } regex_t; /* The structure in which a captured offset is returned. */ typedef int regoff_t; typedef struct { regoff_t rm_so; regoff_t rm_eo; } regmatch_t; /* The functions */ extern int regcomp(regex_t *, const char *, int); extern int regexec(const regex_t *, const char *, size_t, regmatch_t *, int); extern size_t regerror(int, const regex_t *, char *, size_t); extern void regfree(regex_t *); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* End of pcreposix.h */ tomcat-connectors-1.2.41-src/native/iis/pcre/pcreposix.c0000644000000000000020000002601710517277132021511 0ustar rootbin/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. See the file Tech.Notes for some information on the internals. This module is a wrapper that provides a POSIX API to the underlying PCRE functions. Written by: Philip Hazel Copyright (c) 1997-2004 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. ----------------------------------------------------------------------------- */ #include "internal.h" #include "pcreposix.h" #include "stdlib.h" /* Corresponding tables of PCRE error messages and POSIX error codes. */ static const char *const estring[] = { ERR1, ERR2, ERR3, ERR4, ERR5, ERR6, ERR7, ERR8, ERR9, ERR10, ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19, ERR20, ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR29, ERR29, ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39, ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47 }; static const int eint[] = { REG_EESCAPE, /* "\\ at end of pattern" */ REG_EESCAPE, /* "\\c at end of pattern" */ REG_EESCAPE, /* "unrecognized character follows \\" */ REG_BADBR, /* "numbers out of order in {} quantifier" */ REG_BADBR, /* "number too big in {} quantifier" */ REG_EBRACK, /* "missing terminating ] for character class" */ REG_ECTYPE, /* "invalid escape sequence in character class" */ REG_ERANGE, /* "range out of order in character class" */ REG_BADRPT, /* "nothing to repeat" */ REG_BADRPT, /* "operand of unlimited repeat could match the empty string" */ REG_ASSERT, /* "internal error: unexpected repeat" */ REG_BADPAT, /* "unrecognized character after (?" */ REG_BADPAT, /* "POSIX named classes are supported only within a class" */ REG_EPAREN, /* "missing )" */ REG_ESUBREG, /* "reference to non-existent subpattern" */ REG_INVARG, /* "erroffset passed as NULL" */ REG_INVARG, /* "unknown option bit(s) set" */ REG_EPAREN, /* "missing ) after comment" */ REG_ESIZE, /* "parentheses nested too deeply" */ REG_ESIZE, /* "regular expression too large" */ REG_ESPACE, /* "failed to get memory" */ REG_EPAREN, /* "unmatched brackets" */ REG_ASSERT, /* "internal error: code overflow" */ REG_BADPAT, /* "unrecognized character after (?<" */ REG_BADPAT, /* "lookbehind assertion is not fixed length" */ REG_BADPAT, /* "malformed number after (?(" */ REG_BADPAT, /* "conditional group containe more than two branches" */ REG_BADPAT, /* "assertion expected after (?(" */ REG_BADPAT, /* "(?R or (?digits must be followed by )" */ REG_ECTYPE, /* "unknown POSIX class name" */ REG_BADPAT, /* "POSIX collating elements are not supported" */ REG_INVARG, /* "this version of PCRE is not compiled with PCRE_UTF8 support" */ REG_BADPAT, /* "spare error" */ REG_BADPAT, /* "character value in \x{...} sequence is too large" */ REG_BADPAT, /* "invalid condition (?(0)" */ REG_BADPAT, /* "\\C not allowed in lookbehind assertion" */ REG_EESCAPE, /* "PCRE does not support \\L, \\l, \\N, \\U, or \\u" */ REG_BADPAT, /* "number after (?C is > 255" */ REG_BADPAT, /* "closing ) for (?C expected" */ REG_BADPAT, /* "recursive call could loop indefinitely" */ REG_BADPAT, /* "unrecognized character after (?P" */ REG_BADPAT, /* "syntax error after (?P" */ REG_BADPAT, /* "two named groups have the same name" */ REG_BADPAT, /* "invalid UTF-8 string" */ REG_BADPAT, /* "support for \\P, \\p, and \\X has not been compiled" */ REG_BADPAT, /* "malformed \\P or \\p sequence" */ REG_BADPAT /* "unknown property name after \\P or \\p" */ }; /* Table of texts corresponding to POSIX error codes */ static const char *const pstring[] = { "", /* Dummy for value 0 */ "internal error", /* REG_ASSERT */ "invalid repeat counts in {}", /* BADBR */ "pattern error", /* BADPAT */ "? * + invalid", /* BADRPT */ "unbalanced {}", /* EBRACE */ "unbalanced []", /* EBRACK */ "collation error - not relevant", /* ECOLLATE */ "bad class", /* ECTYPE */ "bad escape sequence", /* EESCAPE */ "empty expression", /* EMPTY */ "unbalanced ()", /* EPAREN */ "bad range inside []", /* ERANGE */ "expression too big", /* ESIZE */ "failed to get memory", /* ESPACE */ "bad back reference", /* ESUBREG */ "bad argument", /* INVARG */ "match failed" /* NOMATCH */ }; /************************************************* * Translate PCRE text code to int * *************************************************/ /* PCRE compile-time errors are given as strings defined as macros. We can just look them up in a table to turn them into POSIX-style error codes. */ static int pcre_posix_error_code(const char *s) { size_t i; for (i = 0; i < sizeof(estring)/sizeof(char *); i++) if (strcmp(s, estring[i]) == 0) return eint[i]; return REG_ASSERT; } /************************************************* * Translate error code to string * *************************************************/ EXPORT size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size) { const char *message, *addmessage; size_t length, addlength; message = (errcode >= (int)(sizeof(pstring)/sizeof(char *)))? "unknown error code" : pstring[errcode]; length = strlen(message) + 1; addmessage = " at offset "; addlength = (preg != NULL && (int)preg->re_erroffset != -1)? strlen(addmessage) + 6 : 0; if (errbuf_size > 0) { if (addlength > 0 && errbuf_size >= length + addlength) sprintf(errbuf, "%s%s%-6d", message, addmessage, (int)preg->re_erroffset); else { strncpy(errbuf, message, errbuf_size - 1); errbuf[errbuf_size-1] = 0; } } return length + addlength; } /************************************************* * Free store held by a regex * *************************************************/ EXPORT void regfree(regex_t *preg) { (pcre_free)(preg->re_pcre); } /************************************************* * Compile a regular expression * *************************************************/ /* Arguments: preg points to a structure for recording the compiled expression pattern the pattern to compile cflags compilation flags Returns: 0 on success various non-zero codes on failure */ EXPORT int regcomp(regex_t *preg, const char *pattern, int cflags) { const char *errorptr; int erroffset; int options = 0; if ((cflags & REG_ICASE) != 0) options |= PCRE_CASELESS; if ((cflags & REG_NEWLINE) != 0) options |= PCRE_MULTILINE; preg->re_pcre = pcre_compile(pattern, options, &errorptr, &erroffset, NULL); preg->re_erroffset = erroffset; if (preg->re_pcre == NULL) return pcre_posix_error_code(errorptr); preg->re_nsub = pcre_info((const pcre *)preg->re_pcre, NULL, NULL); return 0; } /************************************************* * Match a regular expression * *************************************************/ /* Unfortunately, PCRE requires 3 ints of working space for each captured substring, so we have to get and release working store instead of just using the POSIX structures as was done in earlier releases when PCRE needed only 2 ints. However, if the number of possible capturing brackets is small, use a block of store on the stack, to reduce the use of malloc/free. The threshold is in a macro that can be changed at configure time. */ EXPORT int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags) { int rc; int options = 0; int *ovector = NULL; int small_ovector[POSIX_MALLOC_THRESHOLD * 3]; BOOL allocated_ovector = FALSE; if ((eflags & REG_NOTBOL) != 0) options |= PCRE_NOTBOL; if ((eflags & REG_NOTEOL) != 0) options |= PCRE_NOTEOL; ((regex_t *)preg)->re_erroffset = (size_t)(-1); /* Only has meaning after compile */ if (nmatch > 0) { if (nmatch <= POSIX_MALLOC_THRESHOLD) { ovector = &(small_ovector[0]); } else { ovector = (int *)malloc(sizeof(int) * nmatch * 3); if (ovector == NULL) return REG_ESPACE; allocated_ovector = TRUE; } } rc = pcre_exec((const pcre *)preg->re_pcre, NULL, string, (int)strlen(string), 0, options, ovector, nmatch * 3); if (rc == 0) rc = nmatch; /* All captured slots were filled in */ if (rc >= 0) { size_t i; for (i = 0; i < (size_t)rc; i++) { pmatch[i].rm_so = ovector[i*2]; pmatch[i].rm_eo = ovector[i*2+1]; } if (allocated_ovector) free(ovector); for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1; return 0; } else { if (allocated_ovector) free(ovector); switch(rc) { case PCRE_ERROR_NOMATCH: return REG_NOMATCH; case PCRE_ERROR_NULL: return REG_INVARG; case PCRE_ERROR_BADOPTION: return REG_INVARG; case PCRE_ERROR_BADMAGIC: return REG_INVARG; case PCRE_ERROR_UNKNOWN_NODE: return REG_ASSERT; case PCRE_ERROR_NOMEMORY: return REG_ESPACE; case PCRE_ERROR_MATCHLIMIT: return REG_ESPACE; case PCRE_ERROR_BADUTF8: return REG_INVARG; case PCRE_ERROR_BADUTF8_OFFSET: return REG_INVARG; default: return REG_ASSERT; } } } /* End of pcreposix.c */ tomcat-connectors-1.2.41-src/native/iis/pcre/pcre-config.in0000644000000000000020000000222310517277132022046 0ustar rootbin#!/bin/sh prefix=@prefix@ exec_prefix=@exec_prefix@ exec_prefix_set=no usage="\ Usage: pcre-config [--prefix] [--exec-prefix] [--version] [--libs] [--libs-posix] [--cflags] [--cflags-posix]" if test $# -eq 0; then echo "${usage}" 1>&2 exit 1 fi libR= case `uname -s` in *SunOS*) libR=" -R@libdir@" ;; esac while test $# -gt 0; do case "$1" in -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac case $1 in --prefix=*) prefix=$optarg if test $exec_prefix_set = no ; then exec_prefix=$optarg fi ;; --prefix) echo $prefix ;; --exec-prefix=*) exec_prefix=$optarg exec_prefix_set=yes ;; --exec-prefix) echo $exec_prefix ;; --version) echo @PCRE_VERSION@ ;; --cflags | --cflags-posix) if test @includedir@ != /usr/include ; then includes=-I@includedir@ fi echo $includes ;; --libs-posix) echo -L@libdir@$libR -lpcreposix -lpcre ;; --libs) echo -L@libdir@$libR -lpcre ;; *) echo "${usage}" 1>&2 exit 1 ;; esac shift done tomcat-connectors-1.2.41-src/native/iis/pcre/chartables.hw0000644000000000000020000001604411726114766022006 0ustar rootbin/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This file is automatically written by the dftables auxiliary program. If you edit it by hand, you might like to edit the Makefile to prevent its ever being regenerated. This file is #included in the compilation of pcre.c to build the default character tables which are used when no tables are passed to the compile function. */ static unsigned char pcre_default_tables[] = { /* This table is a lower casing table. */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122,123,124,125,126,127, 128,129,130,131,132,133,134,135, 136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151, 152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167, 168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183, 184,185,186,187,188,189,190,191, 192,193,194,195,196,197,198,199, 200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215, 216,217,218,219,220,221,222,223, 224,225,226,227,228,229,230,231, 232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,247, 248,249,250,251,252,253,254,255, /* This table is a case flipping table. */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103, 104,105,106,107,108,109,110,111, 112,113,114,115,116,117,118,119, 120,121,122, 91, 92, 93, 94, 95, 96, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,123,124,125,126,127, 128,129,130,131,132,133,134,135, 136,137,138,139,140,141,142,143, 144,145,146,147,148,149,150,151, 152,153,154,155,156,157,158,159, 160,161,162,163,164,165,166,167, 168,169,170,171,172,173,174,175, 176,177,178,179,180,181,182,183, 184,185,186,187,188,189,190,191, 192,193,194,195,196,197,198,199, 200,201,202,203,204,205,206,207, 208,209,210,211,212,213,214,215, 216,217,218,219,220,221,222,223, 224,225,226,227,228,229,230,231, 232,233,234,235,236,237,238,239, 240,241,242,243,244,245,246,247, 248,249,250,251,252,253,254,255, /* This table contains bit maps for various character classes. Each map is 32 bytes long and the bits run from the least significant end of each byte. The classes that have their own maps are: space, xdigit, digit, upper, lower, word, graph print, punct, and cntrl. Other classes are built from combinations. */ 0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, 0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03, 0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff, 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc, 0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* This table identifies various classes of character by individual bits: 0x01 white space character 0x02 letter 0x04 decimal digit 0x08 hexadecimal digit 0x10 alphanumeric or '_' 0x80 regular expression metacharacter or binary zero */ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 0- 7 */ 0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /* 8- 15 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 16- 23 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 24- 31 */ 0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /* - ' */ 0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /* ( - / */ 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /* 0 - 7 */ 0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /* 8 - ? */ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* @ - G */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* H - O */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* P - W */ 0x12,0x12,0x12,0x80,0x00,0x00,0x80,0x10, /* X - _ */ 0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /* ` - g */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* h - o */ 0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /* p - w */ 0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /* x -127 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */ /* End of chartables.c */ tomcat-connectors-1.2.41-src/native/iis/pcre/pcre.in0000644000000000000020000002247210517277132020613 0ustar rootbin/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* In its original form, this is the .in file that is transformed by "configure" into pcre.h. Copyright (c) 1997-2004 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. ----------------------------------------------------------------------------- */ #ifndef _PCRE_H #define _PCRE_H /* The file pcre.h is build by "configure". Do not edit it; instead make changes to pcre.in. */ #define PCRE_MAJOR @PCRE_MAJOR@ #define PCRE_MINOR @PCRE_MINOR@ #define PCRE_DATE @PCRE_DATE@ /* Win32 uses DLL by default */ #ifdef _WIN32 # ifdef PCRE_DEFINITION # ifdef DLL_EXPORT # define PCRE_DATA_SCOPE __declspec(dllexport) # endif # else # ifndef PCRE_STATIC # define PCRE_DATA_SCOPE extern __declspec(dllimport) # endif # endif #endif #ifndef PCRE_DATA_SCOPE # define PCRE_DATA_SCOPE extern #endif /* Have to include stdlib.h in order to ensure that size_t is defined; it is needed here for malloc. */ #include /* Allow for C++ users */ #ifdef __cplusplus extern "C" { #endif /* Options */ #define PCRE_CASELESS 0x0001 #define PCRE_MULTILINE 0x0002 #define PCRE_DOTALL 0x0004 #define PCRE_EXTENDED 0x0008 #define PCRE_ANCHORED 0x0010 #define PCRE_DOLLAR_ENDONLY 0x0020 #define PCRE_EXTRA 0x0040 #define PCRE_NOTBOL 0x0080 #define PCRE_NOTEOL 0x0100 #define PCRE_UNGREEDY 0x0200 #define PCRE_NOTEMPTY 0x0400 #define PCRE_UTF8 0x0800 #define PCRE_NO_AUTO_CAPTURE 0x1000 #define PCRE_NO_UTF8_CHECK 0x2000 #define PCRE_AUTO_CALLOUT 0x4000 #define PCRE_PARTIAL 0x8000 /* Exec-time and get/set-time error codes */ #define PCRE_ERROR_NOMATCH (-1) #define PCRE_ERROR_NULL (-2) #define PCRE_ERROR_BADOPTION (-3) #define PCRE_ERROR_BADMAGIC (-4) #define PCRE_ERROR_UNKNOWN_NODE (-5) #define PCRE_ERROR_NOMEMORY (-6) #define PCRE_ERROR_NOSUBSTRING (-7) #define PCRE_ERROR_MATCHLIMIT (-8) #define PCRE_ERROR_CALLOUT (-9) /* Never used by PCRE itself */ #define PCRE_ERROR_BADUTF8 (-10) #define PCRE_ERROR_BADUTF8_OFFSET (-11) #define PCRE_ERROR_PARTIAL (-12) #define PCRE_ERROR_BADPARTIAL (-13) #define PCRE_ERROR_INTERNAL (-14) #define PCRE_ERROR_BADCOUNT (-15) /* Request types for pcre_fullinfo() */ #define PCRE_INFO_OPTIONS 0 #define PCRE_INFO_SIZE 1 #define PCRE_INFO_CAPTURECOUNT 2 #define PCRE_INFO_BACKREFMAX 3 #define PCRE_INFO_FIRSTBYTE 4 #define PCRE_INFO_FIRSTCHAR 4 /* For backwards compatibility */ #define PCRE_INFO_FIRSTTABLE 5 #define PCRE_INFO_LASTLITERAL 6 #define PCRE_INFO_NAMEENTRYSIZE 7 #define PCRE_INFO_NAMECOUNT 8 #define PCRE_INFO_NAMETABLE 9 #define PCRE_INFO_STUDYSIZE 10 #define PCRE_INFO_DEFAULT_TABLES 11 /* Request types for pcre_config() */ #define PCRE_CONFIG_UTF8 0 #define PCRE_CONFIG_NEWLINE 1 #define PCRE_CONFIG_LINK_SIZE 2 #define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD 3 #define PCRE_CONFIG_MATCH_LIMIT 4 #define PCRE_CONFIG_STACKRECURSE 5 #define PCRE_CONFIG_UNICODE_PROPERTIES 6 /* Bit flags for the pcre_extra structure */ #define PCRE_EXTRA_STUDY_DATA 0x0001 #define PCRE_EXTRA_MATCH_LIMIT 0x0002 #define PCRE_EXTRA_CALLOUT_DATA 0x0004 #define PCRE_EXTRA_TABLES 0x0008 /* Types */ struct real_pcre; /* declaration; the definition is private */ typedef struct real_pcre pcre; /* The structure for passing additional data to pcre_exec(). This is defined in such as way as to be extensible. Always add new fields at the end, in order to remain compatible. */ typedef struct pcre_extra { unsigned long int flags; /* Bits for which fields are set */ void *study_data; /* Opaque data from pcre_study() */ unsigned long int match_limit; /* Maximum number of calls to match() */ void *callout_data; /* Data passed back in callouts */ const unsigned char *tables; /* Pointer to character tables */ } pcre_extra; /* The structure for passing out data via the pcre_callout_function. We use a structure so that new fields can be added on the end in future versions, without changing the API of the function, thereby allowing old clients to work without modification. */ typedef struct pcre_callout_block { int version; /* Identifies version of block */ /* ------------------------ Version 0 ------------------------------- */ int callout_number; /* Number compiled into pattern */ int *offset_vector; /* The offset vector */ const char *subject; /* The subject being matched */ int subject_length; /* The length of the subject */ int start_match; /* Offset to start of this match attempt */ int current_position; /* Where we currently are in the subject */ int capture_top; /* Max current capture */ int capture_last; /* Most recently closed capture */ void *callout_data; /* Data passed in with the call */ /* ------------------- Added for Version 1 -------------------------- */ int pattern_position; /* Offset to next item in the pattern */ int next_item_length; /* Length of next item in the pattern */ /* ------------------------------------------------------------------ */ } pcre_callout_block; /* Indirection for store get and free functions. These can be set to alternative malloc/free functions if required. Special ones are used in the non-recursive case for "frames". There is also an optional callout function that is triggered by the (?) regex item. Some magic is required for Win32 DLL; it is null on other OS. For Virtual Pascal, these have to be different again. */ #ifndef VPCOMPAT PCRE_DATA_SCOPE void *(*pcre_malloc)(size_t); PCRE_DATA_SCOPE void (*pcre_free)(void *); PCRE_DATA_SCOPE void *(*pcre_stack_malloc)(size_t); PCRE_DATA_SCOPE void (*pcre_stack_free)(void *); PCRE_DATA_SCOPE int (*pcre_callout)(pcre_callout_block *); #else /* VPCOMPAT */ extern void *pcre_malloc(size_t); extern void pcre_free(void *); extern void *pcre_stack_malloc(size_t); extern void pcre_stack_free(void *); extern int pcre_callout(pcre_callout_block *); #endif /* VPCOMPAT */ /* Exported PCRE functions */ extern pcre *pcre_compile(const char *, int, const char **, int *, const unsigned char *); extern int pcre_config(int, void *); extern int pcre_copy_named_substring(const pcre *, const char *, int *, int, const char *, char *, int); extern int pcre_copy_substring(const char *, int *, int, int, char *, int); extern int pcre_exec(const pcre *, const pcre_extra *, const char *, int, int, int, int *, int); extern void pcre_free_substring(const char *); extern void pcre_free_substring_list(const char **); extern int pcre_fullinfo(const pcre *, const pcre_extra *, int, void *); extern int pcre_get_named_substring(const pcre *, const char *, int *, int, const char *, const char **); extern int pcre_get_stringnumber(const pcre *, const char *); extern int pcre_get_substring(const char *, int *, int, int, const char **); extern int pcre_get_substring_list(const char *, int *, int, const char ***); extern int pcre_info(const pcre *, int *, int *); extern const unsigned char *pcre_maketables(void); extern pcre_extra *pcre_study(const pcre *, int, const char **); extern const char *pcre_version(void); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* End of pcre.h */ tomcat-connectors-1.2.41-src/native/iis/pcre/perltest80000755000000000000020000001134110517277132021203 0ustar rootbin#! /usr/bin/perl # Program for testing regular expressions with perl to check that PCRE handles # them the same. This is the version that supports /8 for UTF-8 testing. It # requires at least Perl 5.6. # Function for turning a string into a string of printing chars. There are # currently problems with UTF-8 strings; this fudges round them. sub pchars { my($t) = ""; if ($utf8) { use utf8; @p = unpack('U*', $_[0]); foreach $c (@p) { if ($c >= 32 && $c < 127) { $t .= chr $c; } else { $t .= sprintf("\\x{%02x}", $c); } } } else { foreach $c (split(//, $_[0])) { if (ord $c >= 32 && ord $c < 127) { $t .= $c; } else { $t .= sprintf("\\x%02x", ord $c); } } } $t; } # Read lines from named file or stdin and write to named file or stdout; lines # consist of a regular expression, in delimiters and optionally followed by # options, followed by a set of test data, terminated by an empty line. # Sort out the input and output files if (@ARGV > 0) { open(INFILE, "<$ARGV[0]") || die "Failed to open $ARGV[0]\n"; $infile = "INFILE"; } else { $infile = "STDIN"; } if (@ARGV > 1) { open(OUTFILE, ">$ARGV[1]") || die "Failed to open $ARGV[1]\n"; $outfile = "OUTFILE"; } else { $outfile = "STDOUT"; } printf($outfile "Perl $] Regular Expressions\n\n"); # Main loop NEXT_RE: for (;;) { printf " re> " if $infile eq "STDIN"; last if ! ($_ = <$infile>); printf $outfile "$_" if $infile ne "STDIN"; next if ($_ eq ""); $pattern = $_; while ($pattern !~ /^\s*(.).*\1/s) { printf " > " if $infile eq "STDIN"; last if ! ($_ = <$infile>); printf $outfile "$_" if $infile ne "STDIN"; $pattern .= $_; } chomp($pattern); $pattern =~ s/\s+$//; # The private /+ modifier means "print $' afterwards". $showrest = ($pattern =~ s/\+(?=[a-z]*$)//); # The private /8 modifier means "operate in UTF-8". Currently, Perl # has bugs that we try to work around using this flag. $utf8 = ($pattern =~ s/8(?=[a-z]*$)//); # Check that the pattern is valid if ($utf8) { use utf8; eval "\$_ =~ ${pattern}"; } else { eval "\$_ =~ ${pattern}"; } if ($@) { printf $outfile "Error: $@"; next NEXT_RE; } # If the /g modifier is present, we want to put a loop round the matching; # otherwise just a single "if". $cmd = ($pattern =~ /g[a-z]*$/)? "while" : "if"; # If the pattern is actually the null string, Perl uses the most recently # executed (and successfully compiled) regex is used instead. This is a # nasty trap for the unwary! The PCRE test suite does contain null strings # in places - if they are allowed through here all sorts of weird and # unexpected effects happen. To avoid this, we replace such patterns with # a non-null pattern that has the same effect. $pattern = "/(?#)/$2" if ($pattern =~ /^(.)\1(.*)$/); # Read data lines and test them for (;;) { printf "data> " if $infile eq "STDIN"; last NEXT_RE if ! ($_ = <$infile>); chomp; printf $outfile "$_\n" if $infile ne "STDIN"; s/\s+$//; s/^\s+//; last if ($_ eq ""); $x = eval "\"$_\""; # To get escapes processed # Empty array for holding results, then do the matching. @subs = (); $pushes = "push \@subs,\$&;" . "push \@subs,\$1;" . "push \@subs,\$2;" . "push \@subs,\$3;" . "push \@subs,\$4;" . "push \@subs,\$5;" . "push \@subs,\$6;" . "push \@subs,\$7;" . "push \@subs,\$8;" . "push \@subs,\$9;" . "push \@subs,\$10;" . "push \@subs,\$11;" . "push \@subs,\$12;" . "push \@subs,\$13;" . "push \@subs,\$14;" . "push \@subs,\$15;" . "push \@subs,\$16;" . "push \@subs,\$'; }"; if ($utf8) { use utf8; eval "${cmd} (\$x =~ ${pattern}) {" . $pushes; } else { eval "${cmd} (\$x =~ ${pattern}) {" . $pushes; } if ($@) { printf $outfile "Error: $@\n"; next NEXT_RE; } elsif (scalar(@subs) == 0) { printf $outfile "No match\n"; } else { while (scalar(@subs) != 0) { printf $outfile (" 0: %s\n", &pchars($subs[0])); printf $outfile (" 0+ %s\n", &pchars($subs[17])) if $showrest; $last_printed = 0; for ($i = 1; $i <= 16; $i++) { if (defined $subs[$i]) { while ($last_printed++ < $i-1) { printf $outfile ("%2d: \n", $last_printed); } printf $outfile ("%2d: %s\n", $i, &pchars($subs[$i])); $last_printed = $i; } } splice(@subs, 0, 18); } } } } printf $outfile "\n"; # End tomcat-connectors-1.2.41-src/native/iis/pcre/README0000644000000000000020000004620510517277132020212 0ustar rootbinREADME file for PCRE (Perl-compatible regular expression library) ----------------------------------------------------------------- The latest release of PCRE is always available from ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.gz Please read the NEWS file if you are upgrading from a previous release. PCRE has its own native API, but a set of "wrapper" functions that are based on the POSIX API are also supplied in the library libpcreposix. Note that this just provides a POSIX calling interface to PCRE: the regular expressions themselves still follow Perl syntax and semantics. The header file for the POSIX-style functions is called pcreposix.h. The official POSIX name is regex.h, but I didn't want to risk possible problems with existing files of that name by distributing it that way. To use it with an existing program that uses the POSIX API, it will have to be renamed or pointed at by a link. If you are using the POSIX interface to PCRE and there is already a POSIX regex library installed on your system, you must take care when linking programs to ensure that they link with PCRE's libpcreposix library. Otherwise they may pick up the "real" POSIX functions of the same name. Documentation for PCRE ---------------------- If you install PCRE in the normal way, you will end up with an installed set of man pages whose names all start with "pcre". The one that is called "pcre" lists all the others. In addition to these man pages, the PCRE documentation is supplied in two other forms; however, as there is no standard place to install them, they are left in the doc directory of the unpacked source distribution. These forms are: 1. Files called doc/pcre.txt, doc/pcregrep.txt, and doc/pcretest.txt. The first of these is a concatenation of the text forms of all the section 3 man pages except those that summarize individual functions. The other two are the text forms of the section 1 man pages for the pcregrep and pcretest commands. Text forms are provided for ease of scanning with text editors or similar tools. 2. A subdirectory called doc/html contains all the documentation in HTML form, hyperlinked in various ways, and rooted in a file called doc/index.html. Contributions by users of PCRE ------------------------------ You can find contributions from PCRE users in the directory ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/Contrib where there is also a README file giving brief descriptions of what they are. Several of them provide support for compiling PCRE on various flavours of Windows systems (I myself do not use Windows). Some are complete in themselves; others are pointers to URLs containing relevant files. Building PCRE on a Unix-like system ----------------------------------- To build PCRE on a Unix-like system, first run the "configure" command from the PCRE distribution directory, with your current directory set to the directory where you want the files to be created. This command is a standard GNU "autoconf" configuration script, for which generic instructions are supplied in INSTALL. Most commonly, people build PCRE within its own distribution directory, and in this case, on many systems, just running "./configure" is sufficient, but the usual methods of changing standard defaults are available. For example: CFLAGS='-O2 -Wall' ./configure --prefix=/opt/local specifies that the C compiler should be run with the flags '-O2 -Wall' instead of the default, and that "make install" should install PCRE under /opt/local instead of the default /usr/local. If you want to build in a different directory, just run "configure" with that directory as current. For example, suppose you have unpacked the PCRE source into /source/pcre/pcre-xxx, but you want to build it in /build/pcre/pcre-xxx: cd /build/pcre/pcre-xxx /source/pcre/pcre-xxx/configure There are some optional features that can be included or omitted from the PCRE library. You can read more about them in the pcrebuild man page. . If you want to make use of the support for UTF-8 character strings in PCRE, you must add --enable-utf8 to the "configure" command. Without it, the code for handling UTF-8 is not included in the library. (Even when included, it still has to be enabled by an option at run time.) . If, in addition to support for UTF-8 character strings, you want to include support for the \P, \p, and \X sequences that recognize Unicode character properties, you must add --enable-unicode-properties to the "configure" command. This adds about 90K to the size of the library (in the form of a property table); only the basic two-letter properties such as Lu are supported. . You can build PCRE to recognized CR or NL as the newline character, instead of whatever your compiler uses for "\n", by adding --newline-is-cr or --newline-is-nl to the "configure" command, respectively. Only do this if you really understand what you are doing. On traditional Unix-like systems, the newline character is NL. . When called via the POSIX interface, PCRE uses malloc() to get additional storage for processing capturing parentheses if there are more than 10 of them. You can increase this threshold by setting, for example, --with-posix-malloc-threshold=20 on the "configure" command. . PCRE has a counter which can be set to limit the amount of resources it uses. If the limit is exceeded during a match, the match fails. The default is ten million. You can change the default by setting, for example, --with-match-limit=500000 on the "configure" command. This is just the default; individual calls to pcre_exec() can supply their own value. There is discussion on the pcreapi man page. . The default maximum compiled pattern size is around 64K. You can increase this by adding --with-link-size=3 to the "configure" command. You can increase it even more by setting --with-link-size=4, but this is unlikely ever to be necessary. If you build PCRE with an increased link size, test 2 (and 5 if you are using UTF-8) will fail. Part of the output of these tests is a representation of the compiled pattern, and this changes with the link size. . You can build PCRE so that its match() function does not call itself recursively. Instead, it uses blocks of data from the heap via special functions pcre_stack_malloc() and pcre_stack_free() to save data that would otherwise be saved on the stack. To build PCRE like this, use --disable-stack-for-recursion on the "configure" command. PCRE runs more slowly in this mode, but it may be necessary in environments with limited stack sizes. The "configure" script builds seven files: . pcre.h is build by copying pcre.in and making substitutions . Makefile is built by copying Makefile.in and making substitutions. . config.h is built by copying config.in and making substitutions. . pcre-config is built by copying pcre-config.in and making substitutions. . libpcre.pc is data for the pkg-config command, built from libpcre.pc.in . libtool is a script that builds shared and/or static libraries . RunTest is a script for running tests Once "configure" has run, you can run "make". It builds two libraries called libpcre and libpcreposix, a test program called pcretest, and the pcregrep command. You can use "make install" to copy these, the public header files pcre.h and pcreposix.h, and the man pages to appropriate live directories on your system, in the normal way. Retrieving configuration information on Unix-like systems --------------------------------------------------------- Running "make install" also installs the command pcre-config, which can be used to recall information about the PCRE configuration and installation. For example: pcre-config --version prints the version number, and pcre-config --libs outputs information about where the library is installed. This command can be included in makefiles for programs that use PCRE, saving the programmer from having to remember too many details. The pkg-config command is another system for saving and retrieving information about installed libraries. Instead of separate commands for each library, a single command is used. For example: pkg-config --cflags pcre The data is held in *.pc files that are installed in a directory called pkgconfig. Shared libraries on Unix-like systems ------------------------------------- The default distribution builds PCRE as two shared libraries and two static libraries, as long as the operating system supports shared libraries. Shared library support relies on the "libtool" script which is built as part of the "configure" process. The libtool script is used to compile and link both shared and static libraries. They are placed in a subdirectory called .libs when they are newly built. The programs pcretest and pcregrep are built to use these uninstalled libraries (by means of wrapper scripts in the case of shared libraries). When you use "make install" to install shared libraries, pcregrep and pcretest are automatically re-built to use the newly installed shared libraries before being installed themselves. However, the versions left in the source directory still use the uninstalled libraries. To build PCRE using static libraries only you must use --disable-shared when configuring it. For example: ./configure --prefix=/usr/gnu --disable-shared Then run "make" in the usual way. Similarly, you can use --disable-static to build only shared libraries. Cross-compiling on a Unix-like system ------------------------------------- You can specify CC and CFLAGS in the normal way to the "configure" command, in order to cross-compile PCRE for some other host. However, during the building process, the dftables.c source file is compiled *and run* on the local host, in order to generate the default character tables (the chartables.c file). It therefore needs to be compiled with the local compiler, not the cross compiler. You can do this by specifying CC_FOR_BUILD (and if necessary CFLAGS_FOR_BUILD) when calling the "configure" command. If they are not specified, they default to the values of CC and CFLAGS. Building on non-Unix systems ---------------------------- For a non-Unix system, read the comments in the file NON-UNIX-USE, though if the system supports the use of "configure" and "make" you may be able to build PCRE in the same way as for Unix systems. PCRE has been compiled on Windows systems and on Macintoshes, but I don't know the details because I don't use those systems. It should be straightforward to build PCRE on any system that has a Standard C compiler, because it uses only Standard C functions. Testing PCRE ------------ To test PCRE on a Unix system, run the RunTest script that is created by the configuring process. (This can also be run by "make runtest", "make check", or "make test".) For other systems, see the instructions in NON-UNIX-USE. The script runs the pcretest test program (which is documented in its own man page) on each of the testinput files (in the testdata directory) in turn, and compares the output with the contents of the corresponding testoutput file. A file called testtry is used to hold the main output from pcretest (testsavedregex is also used as a working file). To run pcretest on just one of the test files, give its number as an argument to RunTest, for example: RunTest 2 The first file can also be fed directly into the perltest script to check that Perl gives the same results. The only difference you should see is in the first few lines, where the Perl version is given instead of the PCRE version. The second set of tests check pcre_fullinfo(), pcre_info(), pcre_study(), pcre_copy_substring(), pcre_get_substring(), pcre_get_substring_list(), error detection, and run-time flags that are specific to PCRE, as well as the POSIX wrapper API. It also uses the debugging flag to check some of the internals of pcre_compile(). If you build PCRE with a locale setting that is not the standard C locale, the character tables may be different (see next paragraph). In some cases, this may cause failures in the second set of tests. For example, in a locale where the isprint() function yields TRUE for characters in the range 128-255, the use of [:isascii:] inside a character class defines a different set of characters, and this shows up in this test as a difference in the compiled code, which is being listed for checking. Where the comparison test output contains [\x00-\x7f] the test will contain [\x00-\xff], and similarly in some other cases. This is not a bug in PCRE. The third set of tests checks pcre_maketables(), the facility for building a set of character tables for a specific locale and using them instead of the default tables. The tests make use of the "fr_FR" (French) locale. Before running the test, the script checks for the presence of this locale by running the "locale" command. If that command fails, or if it doesn't include "fr_FR" in the list of available locales, the third test cannot be run, and a comment is output to say why. If running this test produces instances of the error ** Failed to set locale "fr_FR" in the comparison output, it means that locale is not available on your system, despite being listed by "locale". This does not mean that PCRE is broken. The fourth test checks the UTF-8 support. It is not run automatically unless PCRE is built with UTF-8 support. To do this you must set --enable-utf8 when running "configure". This file can be also fed directly to the perltest script, provided you are running Perl 5.8 or higher. (For Perl 5.6, a small patch, commented in the script, can be be used.) The fifth test checks error handling with UTF-8 encoding, and internal UTF-8 features of PCRE that are not relevant to Perl. The sixth and final test checks the support for Unicode character properties. It it not run automatically unless PCRE is built with Unicode property support. To to this you must set --enable-unicode-properties when running "configure". Character tables ---------------- PCRE uses four tables for manipulating and identifying characters whose values are less than 256. The final argument of the pcre_compile() function is a pointer to a block of memory containing the concatenated tables. A call to pcre_maketables() can be used to generate a set of tables in the current locale. If the final argument for pcre_compile() is passed as NULL, a set of default tables that is built into the binary is used. The source file called chartables.c contains the default set of tables. This is not supplied in the distribution, but is built by the program dftables (compiled from dftables.c), which uses the ANSI C character handling functions such as isalnum(), isalpha(), isupper(), islower(), etc. to build the table sources. This means that the default C locale which is set for your system will control the contents of these default tables. You can change the default tables by editing chartables.c and then re-building PCRE. If you do this, you should probably also edit Makefile to ensure that the file doesn't ever get re-generated. The first two 256-byte tables provide lower casing and case flipping functions, respectively. The next table consists of three 32-byte bit maps which identify digits, "word" characters, and white space, respectively. These are used when building 32-byte bit maps that represent character classes. The final 256-byte table has bits indicating various character types, as follows: 1 white space character 2 letter 4 decimal digit 8 hexadecimal digit 16 alphanumeric or '_' 128 regular expression metacharacter or binary zero You should not alter the set of characters that contain the 128 bit, as that will cause PCRE to malfunction. Manifest -------- The distribution should contain the following files: (A) The actual source files of the PCRE library functions and their headers: dftables.c auxiliary program for building chartables.c get.c ) maketables.c ) study.c ) source of the functions pcre.c ) in the library pcreposix.c ) printint.c ) ucp.c ) ucp.h ) source for the code that is used for ucpinternal.h ) Unicode property handling ucptable.c ) ucptypetable.c ) pcre.in "source" for the header for the external API; pcre.h is built from this by "configure" pcreposix.h header for the external POSIX wrapper API internal.h header for internal use config.in template for config.h, which is built by configure (B) Auxiliary files: AUTHORS information about the author of PCRE ChangeLog log of changes to the code INSTALL generic installation instructions LICENCE conditions for the use of PCRE COPYING the same, using GNU's standard name Makefile.in template for Unix Makefile, which is built by configure NEWS important changes in this release NON-UNIX-USE notes on building PCRE on non-Unix systems README this file RunTest.in template for a Unix shell script for running tests config.guess ) files used by libtool, config.sub ) used only when building a shared library configure a configuring shell script (built by autoconf) configure.in the autoconf input used to build configure doc/Tech.Notes notes on the encoding doc/*.3 man page sources for the PCRE functions doc/*.1 man page sources for pcregrep and pcretest doc/html/* HTML documentation doc/pcre.txt plain text version of the man pages doc/pcretest.txt plain text documentation of test program doc/perltest.txt plain text documentation of Perl test program install-sh a shell script for installing files libpcre.pc.in "source" for libpcre.pc for pkg-config ltmain.sh file used to build a libtool script mkinstalldirs script for making install directories pcretest.c comprehensive test program pcredemo.c simple demonstration of coding calls to PCRE perltest Perl test program pcregrep.c source of a grep utility that uses PCRE pcre-config.in source of script which retains PCRE information testdata/testinput1 test data, compatible with Perl testdata/testinput2 test data for error messages and non-Perl things testdata/testinput3 test data for locale-specific tests testdata/testinput4 test data for UTF-8 tests compatible with Perl testdata/testinput5 test data for other UTF-8 tests testdata/testinput6 test data for Unicode property support tests testdata/testoutput1 test results corresponding to testinput1 testdata/testoutput2 test results corresponding to testinput2 testdata/testoutput3 test results corresponding to testinput3 testdata/testoutput4 test results corresponding to testinput4 testdata/testoutput5 test results corresponding to testinput5 testdata/testoutput6 test results corresponding to testinput6 (C) Auxiliary files for Win32 DLL dll.mk libpcre.def libpcreposix.def pcre.def (D) Auxiliary file for VPASCAL makevp.bat Philip Hazel September 2004 tomcat-connectors-1.2.41-src/native/iis/pcre/pcre.ia640000644000000000000020000000616111726114766020753 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Microsoft Developer Studio Generated NMAKE File, Based on pcre.dsp # Use Platform SDK: # SetEnv.cmd /SRV64 /RETAIL # nmake -f pcre.amd64 # CPP=cl.exe RSC=rc.exe OUTDIR=.\Release_ia64 INTDIR=.\Release_ia64 # Begin Custom Macros OutDir=.\Release_ia64 # End Custom Macros ALL : "$(OUTDIR)\pcre.lib" CLEAN : -@erase "$(INTDIR)\get.obj" -@erase "$(INTDIR)\maketables.obj" -@erase "$(INTDIR)\pcre.obj" -@erase "$(INTDIR)\pcre_src.idb" -@erase "$(INTDIR)\pcre_src.pdb" -@erase "$(INTDIR)\study.obj" -@erase "$(OUTDIR)\pcre.lib" "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" BSC32=bscmake.exe BSC32_FLAGS=kernel32.lib /nologo /o"$(OUTDIR)\pcre.bsc" BSC32_SBRS= \ LIB32=link.exe -lib LIB32_FLAGS=/nologo /out:"$(OUTDIR)\pcre.lib" LIB32_OBJS= \ "$(INTDIR)\get.obj" \ "$(INTDIR)\maketables.obj" \ "$(INTDIR)\pcre.obj" \ "$(INTDIR)\study.obj" "$(OUTDIR)\pcre.lib" : "$(OUTDIR)" $(DEF_FILE) $(LIB32_OBJS) $(LIB32) @<< $(LIB32_FLAGS) $(DEF_FLAGS) $(LIB32_OBJS) << CPP_PROJ=-nologo -MD -W3 -O2 -Ob2 -Oy- -Zi -EHsc /D "_WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_IA64_=1" -DWIN64 /D "_WIN64" /Wp64 /FIPRE64PRA.H /D "PCRE_STATIC" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\pcre_src" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << SOURCE=.\chartables.hw InputPath=.\chartables.hw ".\chartables.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" < .\chartables.c << SOURCE=.\get.c "$(INTDIR)\get.obj" : $(SOURCE) "$(INTDIR)" ".\config.h" ".\pcre.h" SOURCE=.\maketables.c "$(INTDIR)\maketables.obj" : $(SOURCE) "$(INTDIR)" ".\config.h" ".\pcre.h" SOURCE=.\pcre.c "$(INTDIR)\pcre.obj" : $(SOURCE) "$(INTDIR)" ".\chartables.c" ".\config.h" ".\pcre.h" SOURCE=.\study.c "$(INTDIR)\study.obj" : $(SOURCE) "$(INTDIR)" ".\config.h" ".\pcre.h" SOURCE=.\config.hw InputPath=.\config.hw ".\config.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" < .\config.h << SOURCE=.\pcre.hw InputPath=.\pcre.hw ".\pcre.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" < .\pcre.h << tomcat-connectors-1.2.41-src/native/iis/pcre/RunTest.in0000644000000000000020000001120611111623220021237 0ustar rootbin#! /bin/sh # This file is generated by configure from RunTest.in. Make any changes # to that file. # Run PCRE tests cf=diff testdata=@top_srcdir@/testdata # Select which tests to run; if no selection, run all do1=no do2=no do3=no do4=no do5=no do6=no while [ $# -gt 0 ] ; do case $1 in 1) do1=yes;; 2) do2=yes;; 3) do3=yes;; 4) do4=yes;; 5) do5=yes;; 6) do6=yes;; *) echo "Unknown test number $1"; exit 1;; esac shift done if [ "@LINK_SIZE@" != "" -a "@LINK_SIZE@" != "-DLINK_SIZE=2" ] ; then if [ $do2 = yes ] ; then echo "Can't run test 2 with an internal link size other than 2" exit 1 fi if [ $do5 = yes ] ; then echo "Can't run test 5 with an internal link size other than 2" exit 1 fi if [ $do6 = yes ] ; then echo "Can't run test 6 with an internal link size other than 2" exit 1 fi fi if [ "@UTF8@" = "" ] ; then if [ $do4 = yes ] ; then echo "Can't run test 4 because UTF-8 support is not configured" exit 1 fi if [ $do5 = yes ] ; then echo "Can't run test 5 because UTF-8 support is not configured" exit 1 fi if [ $do6 = yes ] ; then echo "Can't run test 6 because UTF-8 support is not configured" exit 1 fi fi if [ "@UCP@" = "" ] ; then if [ $do6 = yes ] ; then echo "Can't run test 6 because Unicode property support is not configured" exit 1 fi fi if [ $do1 = no -a $do2 = no -a $do3 = no -a $do4 = no -a \ $do5 = no -a $do6 = no ] ; then do1=yes do2=yes do3=yes if [ "@UTF8@" != "" ] ; then do4=yes; fi if [ "@UTF8@" != "" ] ; then do5=yes; fi if [ "@UTF8@" != "" -a "@UCP@" != "" ] ; then do6=yes; fi fi # Show which release ./pcretest /dev/null # Primary test, Perl-compatible if [ $do1 = yes ] ; then echo "Test 1: main functionality (Perl compatible)" ./pcretest $testdata/testinput1 testtry if [ $? = 0 ] ; then $cf testtry $testdata/testoutput1 if [ $? != 0 ] ; then exit 1; fi echo " " else exit 1 fi fi # PCRE tests that are not Perl-compatible - API & error tests, mostly if [ $do2 = yes ] ; then if [ "@LINK_SIZE@" = "" -o "@LINK_SIZE@" = "-DLINK_SIZE=2" ] ; then echo "Test 2: API and error handling (not Perl compatible)" ./pcretest -i $testdata/testinput2 testtry if [ $? = 0 ] ; then $cf testtry $testdata/testoutput2 if [ $? != 0 ] ; then exit 1; fi else exit 1 fi else echo Test 2 skipped for link size other than 2 \(@LINK_SIZE@\) fi fi if [ $do1 = yes -a $do2 = yes ] ; then echo " " echo "The two main tests ran OK" echo " " fi # Locale-specific tests, provided the "fr_FR" locale is available if [ $do3 = yes ] ; then locale -a | grep '^fr_FR$' >/dev/null if [ $? -eq 0 ] ; then echo "Test 3: locale-specific features (using 'fr_FR' locale)" ./pcretest $testdata/testinput3 testtry if [ $? = 0 ] ; then $cf testtry $testdata/testoutput3 if [ $? != 0 ] ; then echo " " echo "Locale test did not run entirely successfully." echo "This usually means that there is a problem with the locale" echo "settings rather than a bug in PCRE." else echo "Locale test ran OK" fi echo " " else exit 1 fi else echo "Cannot test locale-specific features - 'fr_FR' locale not found," echo "or the \"locale\" command is not available to check for it." echo " " fi fi # Additional tests for UTF8 support if [ $do4 = yes ] ; then echo "Test 4: UTF-8 support (Perl compatible)" ./pcretest $testdata/testinput4 testtry if [ $? = 0 ] ; then $cf testtry $testdata/testoutput4 if [ $? != 0 ] ; then exit 1; fi else exit 1 fi echo "UTF8 test ran OK" echo " " fi if [ $do5 = yes ] ; then if [ "@LINK_SIZE@" = "" -o "@LINK_SIZE@" = "-DLINK_SIZE=2" ] ; then echo "Test 5: API and internals for UTF-8 support (not Perl compatible)" ./pcretest $testdata/testinput5 testtry if [ $? = 0 ] ; then $cf testtry $testdata/testoutput5 if [ $? != 0 ] ; then exit 1; fi else exit 1 fi echo "UTF8 internals test ran OK" echo " " else echo Test 5 skipped for link size other than 2 \(@LINK_SIZE@\) fi fi if [ $do6 = yes ] ; then if [ "@LINK_SIZE@" = "" -o "@LINK_SIZE@" = "-DLINK_SIZE=2" ] ; then echo "Test 6: Unicode property support" ./pcretest $testdata/testinput6 testtry if [ $? = 0 ] ; then $cf testtry $testdata/testoutput6 if [ $? != 0 ] ; then exit 1; fi else exit 1 fi echo "Unicode properties test ran OK" echo " " else echo Test 6 skipped for link size other than 2 \(@LINK_SIZE@\) fi fi # End tomcat-connectors-1.2.41-src/native/iis/pcre/study.c0000644000000000000020000003412510517277132020644 0ustar rootbin/************************************************* * Perl-Compatible Regular Expressions * *************************************************/ /* This is a library of functions to support regular expressions whose syntax and semantics are as close as possible to those of the Perl 5 language. See the file Tech.Notes for some information on the internals. Written by: Philip Hazel Copyright (c) 1997-2004 University of Cambridge ----------------------------------------------------------------------------- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of the University of Cambridge nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 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 COPYRIGHT OWNER OR 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. ----------------------------------------------------------------------------- */ /* Include the internals header, which itself includes Standard C headers plus the external pcre header. */ #include "internal.h" /************************************************* * Set a bit and maybe its alternate case * *************************************************/ /* Given a character, set its bit in the table, and also the bit for the other version of a letter if we are caseless. Arguments: start_bits points to the bit map c is the character caseless the caseless flag cd the block with char table pointers Returns: nothing */ static void set_bit(uschar *start_bits, unsigned int c, BOOL caseless, compile_data *cd) { start_bits[c/8] |= (1 << (c&7)); if (caseless && (cd->ctypes[c] & ctype_letter) != 0) start_bits[cd->fcc[c]/8] |= (1 << (cd->fcc[c]&7)); } /************************************************* * Create bitmap of starting chars * *************************************************/ /* This function scans a compiled unanchored expression and attempts to build a bitmap of the set of initial characters. If it can't, it returns FALSE. As time goes by, we may be able to get more clever at doing this. Arguments: code points to an expression start_bits points to a 32-byte table, initialized to 0 caseless the current state of the caseless flag utf8 TRUE if in UTF-8 mode cd the block with char table pointers Returns: TRUE if table built, FALSE otherwise */ static BOOL set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless, BOOL utf8, compile_data *cd) { register int c; /* This next statement and the later reference to dummy are here in order to trick the optimizer of the IBM C compiler for OS/2 into generating correct code. Apparently IBM isn't going to fix the problem, and we would rather not disable optimization (in this module it actually makes a big difference, and the pcre module can use all the optimization it can get). */ volatile int dummy; do { const uschar *tcode = code + 1 + LINK_SIZE; BOOL try_next = TRUE; while (try_next) { /* If a branch starts with a bracket or a positive lookahead assertion, recurse to set bits from within them. That's all for this branch. */ if ((int)*tcode >= OP_BRA || *tcode == OP_ASSERT) { if (!set_start_bits(tcode, start_bits, caseless, utf8, cd)) return FALSE; try_next = FALSE; } else switch(*tcode) { default: return FALSE; /* Skip over callout */ case OP_CALLOUT: tcode += 2 + 2*LINK_SIZE; break; /* Skip over extended extraction bracket number */ case OP_BRANUMBER: tcode += 3; break; /* Skip over lookbehind and negative lookahead assertions */ case OP_ASSERT_NOT: case OP_ASSERTBACK: case OP_ASSERTBACK_NOT: do tcode += GET(tcode, 1); while (*tcode == OP_ALT); tcode += 1+LINK_SIZE; break; /* Skip over an option setting, changing the caseless flag */ case OP_OPT: caseless = (tcode[1] & PCRE_CASELESS) != 0; tcode += 2; break; /* BRAZERO does the bracket, but carries on. */ case OP_BRAZERO: case OP_BRAMINZERO: if (!set_start_bits(++tcode, start_bits, caseless, utf8, cd)) return FALSE; dummy = 1; do tcode += GET(tcode,1); while (*tcode == OP_ALT); tcode += 1+LINK_SIZE; break; /* Single-char * or ? sets the bit and tries the next item */ case OP_STAR: case OP_MINSTAR: case OP_QUERY: case OP_MINQUERY: set_bit(start_bits, tcode[1], caseless, cd); tcode += 2; #ifdef SUPPORT_UTF8 if (utf8) while ((*tcode & 0xc0) == 0x80) tcode++; #endif break; /* Single-char upto sets the bit and tries the next */ case OP_UPTO: case OP_MINUPTO: set_bit(start_bits, tcode[3], caseless, cd); tcode += 4; #ifdef SUPPORT_UTF8 if (utf8) while ((*tcode & 0xc0) == 0x80) tcode++; #endif break; /* At least one single char sets the bit and stops */ case OP_EXACT: /* Fall through */ tcode += 2; case OP_CHAR: case OP_CHARNC: case OP_PLUS: case OP_MINPLUS: set_bit(start_bits, tcode[1], caseless, cd); try_next = FALSE; break; /* Single character type sets the bits and stops */ case OP_NOT_DIGIT: for (c = 0; c < 32; c++) start_bits[c] |= ~cd->cbits[c+cbit_digit]; try_next = FALSE; break; case OP_DIGIT: for (c = 0; c < 32; c++) start_bits[c] |= cd->cbits[c+cbit_digit]; try_next = FALSE; break; case OP_NOT_WHITESPACE: for (c = 0; c < 32; c++) start_bits[c] |= ~cd->cbits[c+cbit_space]; try_next = FALSE; break; case OP_WHITESPACE: for (c = 0; c < 32; c++) start_bits[c] |= cd->cbits[c+cbit_space]; try_next = FALSE; break; case OP_NOT_WORDCHAR: for (c = 0; c < 32; c++) start_bits[c] |= ~cd->cbits[c+cbit_word]; try_next = FALSE; break; case OP_WORDCHAR: for (c = 0; c < 32; c++) start_bits[c] |= cd->cbits[c+cbit_word]; try_next = FALSE; break; /* One or more character type fudges the pointer and restarts, knowing it will hit a single character type and stop there. */ case OP_TYPEPLUS: case OP_TYPEMINPLUS: tcode++; break; case OP_TYPEEXACT: tcode += 3; break; /* Zero or more repeats of character types set the bits and then try again. */ case OP_TYPEUPTO: case OP_TYPEMINUPTO: tcode += 2; /* Fall through */ case OP_TYPESTAR: case OP_TYPEMINSTAR: case OP_TYPEQUERY: case OP_TYPEMINQUERY: switch(tcode[1]) { case OP_ANY: return FALSE; case OP_NOT_DIGIT: for (c = 0; c < 32; c++) start_bits[c] |= ~cd->cbits[c+cbit_digit]; break; case OP_DIGIT: for (c = 0; c < 32; c++) start_bits[c] |= cd->cbits[c+cbit_digit]; break; case OP_NOT_WHITESPACE: for (c = 0; c < 32; c++) start_bits[c] |= ~cd->cbits[c+cbit_space]; break; case OP_WHITESPACE: for (c = 0; c < 32; c++) start_bits[c] |= cd->cbits[c+cbit_space]; break; case OP_NOT_WORDCHAR: for (c = 0; c < 32; c++) start_bits[c] |= ~cd->cbits[c+cbit_word]; break; case OP_WORDCHAR: for (c = 0; c < 32; c++) start_bits[c] |= cd->cbits[c+cbit_word]; break; } tcode += 2; break; /* Character class where all the information is in a bit map: set the bits and either carry on or not, according to the repeat count. If it was a negative class, and we are operating with UTF-8 characters, any byte with a value >= 0xc4 is a potentially valid starter because it starts a character with a value > 255. */ case OP_NCLASS: if (utf8) { start_bits[24] |= 0xf0; /* Bits for 0xc4 - 0xc8 */ memset(start_bits+25, 0xff, 7); /* Bits for 0xc9 - 0xff */ } /* Fall through */ case OP_CLASS: { tcode++; /* In UTF-8 mode, the bits in a bit map correspond to character values, not to byte values. However, the bit map we are constructing is for byte values. So we have to do a conversion for characters whose value is > 127. In fact, there are only two possible starting bytes for characters in the range 128 - 255. */ if (utf8) { for (c = 0; c < 16; c++) start_bits[c] |= tcode[c]; for (c = 128; c < 256; c++) { if ((tcode[c/8] && (1 << (c&7))) != 0) { int d = (c >> 6) | 0xc0; /* Set bit for this starter */ start_bits[d/8] |= (1 << (d&7)); /* and then skip on to the */ c = (c & 0xc0) + 0x40 - 1; /* next relevant character. */ } } } /* In non-UTF-8 mode, the two bit maps are completely compatible. */ else { for (c = 0; c < 32; c++) start_bits[c] |= tcode[c]; } /* Advance past the bit map, and act on what follows */ tcode += 32; switch (*tcode) { case OP_CRSTAR: case OP_CRMINSTAR: case OP_CRQUERY: case OP_CRMINQUERY: tcode++; break; case OP_CRRANGE: case OP_CRMINRANGE: if (((tcode[1] << 8) + tcode[2]) == 0) tcode += 5; else try_next = FALSE; break; default: try_next = FALSE; break; } } break; /* End of bitmap class handling */ } /* End of switch */ } /* End of try_next loop */ code += GET(code, 1); /* Advance to next branch */ } while (*code == OP_ALT); return TRUE; } /************************************************* * Study a compiled expression * *************************************************/ /* This function is handed a compiled expression that it must study to produce information that will speed up the matching. It returns a pcre_extra block which then gets handed back to pcre_exec(). Arguments: re points to the compiled expression options contains option bits errorptr points to where to place error messages; set NULL unless error Returns: pointer to a pcre_extra block, with study_data filled in and the appropriate flag set; NULL on error or if no optimization possible */ EXPORT pcre_extra * pcre_study(const pcre *external_re, int options, const char **errorptr) { uschar start_bits[32]; pcre_extra *extra; pcre_study_data *study; const uschar *tables; const real_pcre *re = (const real_pcre *)external_re; uschar *code = (uschar *)re + re->name_table_offset + (re->name_count * re->name_entry_size); compile_data compile_block; *errorptr = NULL; if (re == NULL || re->magic_number != MAGIC_NUMBER) { *errorptr = "argument is not a compiled regular expression"; return NULL; } if ((options & ~PUBLIC_STUDY_OPTIONS) != 0) { *errorptr = "unknown or incorrect option bit(s) set"; return NULL; } /* For an anchored pattern, or an unanchored pattern that has a first char, or a multiline pattern that matches only at "line starts", no further processing at present. */ if ((re->options & (PCRE_ANCHORED|PCRE_FIRSTSET|PCRE_STARTLINE)) != 0) return NULL; /* Set the character tables in the block that is passed around */ tables = re->tables; if (tables == NULL) (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES, (void*)&tables); compile_block.lcc = tables + lcc_offset; compile_block.fcc = tables + fcc_offset; compile_block.cbits = tables + cbits_offset; compile_block.ctypes = tables + ctypes_offset; /* See if we can find a fixed set of initial characters for the pattern. */ memset(start_bits, 0, 32 * sizeof(uschar)); if (!set_start_bits(code, start_bits, (re->options & PCRE_CASELESS) != 0, (re->options & PCRE_UTF8) != 0, &compile_block)) return NULL; /* Get a pcre_extra block and a pcre_study_data block. The study data is put in the latter, which is pointed to by the former, which may also get additional data set later by the calling program. At the moment, the size of pcre_study_data is fixed. We nevertheless save it in a field for returning via the pcre_fullinfo() function so that if it becomes variable in the future, we don't have to change that code. */ extra = (pcre_extra *)(pcre_malloc) (sizeof(pcre_extra) + sizeof(pcre_study_data)); if (extra == NULL) { *errorptr = "failed to get memory"; return NULL; } study = (pcre_study_data *)((char *)extra + sizeof(pcre_extra)); extra->flags = PCRE_EXTRA_STUDY_DATA; extra->study_data = study; study->size = sizeof(pcre_study_data); study->options = PCRE_STUDY_MAPPED; memcpy(study->start_bits, start_bits, sizeof(start_bits)); return extra; } /* End of study.c */ tomcat-connectors-1.2.41-src/native/iis/Makefile.x860000644000000000000020000001600411726114766020465 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. TARGET=isapi_redirect$(SO_VERSION) CPP=cl.exe MTL=midl.exe RSC=rc.exe OUTDIR=.\Release_x86 INTDIR=.\Release_x86 # Begin Custom Macros OutDir=.\Release_x86 # End Custom Macros !IF "$(RECURSE)" == "0" ALL : "$(OUTDIR)\$(TARGET).dll" !ELSE ALL : "pcre_x86" "$(OUTDIR)\$(TARGET).dll" !ENDIF !IF "$(RECURSE)" == "1" CLEAN :"pcre_x86CLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\jk.res" -@erase "$(INTDIR)\isapi_redirector_src.idb" -@erase "$(INTDIR)\isapi_redirector_src.pdb" -@erase "$(INTDIR)\jk_ajp12_worker.obj" -@erase "$(INTDIR)\jk_ajp13.obj" -@erase "$(INTDIR)\jk_ajp13_worker.obj" -@erase "$(INTDIR)\jk_ajp14.obj" -@erase "$(INTDIR)\jk_ajp14_worker.obj" -@erase "$(INTDIR)\jk_ajp_common.obj" -@erase "$(INTDIR)\jk_connect.obj" -@erase "$(INTDIR)\jk_context.obj" -@erase "$(INTDIR)\jk_isapi_plugin.obj" -@erase "$(INTDIR)\jk_lb_worker.obj" -@erase "$(INTDIR)\jk_map.obj" -@erase "$(INTDIR)\jk_md5.obj" -@erase "$(INTDIR)\jk_msg_buff.obj" -@erase "$(INTDIR)\jk_nwmain.obj" -@erase "$(INTDIR)\jk_pool.obj" -@erase "$(INTDIR)\jk_shm.obj" -@erase "$(INTDIR)\jk_sockbuf.obj" -@erase "$(INTDIR)\jk_status.obj" -@erase "$(INTDIR)\jk_uri_worker_map.obj" -@erase "$(INTDIR)\jk_url.obj" -@erase "$(INTDIR)\jk_util.obj" -@erase "$(INTDIR)\jk_worker.obj" -@erase "$(OUTDIR)\$(TARGET).dll" -@erase "$(OUTDIR)\isapi_redirect.exp" -@erase "$(OUTDIR)\isapi_redirect.lib" -@erase "$(OUTDIR)\$(TARGET).pdb" "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\isapi.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib strsafe.lib $(EXTRA_LIBS) /nologo /base:"0x6A6B0000" /dll /incremental:no /pdb:"$(OUTDIR)\$(TARGET).pdb" /debug /machine:I386 /def:".\isapi.def" /out:"$(OUTDIR)\$(TARGET).dll" /implib:"$(OUTDIR)\isapi_redirect.lib" DEF_FILE= \ ".\isapi.def" LINK32_OBJS= \ "$(INTDIR)\jk_ajp12_worker.obj" \ "$(INTDIR)\jk_ajp13.obj" \ "$(INTDIR)\jk_ajp13_worker.obj" \ "$(INTDIR)\jk_ajp14.obj" \ "$(INTDIR)\jk_ajp14_worker.obj" \ "$(INTDIR)\jk_ajp_common.obj" \ "$(INTDIR)\jk_connect.obj" \ "$(INTDIR)\jk_context.obj" \ "$(INTDIR)\jk_isapi_plugin.obj" \ "$(INTDIR)\jk_lb_worker.obj" \ "$(INTDIR)\jk_map.obj" \ "$(INTDIR)\jk_md5.obj" \ "$(INTDIR)\jk_msg_buff.obj" \ "$(INTDIR)\jk_nwmain.obj" \ "$(INTDIR)\jk_pool.obj" \ "$(INTDIR)\jk_shm.obj" \ "$(INTDIR)\jk_sockbuf.obj" \ "$(INTDIR)\jk_status.obj" \ "$(INTDIR)\jk_uri_worker_map.obj" \ "$(INTDIR)\jk_url.obj" \ "$(INTDIR)\jk_util.obj" \ "$(INTDIR)\jk_worker.obj" \ "$(INTDIR)\jk.res" \ ".\pcre\Release_x86\pcre.lib" "$(OUTDIR)\$(TARGET).dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << IF EXIST $(OUTDIR)\$(TARGET).manifest \ mt -nologo -manifest $(OUTDIR)\$(TARGET).manifest -outputresource:$(OUTDIR)\$(TARGET).dll;2 CPP_PROJ=-nologo -MD -W3 -O2 -Ob2 -Oy- -Zi -EHsc /I "..\common" /I "pcre" $(CFLAGS) /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "JK_ISAPI" /D "ISAPI_EXPORTS" /D "HAS_PCRE" /D "PCRE_STATIC" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\isapi_redirector_src" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 RSC_PROJ=/l 0x409 /fo"$(INTDIR)\jk.res" /i "..\common" /d "JK_ISAPI" /d "NDEBUG" SOURCE=..\common\jk.rc "$(INTDIR)\jk.res" : $(SOURCE) "$(INTDIR)" $(RSC) $(RSC_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp12_worker.c "$(INTDIR)\jk_ajp12_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp13.c "$(INTDIR)\jk_ajp13.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp13_worker.c "$(INTDIR)\jk_ajp13_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp14.c "$(INTDIR)\jk_ajp14.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp14_worker.c "$(INTDIR)\jk_ajp14_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp_common.c "$(INTDIR)\jk_ajp_common.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_connect.c "$(INTDIR)\jk_connect.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_context.c "$(INTDIR)\jk_context.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=.\jk_isapi_plugin.c "$(INTDIR)\jk_isapi_plugin.obj" : $(SOURCE) "$(INTDIR)" SOURCE=..\common\jk_lb_worker.c "$(INTDIR)\jk_lb_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_map.c "$(INTDIR)\jk_map.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_md5.c "$(INTDIR)\jk_md5.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_msg_buff.c "$(INTDIR)\jk_msg_buff.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_nwmain.c "$(INTDIR)\jk_nwmain.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_pool.c "$(INTDIR)\jk_pool.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_shm.c "$(INTDIR)\jk_shm.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_sockbuf.c "$(INTDIR)\jk_sockbuf.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_status.c "$(INTDIR)\jk_status.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_uri_worker_map.c "$(INTDIR)\jk_uri_worker_map.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_url.c "$(INTDIR)\jk_url.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_util.c "$(INTDIR)\jk_util.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_worker.c "$(INTDIR)\jk_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) "pcre_x86" : cd ".\pcre" $(MAKE) /$(MAKEFLAGS) /F ".\pcre.x86" cd ".." "pcre_x86CLEAN" : cd ".\pcre" $(MAKE) /$(MAKEFLAGS) /F ".\pcre.x86" CLEAN cd ".." tomcat-connectors-1.2.41-src/native/iis/isapi.dsp0000644000000000000020000001640611660225503020211 0ustar rootbin# Microsoft Developer Studio Project File - Name="isapi" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=isapi - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "isapi.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "isapi.mak" CFG="isapi - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "isapi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "isapi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "isapi - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JK_ISAPI" /D "ISAPI_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /Zi /O2 /I "..\common" /I "pcre" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "JK_ISAPI" /D "ISAPI_EXPORTS" /D "HAS_PCRE" /D "PCRE_STATIC" /Fd"Release/isapi_redirector_src" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" # ADD RSC /l 0x809 /d "JK_ISAPI" /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib strsafe.lib /nologo /base:"0x6A6B0000" /dll /debug /machine:I386 /out:"Release\isapi_redirect.dll" !ELSEIF "$(CFG)" == "isapi - 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 "JK_ISAPI" /D "ISAPI_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "..\common" /I "pcre" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "JK_ISAPI" /D "ISAPI_EXPORTS" /D "HAS_PCRE" /D "PCRE_STATIC" /Fd"Debug/isapi_redirector_src" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" # ADD RSC /l 0x809 /d "JK_ISAPI" /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib strsafe.lib /nologo /base:"0x6A6B0000" /dll /incremental:no /debug /machine:I386 /out:"Debug\isapi_redirect.dll" !ENDIF # Begin Target # Name "isapi - Win32 Release" # Name "isapi - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\common\jk.rc # End Source File # Begin Source File SOURCE=..\common\jk_ajp12_worker.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp13.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp13_worker.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp14.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp14_worker.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp_common.c # End Source File # Begin Source File SOURCE=..\common\jk_connect.c # End Source File # Begin Source File SOURCE=..\common\jk_context.c # End Source File # Begin Source File SOURCE=.\jk_isapi_plugin.c # End Source File # Begin Source File SOURCE=..\common\jk_lb_worker.c # End Source File # Begin Source File SOURCE=..\common\jk_map.c # End Source File # Begin Source File SOURCE=..\common\jk_md5.c # End Source File # Begin Source File SOURCE=..\common\jk_msg_buff.c # End Source File # Begin Source File SOURCE=..\common\jk_nwmain.c # End Source File # Begin Source File SOURCE=..\common\jk_pool.c # End Source File # Begin Source File SOURCE=..\common\jk_shm.c # End Source File # Begin Source File SOURCE=..\common\jk_sockbuf.c # End Source File # Begin Source File SOURCE=..\common\jk_status.c # End Source File # Begin Source File SOURCE=..\common\jk_uri_worker_map.c # End Source File # Begin Source File SOURCE=..\common\jk_url.c # End Source File # Begin Source File SOURCE=..\common\jk_util.c # End Source File # Begin Source File SOURCE=..\common\jk_worker.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=..\common\jk_ajp13.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp13_worker.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp14.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp14_worker.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp_common.h # End Source File # Begin Source File SOURCE=..\common\jk_channel.h # End Source File # Begin Source File SOURCE=..\common\jk_connect.h # End Source File # Begin Source File SOURCE=..\common\jk_context.h # End Source File # Begin Source File SOURCE=..\common\jk_env.h # End Source File # Begin Source File SOURCE=..\common\jk_global.h # End Source File # Begin Source File SOURCE=..\common\jk_lb_worker.h # End Source File # Begin Source File SOURCE=..\common\jk_logger.h # End Source File # Begin Source File SOURCE=..\common\jk_map.h # End Source File # Begin Source File SOURCE=..\common\jk_md5.h # End Source File # Begin Source File SOURCE=..\common\jk_msg_buff.h # End Source File # Begin Source File SOURCE=..\common\jk_mt.h # End Source File # Begin Source File SOURCE=..\common\jk_pool.h # End Source File # Begin Source File SOURCE=..\common\jk_service.h # End Source File # Begin Source File SOURCE=..\common\jk_shm.h # End Source File # Begin Source File SOURCE=..\common\jk_status.h # End Source File # Begin Source File SOURCE=..\common\jk_uri_worker_map.h # End Source File # Begin Source File SOURCE=..\common\jk_url.h # End Source File # Begin Source File SOURCE=..\common\jk_util.h # End Source File # Begin Source File SOURCE=..\common\jk_version.h # End Source File # Begin Source File SOURCE=..\common\jk_worker.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # Begin Source File SOURCE=.\isapi.def # End Source File # End Group # End Target # End Project tomcat-connectors-1.2.41-src/native/iis/jk_isapi_plugin.c0000644000000000000020000040442612453005413021707 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: ISAPI plugin for IIS/PWS * * Author: Gal Shachor * * Author: Larry Isaacs * * Author: Ignacio J. Ortega * * Author: Mladen Turk * * Version: $Revision: 1649861 $ * ***************************************************************************/ /* * Define WIN32 API we are going to use. */ #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0502 #endif #include #include #include #include #include "jk_global.h" #include "jk_url.h" #include "jk_util.h" #include "jk_map.h" #include "jk_pool.h" #include "jk_service.h" #include "jk_worker.h" #include "jk_uri_worker_map.h" #include "jk_shm.h" #include "jk_ajp13.h" #include "pcre.h" #ifndef POSIX_MALLOC_THRESHOLD #define POSIX_MALLOC_THRESHOLD 10 #endif #include #define VERSION_STRING "Tomcat/ISAPI/" JK_EXPOSED_VERSION #define FULL_VERSION_STRING "Tomcat/ISAPI/" JK_FULL_EXPOSED_VERSION #define SHM_DEF_PREFIX "JK_" #define DEFAULT_WORKER_NAME "ajp13" /* * This is default value found inside httpd.conf * for MaxClients */ #define DEFAULT_WORKER_THREADS 250 #define RES_BUFFER_SIZE 64 #define HDR_BUFFER_SIZE 1024 /* * We use special headers to pass values from the filter to the * extension. These values are: * * 1. The real URI before redirection took place * 2. The name of the worker to be used. * 3. The contents of the Translate header, if any * */ #define URI_HEADER_NAME_BASE "TOMCATURI" #define QUERY_HEADER_NAME_BASE "TOMCATQUERY" #define WORKER_HEADER_NAME_BASE "TOMCATWORKER" #define WORKER_HEADER_INDEX_BASE "TOMCATWORKERIDX" #define TOMCAT_TRANSLATE_HEADER_NAME_BASE "TOMCATTRANSLATE" #ifndef USE_CGI_HEADERS #define CONTENT_LENGTH "CONTENT-LENGTH:" #define ALL_HEADERS "ALL_RAW" #else #define ALL_HEADERS "ALL_HTTP" #endif /* The HTTP_ form of the header for use in ExtensionProc */ #define HTTP_HEADER_PREFIX "HTTP_" #ifdef USE_CGI_HEADERS #define HTTP_HEADER_PREFIX_LEN 5 #endif /* The template used to construct our unique headers * from the base name and module instance */ #define HEADER_TEMPLATE "%s%p:" #define HTTP_HEADER_TEMPLATE HTTP_HEADER_PREFIX "%s%p" static char URI_HEADER_NAME[RES_BUFFER_SIZE]; static char QUERY_HEADER_NAME[RES_BUFFER_SIZE]; static char WORKER_HEADER_NAME[RES_BUFFER_SIZE]; static char TOMCAT_TRANSLATE_HEADER_NAME[RES_BUFFER_SIZE]; static char WORKER_HEADER_INDEX[RES_BUFFER_SIZE]; /* The variants of the special headers after IIS adds * "HTTP_" to the front of them */ static char HTTP_URI_HEADER_NAME[RES_BUFFER_SIZE]; static char HTTP_QUERY_HEADER_NAME[RES_BUFFER_SIZE]; static char HTTP_WORKER_HEADER_NAME[RES_BUFFER_SIZE]; static char HTTP_WORKER_HEADER_INDEX[RES_BUFFER_SIZE]; #define REGISTRY_LOCATION "Software\\Apache Software Foundation\\Jakarta Isapi Redirector\\1.0" #define W3SVC_REGISTRY_KEY "SYSTEM\\CurrentControlSet\\Services\\W3SVC\\Parameters" #define EXTENSION_URI_TAG "extension_uri" #define URI_SELECT_TAG "uri_select" #define URI_SELECT_PARSED_VERB "parsed" #define URI_SELECT_UNPARSED_VERB "unparsed" #define URI_SELECT_ESCAPED_VERB "escaped" #define URI_SELECT_PROXY_VERB "proxy" #define URI_REWRITE_TAG "rewrite_rule_file" #define SHM_SIZE_TAG "shm_size" #define WORKER_MOUNT_RELOAD_TAG "worker_mount_reload" #define STRIP_SESSION_TAG "strip_session" #define AUTH_COMPLETE_TAG "auth_complete" #define REJECT_UNSAFE_TAG "reject_unsafe" #define COLLAPSE_SLASHES_TAG "collapse_slashes" #define COLLAPSE_SLASHES_ALL_VERB "all" #define COLLAPSE_SLASHES_NONE_VERB "none" #define COLLAPSE_SLASHES_UNMOUNT_VERB "unmount" #define WATCHDOG_INTERVAL_TAG "watchdog_interval" #define ENABLE_CHUNKED_ENCODING_TAG "enable_chunked_encoding" #define ERROR_PAGE_TAG "error_page" #define LOG_ROTATION_TIME_TAG "log_rotationtime" #define LOG_FILESIZE_TAG "log_filesize" /* HTTP standard headers */ #define TRANSFER_ENCODING_CHUNKED_HEADER_COMPLETE "Transfer-Encoding: chunked" #define TRANSFER_ENCODING_CHUNKED_HEADER_COMPLETE_LEN 26 #define TRANSFER_ENCODING_HEADER_NAME "Transfer-Encoding" #define TRANSFER_ENCODING_HEADER_NAME_LEN 17 #define TRANSFER_ENCODING_IDENTITY_VALUE "identity" #define TRANSFER_ENCODING_CHUNKED_VALUE "chunked" #define TRANSFER_ENCODING_CHUNKED_VALUE_LEN 7 #define CONTENT_LENGTH_HEADER_NAME "Content-Length" #define CONTENT_LENGTH_HEADER_NAME_LEN 14 #define CONNECTION_HEADER_NAME "Connection" #define CONNECTION_CLOSE_VALUE "Close" #define TRANSLATE_HEADER "Translate:" #define TRANSLATE_HEADER_NAME "Translate" #define TRANSLATE_HEADER_NAME_LC "translate" /* HTTP protocol CRLF */ #define CRLF "\r\n" #define CRLF_LEN 2 #define NIL "" /* Transfer-Encoding: chunked content trailer */ #define CHUNKED_ENCODING_TRAILER "0\r\n\r\n" #define CHUNKED_ENCODING_TRAILER_LEN 5 #define BAD_REQUEST -1 #define BAD_PATH -2 #define MAX_SERVERNAME 1024 #define MAX_INSTANCEID 32 char HTML_ERROR_HEAD[] = "\n" "\n" "\n\n" "\n" "\n"; #define HTML_ERROR_BODY_FMT "%s!\n\n\n

%s!

\n

\n%s\n

\n" char HTML_ERROR_TAIL[] = "

\n
 
 
 
 \n" FULL_VERSION_STRING "\n" "
 \n" "


\n" "

\n" "Copyright © 1999-2015 Apache Software Foundation
\n" "All Rights Reserved\n" "

\n\n\n"; static struct error_reasons { int status; const char *reason; const char *title; const char *description; } error_reasons[] = { { 100, "Continue", NULL, NULL }, { 101, "Switching Protocols", NULL, NULL }, { 200, "OK", NULL, NULL }, { 201, "Created", NULL, NULL }, { 202, "Accepted", NULL, NULL }, { 203, "Non-Authoritative Information", NULL, NULL }, { 204, "No Content", NULL, NULL }, { 205, "Reset Content", NULL, NULL }, { 206, "Partial Content", NULL, NULL }, { 300, "Multiple Choices", NULL, NULL }, { 301, "Moved Permanently", NULL, NULL }, { 302, "Moved Temporarily", NULL, NULL }, { 303, "See Other", NULL, NULL }, { 304, "Not Modified", NULL, NULL }, { 305, "Use Proxy", NULL, NULL }, { 400, "Bad Request", "Bad Request", "Your browser (or proxy) sent a request that " "this server could not understand." }, { 401, "Unauthorized", "Access is denied due to invalid credentials", "You do not have permission to view this directory or " "page using the credentials that you supplied." }, { 402, "Payment Required", NULL, NULL }, { 403, "Forbidden", "Access is denied", "You do not have permission to view this directory or page " "using the credentials that you supplied." }, { 404, "Not Found", "The requested URL was not found on this server", "If you entered the URL manually please check your" "spelling and try again." }, { 405, "Method Not Allowed", "HTTP method used to access this page is not allowed", "The page you are looking for cannot be displayed because an " "invalid method (HTTP method) was used to attempt access." }, { 406, "Not Acceptable", "Client browser does not accept the MIME type of the requested page", "The page you are looking for cannot be opened by your browser " "because it has a file name extension that your browser " "does not accept." }, { 407, "Proxy Authentication Required", NULL, "The client must first authenticate itself with the proxy" }, { 408, "Request Timeout", NULL, "The client did not produce a request within the time " "that the server was prepared to wait." }, { 409, "Conflict", NULL, "The request could not be completed due to a conflict with " "the current state of the resource." }, { 410, "Gone", NULL, "The requested resource is no longer available at the " "server and no forwarding address is known." }, { 411, "Length Required", NULL, "The server refuses to accept the request without a " "defined Content-Length." }, { 412, "Precondition Failed", NULL, "The precondition given in one or more of the request " "header fields evaluated to false when it was tested on the server." }, { 413, "Request Entity Too Large", NULL, "The HTTP method does not allow the data transmitted, " "or the data volume exceeds the capacity limit." }, { 414, "Request-URI Too Long", "Submitted URI too large", "The length of the requested URL exceeds the capacity limit " "for this server. The request cannot be processed." }, { 415, "Unsupported Media Type", NULL, "The server is refusing to service the request because the " "entity of the request is in a format not supported by the " "requested resource for the requested method." }, { 500, "Internal Server Error", NULL, "The server encountered an internal error and was " "unable to complete your request." }, { 501, "Not Implemented", NULL, "The server does not support the functionality required " "to fulfill the request." }, { 502, "Bad Gateway", NULL, "There is a problem with the page you are looking for, " "and it cannot be displayed. When the Web server (while " "acting as a gateway or proxy) contacted the upstream content " "server, it received an invalid response from the content server." }, { 503, "Service Unavailable", "Service Temporarily Unavailable", "The server is temporarily unable to service your " "request due to maintenance downtime or capacity problems. " "Please try again later." }, { 504, "Gateway Timeout", NULL, "The server, while acting as a gateway or proxy, " "did not receive a timely response from the upstream server" }, { 505, "HTTP Version Not Supported", NULL, "The server does not support, or refuses to support, the " "HTTP protocol version that was used in the request message." }, { 0, NULL, NULL, NULL } }; #define STRNULL_FOR_NULL(x) ((x) ? (x) : "(null)") #define JK_TOLOWER(x) ((char)tolower((BYTE)(x))) #define ISIZEOF(X) (int)sizeof(X) #define GET_SERVER_VARIABLE_VALUE(name, place) \ do { \ (place) = dup_server_value(private_data->lpEcb, \ (name), \ &private_data->p); \ } while(0) #define GET_SERVER_VARIABLE_VALUE_INT(name, place, def) \ do { \ char _tb[RES_BUFFER_SIZE]; \ if (get_server_value(private_data->lpEcb, \ (name), \ _tb, \ RES_BUFFER_SIZE)) { \ (place) = atoi(_tb); \ if (((place) == 0) && (errno == EINVAL || \ errno == ERANGE)) { \ (place) = def; \ } \ } else { \ (place) = def; \ } } while(0) static char dll_file_path[MAX_PATH]; static char ini_file_name[MAX_PATH]; static char ini_mutex_name[MAX_PATH]; static int using_ini_file = JK_FALSE; static HANDLE init_cs = NULL; static volatile int is_inited = JK_FALSE; static volatile int is_mapread = JK_FALSE; static BOOL dll_process_detach = FALSE; static jk_uri_worker_map_t *uw_map = NULL; static jk_map_t *workers_map = NULL; static jk_map_t *rewrite_map = NULL; static jk_map_t *rregexp_map = NULL; static jk_map_t *jk_environment_map = NULL; static jk_logger_t *logger = NULL; static JK_CRIT_SEC log_cs; static char *CONTENT_TYPE = "Content-Type:text/html\r\n\r\n"; static char extension_uri[INTERNET_MAX_URL_LENGTH]; static char log_file[MAX_PATH * 2]; static char log_file_effective[MAX_PATH * 2]; static int log_level = JK_LOG_DEF_LEVEL; static long log_rotationtime = 0; static time_t log_next_rotate_time = 0; static ULONGLONG log_filesize = 0; static char shm_loaded_name[MAX_PATH] = {0}; static char worker_file[MAX_PATH * 2]; static char worker_mount_file[MAX_PATH * 2] = {0}; static int worker_mount_reload = JK_URIMAP_DEF_RELOAD; static char rewrite_rule_file[MAX_PATH * 2] = {0}; static int shm_config_size = -1; static int strip_session = 0; static int use_auth_notification_flags = 1; static int chunked_encoding_enabled = JK_FALSE; static int reject_unsafe = 0; static int collapse_slashes = JK_COLLAPSE_DEFAULT; static volatile int watchdog_interval = 0; static HANDLE watchdog_handle = NULL; static char error_page_buf[INTERNET_MAX_URL_LENGTH] = {0}; static char *error_page = NULL; #define URI_SELECT_OPT_PARSED 0 #define URI_SELECT_OPT_UNPARSED 1 #define URI_SELECT_OPT_ESCAPED 2 #define URI_SELECT_OPT_PROXY 3 static int uri_select_option = URI_SELECT_OPT_PROXY; static jk_worker_env_t worker_env; typedef struct isapi_private_data_t isapi_private_data_t; struct isapi_private_data_t { jk_pool_t p; unsigned int bytes_read_so_far; int chunk_content; /* Whether we're responding with Transfer-Encoding: chunked content */ char *err_hdrs; LPEXTENSION_CONTROL_BLOCK lpEcb; }; typedef struct isapi_log_data_t isapi_log_data_t; struct isapi_log_data_t { char uri[INTERNET_MAX_URL_LENGTH]; char query[INTERNET_MAX_URL_LENGTH]; int request_matched; /* Whether this request (within a multi-request connection) was handled and needs the log values adjusted */ }; typedef struct iis_info_t iis_info_t; struct iis_info_t { int major; /* The major version */ int minor; /* The minor version */ DWORD filter_notify_event; /* The primary filter SF_NOTIFY_* event */ }; static iis_info_t iis_info; static int JK_METHOD start_response(jk_ws_service_t *s, int status, const char *reason, const char *const *header_names, const char *const *header_values, unsigned int num_of_headers); static int JK_METHOD iis_read(jk_ws_service_t *s, void *b, unsigned int l, unsigned int *a); static int JK_METHOD iis_write(jk_ws_service_t *s, const void *b, unsigned int l); static int JK_METHOD iis_done(jk_ws_service_t *s); static int init_ws_service(isapi_private_data_t * private_data, jk_ws_service_t *s, char **worker_name); static int init_jk(char *serverName); static int JK_METHOD iis_log_to_file(jk_logger_t *l, int level, int used, char *what); static BOOL initialize_extension(void); static int read_registry_init_data(void); static int get_config_parameter(LPVOID src, const char *tag, char *val, size_t sz); static int get_config_bool(LPVOID src, const char *tag, int def); static int get_config_int(LPVOID src, const char *tag, int def); static int get_registry_config_parameter(HKEY hkey, const char *tag, char *b, size_t sz); static int get_registry_config_number(HKEY hkey, const char *tag, int *val); static BOOL get_server_value(LPEXTENSION_CONTROL_BLOCK lpEcb, char *name, char *buf, size_t bufsz); static char *dup_server_value(LPEXTENSION_CONTROL_BLOCK lpEcb, const char *name, jk_pool_t *p); static int base64_encode_cert_len(int len); static int base64_encode_cert(char *encoded, const char *string, int len); static int get_iis_info(iis_info_t *info); static int isapi_write_client(isapi_private_data_t *p, const char *buf, unsigned int write_length); static char *path_merge(const char *root, const char *path); static int is_path_relative(const char *path); static char x2c(const char *what) { register char digit; digit = ((what[0] >= 'A') ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0')); digit *= 16; digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 : (what[1] - '0')); return (digit); } static int unescape_url(char *url) { register int x, y, badesc, badpath; badesc = 0; badpath = 0; for (x = 0, y = 0; url[y]; ++x, ++y) { if (url[y] != '%') url[x] = url[y]; else { if (!isxdigit(url[y + 1]) || !isxdigit(url[y + 2])) { badesc = 1; url[x] = '%'; } else { url[x] = x2c(&url[y + 1]); y += 2; if (url[x] == '/' || url[x] == '\0') badpath = 1; } } } url[x] = '\0'; if (badesc) return BAD_REQUEST; else if (badpath) return BAD_PATH; else return 0; } static void getparents(char *name) { int l, w; /* Four paseses, as per RFC 1808 */ /* a) remove ./ path segments */ for (l = 0, w = 0; name[l] != '\0';) { if (name[l] == '.' && name[l + 1] == '/' && (l == 0 || name[l - 1] == '/')) l += 2; else name[w++] = name[l++]; } /* b) remove trailing . path, segment */ if (w == 1 && name[0] == '.') w--; else if (w > 1 && name[w - 1] == '.' && name[w - 2] == '/') w--; name[w] = '\0'; /* c) remove all xx/../ segments. (including leading ../ and /../) */ l = 0; while (name[l] != '\0') { if (name[l] == '.' && name[l + 1] == '.' && name[l + 2] == '/' && (l == 0 || name[l - 1] == '/')) { register int m = l + 3, n; l = l - 2; if (l >= 0) { while (l >= 0 && name[l] != '/') l--; l++; } else l = 0; n = l; while ((name[n] = name[m]) != '\0') { n++; m++; } } else ++l; } /* d) remove trailing xx/.. segment. */ if (l == 2 && name[0] == '.' && name[1] == '.') name[0] = '\0'; else if (l > 2 && name[l - 1] == '.' && name[l - 2] == '.' && name[l - 3] == '/') { l = l - 4; if (l >= 0) { while (l >= 0 && name[l] != '/') l--; l++; } else l = 0; name[l] = '\0'; } } /* Apache code to escape a URL */ #define T_OS_ESCAPE_PATH (4) static const BYTE test_char_table[256] = { 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 7, 6, 1, 6, 1, 1, 9, 9, 1, 0, 8, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 15, 15, 8, 15, 15, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 7, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 7, 15, 1, 14, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 }; #define TEST_CHAR(c, f) (test_char_table[(unsigned int)(c)] & (f)) static const char c2x_table[] = "0123456789abcdef"; static BYTE *c2x(unsigned int what, BYTE *where) { *where++ = '%'; *where++ = c2x_table[what >> 4]; *where++ = c2x_table[what & 0xf]; return where; } static const char *status_reason(int status) { struct error_reasons *r; r = error_reasons; while (r->status <= status) { if (r->status == status) return r->reason; else r++; } return "No Reason"; } static const char *status_title(int status) { struct error_reasons *r; r = error_reasons; while (r->status <= status) { if (r->status == status) { if (r->title) return r->title; else return r->reason; } else r++; } return "Unknown Error"; } static const char *status_description(int status) { struct error_reasons *r; r = error_reasons; while (r->status <= status) { if (r->status == status) { if (r->description) return r->description; else return r->reason; } else r++; } return "Unknown Error"; } static int escape_url(const char *path, char *dest, int destsize) { const BYTE *s = (const BYTE *)path; BYTE *d = (BYTE *)dest; BYTE *e = d + destsize - 1; BYTE *ee = d + destsize - 3; while (*s) { if (TEST_CHAR(*s, T_OS_ESCAPE_PATH)) { if (d >= ee) return JK_FALSE; d = c2x(*s, d); } else { if (d >= e) return JK_FALSE; *d++ = *s; } ++s; } *d = '\0'; return JK_TRUE; } /* * Find the first occurrence of find in s. */ static char *stristr(const char *s, const char *find) { char c, sc; size_t len; if ((c = JK_TOLOWER(*find++)) != 0) { len = strlen(find); do { do { if ((sc = JK_TOLOWER(*s++)) == 0) return (NULL); } while (sc != c); } while (strnicmp(s, find, len) != 0); s--; } return ((char *)s); } /* * Find the first occurrence of path in uri tokenized by "/". * The comparison is done case insensitive. */ static const char *find_path_in_uri(const char *uri, const char *path) { size_t len = strlen(path); while (uri = strchr(uri, '/')) { uri++; if (!strnicmp(uri, path, len) && (*(uri + len) == '/' || strlen(uri) == len)) { return uri; } } return NULL; } static int uri_is_web_inf(const char *uri) { if (find_path_in_uri(uri, "web-inf")) { return JK_TRUE; } if (find_path_in_uri(uri, "meta-inf")) { return JK_TRUE; } return JK_FALSE; } static void write_error_response(PHTTP_FILTER_CONTEXT pfc, int err) { char status[1024]; char body[8192] = ""; DWORD len; /* reject !!! */ pfc->AddResponseHeaders(pfc, CONTENT_TYPE, 0); StringCbPrintf(status, sizeof(status), "%d %s", err, status_reason(err)); pfc->ServerSupportFunction(pfc, SF_REQ_SEND_RESPONSE_HEADER, status, 0, 0); len = ISIZEOF(HTML_ERROR_HEAD) - 1; pfc->WriteClient(pfc, HTML_ERROR_HEAD, &len, HSE_IO_SYNC); StringCbPrintf(body, sizeof(body), HTML_ERROR_BODY_FMT, status_reason(err), status_title(err), status_description(err)); len = lstrlenA(body); pfc->WriteClient(pfc, body, &len, HSE_IO_SYNC); len = ISIZEOF(HTML_ERROR_TAIL) - 1; pfc->WriteClient(pfc, HTML_ERROR_TAIL, &len, HSE_IO_SYNC); } static void write_error_message(LPEXTENSION_CONTROL_BLOCK lpEcb, int err, const char *err_hdrs) { DWORD len; char status[1024]; char body[8192] = ""; if (error_page) { char error_page_url[INTERNET_MAX_URL_LENGTH] = ""; DWORD len_of_error_page; StringCbPrintf(error_page_url, INTERNET_MAX_URL_LENGTH, error_page, err); len_of_error_page = lstrlenA(error_page_url); if (!lpEcb->ServerSupportFunction(lpEcb->ConnID, HSE_REQ_SEND_URL_REDIRECT_RESP, error_page_url, &len_of_error_page, NULL)) { lpEcb->dwHttpStatusCode = err; } else { return; } } lpEcb->dwHttpStatusCode = err; StringCbPrintf(status, sizeof(status), "%d %s", err, status_reason(err)); /* XXX: Should we allow something beside 401? */ if (err_hdrs && err == 401) { /* Include extra error headers */ HRESULT hr = StringCbCopy(body, sizeof(body), err_hdrs); if (FAILED(hr) || strlen(body) > (8191 - strlen(CONTENT_TYPE))) { /* Header is too long. */ jk_log(logger, JK_LOG_WARNING, "error header too long (%d bytes requested).", lstrlenA(err_hdrs)); body[0] = '\0'; } } StringCbCat(body, sizeof(body), CONTENT_TYPE); lpEcb->ServerSupportFunction(lpEcb->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, status, 0, (LPDWORD)body); /* First write the HEAD */ len = ISIZEOF(HTML_ERROR_HEAD) - 1; lpEcb->WriteClient(lpEcb->ConnID, HTML_ERROR_HEAD, &len, HSE_IO_SYNC); StringCbPrintf(body, sizeof(body), HTML_ERROR_BODY_FMT, status_reason(err), status_title(err), status_description(err)); len = lstrlenA(body); lpEcb->WriteClient(lpEcb->ConnID, body, &len, HSE_IO_SYNC); len = ISIZEOF(HTML_ERROR_TAIL) - 1; lpEcb->WriteClient(lpEcb->ConnID, HTML_ERROR_TAIL, &len, HSE_IO_SYNC); } static int JK_METHOD start_response(jk_ws_service_t *s, int status, const char *reason, const char *const *header_names, const char *const *header_values, unsigned int num_of_headers) { int rv = JK_TRUE; isapi_private_data_t *p; JK_TRACE_ENTER(logger); if (status < 100 || status > 1000) { jk_log(logger, JK_LOG_ERROR, "invalid status %d", status); JK_TRACE_EXIT(logger); return JK_FALSE; } if (s == NULL || s->ws_private == NULL) { JK_LOG_NULL_PARAMS(logger); JK_TRACE_EXIT(logger); return JK_FALSE; } p = s->ws_private; /* If we use proxy error pages, still pass * through context headers needed for special status codes. */ if (s->extension.use_server_error_pages && status >= s->extension.use_server_error_pages) { if (status == JK_HTTP_UNAUTHORIZED) { int found = JK_FALSE; unsigned int h; for (h = 0; h < num_of_headers; h++) { if (!strcasecmp(header_names[h], "WWW-Authenticate")) { p->err_hdrs = jk_pool_strcatv(&p->p, "WWW-Authenticate:", header_values[h], CRLF, NULL); found = JK_TRUE; } } if (found == JK_FALSE) { jk_log(logger, JK_LOG_INFO, "origin server sent 401 without" " WWW-Authenticate header"); } } return JK_TRUE; } if (!s->response_started) { char *status_str = NULL; char *headers_str = NULL; BOOL keep_alive = FALSE; /* Whether the downstream or us can supply content length */ BOOL rc; size_t i, len_of_headers = 0; s->response_started = JK_TRUE; if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Starting response for URI '%s' (protocol %s)", s->req_uri, s->protocol); } /* * Create the status line */ if (!reason) { reason = status_reason(status); } status_str = (char *)malloc((6 + strlen(reason))); StringCbPrintf(status_str, 6 + strlen(reason), "%d %s", status, reason); if (chunked_encoding_enabled) { /* Check if we've got an HTTP/1.1 response */ if (!strcasecmp(s->protocol, "HTTP/1.1")) { keep_alive = TRUE; /* Chunking only when HTTP/1.1 client and enabled */ p->chunk_content = JK_TRUE; } } /* * Create response headers string */ /* Calculate length of headers block */ for (i = 0; i < num_of_headers; i++) { len_of_headers += strlen(header_names[i]); len_of_headers += strlen(header_values[i]); len_of_headers += 4; /* extra for colon, space and crlf */ } /* * Exclude status codes that MUST NOT include message bodies */ if ((status == 204) || (status == 205) || (status == 304)) { p->chunk_content = JK_FALSE; /* Keep alive is still possible */ if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Response status %d implies no message body", status ); } if (p->chunk_content) { for (i = 0; i < num_of_headers; i++) { /* Check the downstream response to see whether * it's appropriate to chunk the response content * and whether it supports keeping the connection open. * This implements the rules for HTTP/1.1 message length determination * with the exception of multipart/byteranges media types. * http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4 */ if (!strcasecmp(CONTENT_LENGTH_HEADER_NAME, header_names[i])) { p->chunk_content = JK_FALSE; if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Response specifies Content-Length" ); } else if (!strcasecmp(CONNECTION_HEADER_NAME, header_names[i]) && !strcasecmp(CONNECTION_CLOSE_VALUE, header_values[i])) { keep_alive = FALSE; p->chunk_content = JK_FALSE; if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Response specifies Connection: Close" ); } else if (!strcasecmp(TRANSFER_ENCODING_HEADER_NAME, header_names[i]) && !strcasecmp(TRANSFER_ENCODING_IDENTITY_VALUE, header_values[i])) { /* HTTP states that this must include 'chunked' as the last value. * 'identity' is the same as absence of the header */ p->chunk_content = JK_FALSE; if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Response specifies Transfer-Encoding" ); } } /* Provide room in the buffer for the Transfer-Encoding header if we use it. */ len_of_headers += TRANSFER_ENCODING_CHUNKED_HEADER_COMPLETE_LEN + 2; } /* Allocate and init the headers string */ len_of_headers += 3; /* crlf and terminating null char */ headers_str = (char *)malloc(len_of_headers); headers_str[0] = '\0'; /* Copy headers into headers block for sending */ for (i = 0; i < num_of_headers; i++) { StringCbCat(headers_str, len_of_headers, header_names[i]); StringCbCat(headers_str, len_of_headers, ": "); StringCbCat(headers_str, len_of_headers, header_values[i]); StringCbCat(headers_str, len_of_headers, CRLF); } if (p->chunk_content) { /* Configure the response if chunked encoding is used */ if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Using Transfer-Encoding: chunked"); /** We will supply the transfer-encoding to allow IIS to keep the connection open */ keep_alive = TRUE; /* Indicate to the client that the content will be chunked - We've already reserved space for this */ StringCbCat(headers_str, len_of_headers, TRANSFER_ENCODING_CHUNKED_HEADER_COMPLETE); StringCbCat(headers_str, len_of_headers, CRLF); } /* Terminate the headers */ StringCbCat(headers_str, len_of_headers, CRLF); if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "%ssing Keep-Alive", (keep_alive ? "U" : "Not u")); if (keep_alive) { HSE_SEND_HEADER_EX_INFO hi; /* Fill in the response */ hi.pszStatus = status_str; hi.pszHeader = headers_str; hi.cchStatus = lstrlenA(status_str); hi.cchHeader = lstrlenA(headers_str); /* * Using the extended form of the API means we have to get this right, * i.e. IIS won't keep connections open if there's a Content-Length and close them if there isn't. */ hi.fKeepConn = keep_alive; /* Send the response to the client */ rc = p->lpEcb->ServerSupportFunction(p->lpEcb->ConnID, HSE_REQ_SEND_RESPONSE_HEADER_EX, &hi, NULL, NULL); } else { /* Old style response - forces Connection: close if Tomcat response doesn't specify necessary details to allow keep alive */ rc = p->lpEcb->ServerSupportFunction(p->lpEcb->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, status_str, 0, (LPDWORD)headers_str); } if (!rc) { jk_log(logger, JK_LOG_ERROR, "HSE_REQ_SEND_RESPONSE_HEADER%s failed with error=%d (0x%08x)", (keep_alive ? "_EX" : ""), GetLastError(), GetLastError()); rv = JK_FALSE; } if (headers_str) free(headers_str); if (status_str) free(status_str); } JK_TRACE_EXIT(logger); return rv; } static int JK_METHOD iis_read(jk_ws_service_t *s, void *b, unsigned int l, unsigned int *a) { isapi_private_data_t *p; JK_TRACE_ENTER(logger); if (s == NULL || s->ws_private == NULL) { JK_LOG_NULL_PARAMS(logger); JK_TRACE_EXIT(logger); return JK_FALSE; } if (a == NULL || b == NULL) { /* XXX: Do we really need those useless checks? */ JK_LOG_NULL_PARAMS(logger); JK_TRACE_EXIT(logger); return JK_FALSE; } p = s->ws_private; if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Preparing to read %d bytes. " "ECB reports %d bytes total, with %d available.", l, p->lpEcb->cbTotalBytes, p->lpEcb->cbAvailable); } *a = 0; if (l) { char *buf = b; DWORD already_read = p->lpEcb->cbAvailable - p->bytes_read_so_far; if (already_read >= l) { if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Already read %d bytes - supplying %d bytes from buffer", already_read, l); } memcpy(buf, p->lpEcb->lpbData + p->bytes_read_so_far, l); p->bytes_read_so_far += l; *a = l; } else { /* * Try to copy what we already have */ if (already_read > 0) { if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Supplying %d bytes from buffer", already_read); } memcpy(buf, p->lpEcb->lpbData + p->bytes_read_so_far, already_read); buf += already_read; l -= already_read; p->bytes_read_so_far = p->lpEcb->cbAvailable; *a = already_read; } /* * Now try to read from the client ... */ if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Attempting to read %d bytes from client", l); } if (p->lpEcb->ReadClient(p->lpEcb->ConnID, buf, &l)) { /* ReadClient will succeed with dwSize == 0 for last chunk if request chunk encoded */ *a += l; } else { jk_log(logger, JK_LOG_ERROR, "ReadClient failed with %d (0x%08x)", GetLastError(), GetLastError()); JK_TRACE_EXIT(logger); return JK_FALSE; } } } JK_TRACE_EXIT(logger); return JK_TRUE; } /* * Writes a buffer to the ISAPI response. */ static int isapi_write_client(isapi_private_data_t *p, const char *buf, unsigned int write_length) { unsigned int written = 0; DWORD try_to_write = 0; JK_TRACE_ENTER(logger); if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Writing %d bytes of data to client", write_length); while (written < write_length) { try_to_write = write_length - written; if (!p->lpEcb->WriteClient(p->lpEcb->ConnID, (LPVOID)(buf + written), &try_to_write, HSE_IO_SYNC)) { jk_log(logger, JK_LOG_ERROR, "WriteClient failed with %d (0x%08x)", GetLastError(), GetLastError()); JK_TRACE_EXIT(logger); return JK_FALSE; } written += try_to_write; if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Wrote %d bytes of data successfully", try_to_write); } JK_TRACE_EXIT(logger); return JK_TRUE; } /* * Write content to the response. * If chunked encoding has been enabled and the client supports it *(and it's appropriate for the response), then this will write a * single "Transfer-Encoding: chunked" chunk */ static int JK_METHOD iis_write(jk_ws_service_t *s, const void *b, unsigned int l) { isapi_private_data_t *p; const char *buf = (const char *)b; JK_TRACE_ENTER(logger); if (!l) { JK_TRACE_EXIT(logger); return JK_TRUE; } if (s == NULL || s->ws_private == NULL || b == NULL) { JK_LOG_NULL_PARAMS(logger); JK_TRACE_EXIT(logger); return JK_FALSE; } p = s->ws_private; if (!s->response_started) { start_response(s, 200, NULL, NULL, NULL, 0); } if (p->chunk_content == JK_FALSE) { if (isapi_write_client(p, buf, l) == JK_FALSE) { JK_TRACE_EXIT(logger); return JK_FALSE; } } else { char chunk_header[RES_BUFFER_SIZE]; /* Construct chunk header : HEX CRLF*/ StringCbPrintf(chunk_header, RES_BUFFER_SIZE, "%X%s", l, CRLF); if (iis_info.major >= 6) { HSE_RESPONSE_VECTOR response_vector; HSE_VECTOR_ELEMENT response_elements[3]; response_elements[0].ElementType = HSE_VECTOR_ELEMENT_TYPE_MEMORY_BUFFER; response_elements[0].pvContext = chunk_header; response_elements[0].cbOffset = 0; response_elements[0].cbSize = strlen(chunk_header); response_elements[1].ElementType = HSE_VECTOR_ELEMENT_TYPE_MEMORY_BUFFER; response_elements[1].pvContext = (PVOID)buf; response_elements[1].cbOffset = 0; response_elements[1].cbSize = l; response_elements[2].ElementType = HSE_VECTOR_ELEMENT_TYPE_MEMORY_BUFFER; response_elements[2].pvContext = CRLF; response_elements[2].cbOffset = 0; response_elements[2].cbSize = CRLF_LEN; response_vector.dwFlags = HSE_IO_SYNC; response_vector.pszStatus = NULL; response_vector.pszHeaders = NULL; response_vector.nElementCount = 3; response_vector.lpElementArray = response_elements; if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Using vector write for chunk encoded %d byte chunk", l); if (!p->lpEcb->ServerSupportFunction(p->lpEcb->ConnID, HSE_REQ_VECTOR_SEND, &response_vector, NULL, NULL)) { jk_log(logger, JK_LOG_ERROR, "Vector write of chunk encoded response failed with %d (0x%08x)", GetLastError(), GetLastError()); JK_TRACE_EXIT(logger); return JK_FALSE; } } else { /* Write chunk header */ if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Using chunked encoding - writing chunk header for %d byte chunk", l); if (!isapi_write_client(p, chunk_header, lstrlenA(chunk_header))) { jk_log(logger, JK_LOG_ERROR, "WriteClient for chunk header failed"); JK_TRACE_EXIT(logger); return JK_FALSE; } /* Write chunk body (or simple body block) */ if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Writing %s of size %d", (p->chunk_content ? "chunk body" : "simple response"), l); } if (!isapi_write_client(p, buf, l)) { jk_log(logger, JK_LOG_ERROR, "WriteClient for response body chunk failed"); JK_TRACE_EXIT(logger); return JK_FALSE; } /* Write chunk trailer */ if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Using chunked encoding - writing chunk trailer"); } if (!isapi_write_client(p, CRLF, CRLF_LEN)) { jk_log(logger, JK_LOG_ERROR, "WriteClient for chunk trailer failed"); JK_TRACE_EXIT(logger); return JK_FALSE; } } } JK_TRACE_EXIT(logger); return JK_TRUE; } /** * In the case of a Transfer-Encoding: chunked response, this will write the terminator chunk. */ static int JK_METHOD iis_done(jk_ws_service_t *s) { isapi_private_data_t *p; JK_TRACE_ENTER(logger); if (s == NULL || s->ws_private == NULL) { JK_LOG_NULL_PARAMS(logger); JK_TRACE_EXIT(logger); return JK_FALSE; } p = s->ws_private; if (p->chunk_content == JK_FALSE) { JK_TRACE_EXIT(logger); return JK_TRUE; } /* Write last chunk + terminator */ if (iis_info.major >= 6) { HSE_RESPONSE_VECTOR response_vector; HSE_VECTOR_ELEMENT response_elements[1]; response_elements[0].ElementType = HSE_VECTOR_ELEMENT_TYPE_MEMORY_BUFFER; response_elements[0].pvContext = CHUNKED_ENCODING_TRAILER; response_elements[0].cbOffset = 0; response_elements[0].cbSize = CHUNKED_ENCODING_TRAILER_LEN; /* HSE_IO_FINAL_SEND lets IIS process the response to the client before we return */ response_vector.dwFlags = HSE_IO_SYNC | HSE_IO_FINAL_SEND; response_vector.pszStatus = NULL; response_vector.pszHeaders = NULL; response_vector.nElementCount = 1; response_vector.lpElementArray = response_elements; if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Using vector write to terminate chunk encoded response."); if (!p->lpEcb->ServerSupportFunction(p->lpEcb->ConnID, HSE_REQ_VECTOR_SEND, &response_vector, NULL, NULL)) { jk_log(logger, JK_LOG_ERROR, "Vector termination of chunk encoded response failed with %d (0x%08x)", GetLastError(), GetLastError()); JK_TRACE_EXIT(logger); return JK_FALSE; } } else { if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Terminating chunk encoded response"); if (!isapi_write_client(p, CHUNKED_ENCODING_TRAILER, CHUNKED_ENCODING_TRAILER_LEN)) { jk_log(logger, JK_LOG_ERROR, "WriteClient for chunked response terminator failed with %d (0x%08x)", GetLastError(), GetLastError()); JK_TRACE_EXIT(logger); return JK_FALSE; } } JK_TRACE_EXIT(logger); return JK_TRUE; } BOOL WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer) { BOOL rv = TRUE; ULONG http_filter_revision = HTTP_FILTER_REVISION; pVer->dwFilterVersion = pVer->dwServerFilterVersion; if (pVer->dwFilterVersion > http_filter_revision) { pVer->dwFilterVersion = http_filter_revision; } WaitForSingleObject(init_cs, INFINITE); if (!is_inited) { rv = initialize_extension(); } ReleaseMutex(init_cs); if (iis_info.major < 5 || (iis_info.major == 5 && iis_info.minor < 1)) { SetLastError(ERROR_OLD_WIN_VERSION); return FALSE; } pVer->dwFlags = SF_NOTIFY_ORDER_HIGH | SF_NOTIFY_SECURE_PORT | SF_NOTIFY_NONSECURE_PORT | SF_NOTIFY_LOG | iis_info.filter_notify_event; StringCbCopy(pVer->lpszFilterDesc, SF_MAX_FILTER_DESC_LEN, (VERSION_STRING)); return rv; } #define AP_REG_ICASE 0x01 /** use a case-insensitive match */ #define AP_REG_NEWLINE 0x02 /** don't match newlines against '.' etc */ #define AP_REG_NOTBOL 0x04 /** ^ will not match against start-of-string */ #define AP_REG_NOTEOL 0x08 /** $ will not match against end-of-string */ #define AP_REG_EXTENDED (0) /** unused */ #define AP_REG_NOSUB (0) /** unused */ /** The max number of regex captures that can be expanded by ap_pregsub */ #define AP_MAX_REG_MATCH 10 /* Error values: */ enum { AP_REG_ASSERT = 1, /** internal error ? */ AP_REG_ESPACE, /** failed to get memory */ AP_REG_INVARG, /** invalid argument */ AP_REG_NOMATCH /** match failed */ }; /* The structure representing a compiled regular expression. */ typedef struct { void *re_pcre; size_t re_nsub; size_t re_erroffset; const char *real; const char *fake; } ap_regex_t; /* The structure in which a captured offset is returned. */ typedef struct { int rm_so; int rm_eo; } ap_regmatch_t; /* Table of error strings corresponding to POSIX error codes; must be * kept in synch with include/ap_regex.h's AP_REG_E* definitions. */ static const char *const pstring[] = { "", /* Dummy for value 0 */ "internal error", /* AP_REG_ASSERT */ "failed to get memory", /* AP_REG_ESPACE */ "bad argument", /* AP_REG_INVARG */ "match failed" /* AP_REG_NOMATCH */ }; static size_t ap_regerror(int errcode, const ap_regex_t *preg, char *errbuf, size_t errbuf_size) { const char *message, *addmessage; size_t length, addlength; message = (errcode >= (int)(sizeof(pstring)/sizeof(char *))) ? "unknown error code" : pstring[errcode]; length = strlen(message) + 1; addmessage = " at offset "; addlength = (preg != NULL && (int)preg->re_erroffset != -1)? strlen(addmessage) + 6 : 0; if (errbuf_size > 0) { if (addlength > 0 && errbuf_size >= length + addlength) { StringCbPrintf(errbuf, sizeof(errbuf), "%s%s%-6d", message, addmessage, (int)preg->re_erroffset); } else { strncpy(errbuf, message, errbuf_size - 1); errbuf[errbuf_size-1] = 0; } } return length + addlength; } /************************************************* * Free store held by a regex * *************************************************/ static void ap_regfree(ap_regex_t *preg) { (pcre_free)(preg->re_pcre); } /************************************************* * Compile a regular expression * *************************************************/ /* Arguments: preg points to a structure for recording the compiled expression pattern the pattern to compile cflags compilation flags Returns: 0 on success various non-zero codes on failure */ static int ap_regcomp(ap_regex_t *preg, const char *pattern, int cflags) { const char *errorptr; int erroffset; int options = 0; if ((cflags & AP_REG_ICASE) != 0) options |= PCRE_CASELESS; if ((cflags & AP_REG_NEWLINE) != 0) options |= PCRE_MULTILINE; preg->re_pcre = pcre_compile(pattern, options, &errorptr, &erroffset, NULL); preg->re_erroffset = erroffset; if (preg->re_pcre == NULL) return AP_REG_INVARG; preg->re_nsub = pcre_info((const pcre *)preg->re_pcre, NULL, NULL); return 0; } /************************************************* * Match a regular expression * *************************************************/ /* Unfortunately, PCRE requires 3 ints of working space for each captured substring, so we have to get and release working store instead of just using the POSIX structures as was done in earlier releases when PCRE needed only 2 ints. However, if the number of possible capturing brackets is small, use a block of store on the stack, to reduce the use of malloc/free. The threshold is in a macro that can be changed at configure time. */ static int ap_regexec(const ap_regex_t *preg, const char *string, int nmatch, ap_regmatch_t pmatch[], int eflags) { int rc; int options = 0; int *ovector = NULL; int small_ovector[POSIX_MALLOC_THRESHOLD * 3]; int allocated_ovector = 0; if ((eflags & AP_REG_NOTBOL) != 0) options |= PCRE_NOTBOL; if ((eflags & AP_REG_NOTEOL) != 0) options |= PCRE_NOTEOL; ((ap_regex_t *)preg)->re_erroffset = (size_t)(-1); /* Only has meaning after compile */ if (nmatch > 0) { if (nmatch <= POSIX_MALLOC_THRESHOLD) { ovector = &(small_ovector[0]); } else { ovector = (int *)malloc(sizeof(int) * nmatch * 3); if (ovector == NULL) return AP_REG_ESPACE; allocated_ovector = 1; } } rc = pcre_exec((const pcre *)preg->re_pcre, NULL, string, lstrlenA(string), 0, options, ovector, nmatch * 3); if (rc == 0) rc = nmatch; /* All captured slots were filled in */ if (rc >= 0) { int i; for (i = 0; i < rc; i++) { pmatch[i].rm_so = ovector[i*2]; pmatch[i].rm_eo = ovector[i*2+1]; } if (allocated_ovector) free(ovector); for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1; return 0; } else { if (allocated_ovector) free(ovector); switch(rc) { case PCRE_ERROR_NOMATCH: return AP_REG_NOMATCH; case PCRE_ERROR_NULL: return AP_REG_INVARG; case PCRE_ERROR_BADOPTION: return AP_REG_INVARG; case PCRE_ERROR_BADMAGIC: return AP_REG_INVARG; case PCRE_ERROR_UNKNOWN_NODE: return AP_REG_ASSERT; case PCRE_ERROR_NOMEMORY: return AP_REG_ESPACE; #ifdef PCRE_ERROR_MATCHLIMIT case PCRE_ERROR_MATCHLIMIT: return AP_REG_ESPACE; #endif #ifdef PCRE_ERROR_BADUTF8 case PCRE_ERROR_BADUTF8: return AP_REG_INVARG; #endif #ifdef PCRE_ERROR_BADUTF8_OFFSET case PCRE_ERROR_BADUTF8_OFFSET: return AP_REG_INVARG; #endif default: break; } } return AP_REG_ASSERT; } /* This function substitutes for $0-$9, filling in regular expression * submatches. Pass it the same nmatch and pmatch arguments that you * passed ap_regexec(). pmatch should not be greater than the maximum number * of subexpressions - i.e. one more than the re_nsub member of ap_regex_t. * * input should be the string with the $-expressions, source should be the * string that was matched against. * * It returns the substituted string, or NULL on error. * * Parts of this code are based on Henry Spencer's regsub(), from his * AT&T V8 regexp package. */ static char *ap_pregsub(const char *input, const char *source, size_t nmatch, ap_regmatch_t pmatch[]) { const char *src = input; char *dest, *dst; char c; size_t no; int len; if (!source) return NULL; if (!nmatch) return strdup(src); /* First pass, find the size */ len = 0; while ((c = *src++) != '\0') { if (c == '&') no = 0; else if (c == '$' && isdigit((unsigned char)*src)) no = *src++ - '0'; else no = 10; if (no > 9) { /* Ordinary character. */ if (c == '\\' && (*src == '$' || *src == '&')) c = *src++; len++; } else if (no < nmatch && pmatch[no].rm_so < pmatch[no].rm_eo) { len += pmatch[no].rm_eo - pmatch[no].rm_so; } } dest = dst = calloc(1, len + 1); /* Now actually fill in the string */ src = input; while ((c = *src++) != '\0') { if (c == '&') no = 0; else if (c == '$' && isdigit((unsigned char)*src)) no = *src++ - '0'; else no = 10; if (no > 9) { /* Ordinary character. */ if (c == '\\' && (*src == '$' || *src == '&')) c = *src++; *dst++ = c; } else if (no < nmatch && pmatch[no].rm_so < pmatch[no].rm_eo) { len = pmatch[no].rm_eo - pmatch[no].rm_so; memcpy(dst, source + pmatch[no].rm_so, len); dst += len; } } *dst = '\0'; return dest; } static char *simple_rewrite(jk_pool_t *p, const char *uri) { if (rewrite_map) { int i; for (i = 0; i < jk_map_size(rewrite_map); i++) { size_t len; const char *src = jk_map_name_at(rewrite_map, i); if (*src == '~') continue; /* Skip regexp rewrites */ len = strlen(src); if (strncmp(uri, src, len) == 0) { return jk_pool_strcat(p, jk_map_value_at(rewrite_map, i), uri + len); } } } return NULL; } static char *rregex_rewrite(jk_pool_t *p, const char *uri) { ap_regmatch_t regm[AP_MAX_REG_MATCH]; if (rregexp_map) { int i; for (i = 0; i < jk_map_size(rregexp_map); i++) { ap_regex_t *regexp = (ap_regex_t *)jk_map_value_at(rregexp_map, i); if (!ap_regexec(regexp, uri, AP_MAX_REG_MATCH, regm, 0)) { char *subs = ap_pregsub(regexp->fake, uri, AP_MAX_REG_MATCH, regm); if (subs) { char *buf, *ptr; size_t orgsz = strlen(uri); size_t subsz = strlen(subs); size_t lefts = orgsz - regm[0].rm_eo; ptr = buf = jk_pool_alloc(p, regm[0].rm_so + subsz + lefts + 1); memcpy(buf, uri, regm[0].rm_so); ptr += regm[0].rm_so; memcpy(ptr, subs, subsz); ptr += subsz; memcpy(ptr, uri + regm[0].rm_eo, lefts); ptr[lefts] = '\0'; return buf; } } } } return NULL; } static __inline void clear_header(PHTTP_FILTER_PREPROC_HEADERS pfp, PHTTP_FILTER_CONTEXT pfc, LPSTR lpszName) { pfp->SetHeader(pfc, lpszName, NIL); } static __inline LPSTR get_pheader(jk_pool_t *pool, PHTTP_FILTER_PREPROC_HEADERS pfp, PHTTP_FILTER_CONTEXT pfc, LPSTR lpszName, LPSTR lpszBuf, size_t bsize) { LPSTR rv = lpszBuf; DWORD dwLen = (DWORD)bsize; if (!pfp->GetHeader(pfc, lpszName, lpszBuf, &dwLen)) { if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return NULL; if ((rv = jk_pool_alloc(pool, dwLen)) == NULL) return NULL; /* Try again with dynamic buffer */ if (!pfp->GetHeader(pfc, lpszName, rv, &dwLen)) return NULL; } return rv; } static DWORD handle_notify_event(PHTTP_FILTER_CONTEXT pfc, PHTTP_FILTER_PREPROC_HEADERS pfp) { int rc; DWORD rv = SF_STATUS_REQ_NEXT_NOTIFICATION; const char *worker = NULL; rule_extension_t *extensions; int worker_index = -1; int port = 0; jk_pool_atom_t pbuf[HUGE_POOL_SIZE]; jk_pool_t pool; char *uri_undec = NULL; char *uri = NULL; char *host = NULL; char *translate = NULL; char szHB[HDR_BUFFER_SIZE] = "/"; char szUB[HDR_BUFFER_SIZE] = ""; char szTB[16] = ""; char szPB[16] = ""; char swindex[32] = ""; char *query; DWORD len; if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Filter started"); jk_open_pool(&pool, pbuf, sizeof(jk_pool_atom_t) * HUGE_POOL_SIZE); /* * Just in case somebody set these headers in the request! */ clear_header(pfp, pfc, URI_HEADER_NAME); clear_header(pfp, pfc, QUERY_HEADER_NAME); clear_header(pfp, pfc, WORKER_HEADER_NAME); clear_header(pfp, pfc, WORKER_HEADER_INDEX); clear_header(pfp, pfc, TOMCAT_TRANSLATE_HEADER_NAME); /* * Suppress logging of original uri/query when we don't map a URL */ if (pfc->pFilterContext) { isapi_log_data_t *ld = (isapi_log_data_t *)pfc->pFilterContext; ld->request_matched = JK_FALSE; } uri = get_pheader(&pool, pfp, pfc, "url", szUB, sizeof(szUB)); if (uri == NULL) { jk_log(logger, JK_LOG_ERROR, "error while getting the url"); return SF_STATUS_REQ_ERROR; } if (*uri == '\0') { /* Empty url */ return SF_STATUS_REQ_NEXT_NOTIFICATION; } query = strchr(uri, '?'); if (query) { *query++ = '\0'; if (*query) query = jk_pool_strdup(&pool, query); else query = NULL; } if (uri_select_option == URI_SELECT_OPT_UNPARSED) { /* Duplicate unparsed uri */ uri_undec = jk_pool_strdup(&pool, uri); } rc = unescape_url(uri); if (rc == BAD_REQUEST) { jk_log(logger, JK_LOG_ERROR, "[%s] contains one or more invalid escape sequences.", uri); write_error_response(pfc, 400); rv = SF_STATUS_REQ_FINISHED; goto cleanup; } if (rc == BAD_PATH) { jk_log(logger, JK_LOG_EMERG, "[%s] contains forbidden escape sequences.", uri); write_error_response(pfc, 404); rv = SF_STATUS_REQ_FINISHED; goto cleanup; } getparents(uri); len = ISIZEOF(szHB) - 1; if (pfc->GetServerVariable(pfc, "SERVER_NAME", &szHB[1], &len) && len > 1) { len = ISIZEOF(szPB); if (pfc->GetServerVariable(pfc, "SERVER_PORT", szPB, &len)) port = atoi(szPB); if (port != 0 && port != 80 && port != 443) { host = jk_pool_strcatv(&pool, szHB, ":", szPB, NULL); } else host = szHB; } worker = map_uri_to_worker_ext(uw_map, uri, host, &extensions, &worker_index, logger); /* * Check if somebody is feading us with his own TOMCAT data headers. * We reject such postings ! */ if (worker) { char *forwardURI; char *rewriteURI; isapi_log_data_t *ld; BOOL rs; if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "check if [%s] points to the web-inf directory", uri); if (uri_is_web_inf(uri)) { jk_log(logger, JK_LOG_EMERG, "[%s] points to the web-inf or meta-inf directory. " "Somebody tries to hack into the site!!!", uri); write_error_response(pfc, 404); rv = SF_STATUS_REQ_FINISHED; goto cleanup; } /* This is a servlet, should redirect ... */ if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "[%s] is a servlet url - should redirect to %s", uri, worker); /* get URI we should forward */ if (uri_select_option == URI_SELECT_OPT_UNPARSED) { /* get original unparsed URI */ forwardURI = uri_undec; } else if (uri_select_option == URI_SELECT_OPT_ESCAPED) { size_t elen = strlen(uri) * 3 + 1; char *escuri = jk_pool_alloc(&pool, elen); if (!escape_url(uri, escuri, (int)elen)) { jk_log(logger, JK_LOG_ERROR, "[%s] re-encoding request exceeds maximum buffer size.", uri); write_error_response(pfc, 400); rv = SF_STATUS_REQ_FINISHED; goto cleanup; } if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "fowarding escaped URI [%s]", escuri); forwardURI = escuri; } else if (uri_select_option == URI_SELECT_OPT_PROXY) { size_t elen = strlen(uri) * 3 + 1; char *escuri = jk_pool_alloc(&pool, elen); if (!jk_canonenc(uri, escuri, (int)elen)) { jk_log(logger, JK_LOG_ERROR, "[%s] re-encoding request exceeds maximum buffer size.", uri); write_error_response(pfc, 400); rv = SF_STATUS_REQ_FINISHED; goto cleanup; } if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "fowarding escaped URI [%s]", escuri); forwardURI = escuri; } else { forwardURI = uri; } /* Do a simple rewrite . * Note that URI can be escaped, so thus the rule has * to be in that case. * * TODO: Add more advanced regexp rewrite. */ rewriteURI = simple_rewrite(&pool, forwardURI); if (rewriteURI == NULL) rewriteURI = rregex_rewrite(&pool, forwardURI); if (rewriteURI) { if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "rewritten URI [%s]->[%s]", forwardURI, rewriteURI); } forwardURI = rewriteURI; } itoa(worker_index, swindex, 10); rs = pfp->AddHeader(pfc, URI_HEADER_NAME, forwardURI); if (rs && query) rs = pfp->AddHeader(pfc, QUERY_HEADER_NAME, query); rs = rs && pfp->AddHeader(pfc, WORKER_HEADER_NAME, (LPSTR)worker); rs = rs && pfp->AddHeader(pfc, WORKER_HEADER_INDEX, swindex); rs = rs && pfp->SetHeader(pfc, "url", extension_uri); if (!rs) { jk_log(logger, JK_LOG_ERROR, "error while adding request headers"); SetLastError(ERROR_INVALID_PARAMETER); rv = SF_STATUS_REQ_ERROR; goto cleanup; } translate = get_pheader(&pool, pfp, pfc, TRANSLATE_HEADER, szTB, sizeof(szTB)); /* Move Translate: header to a temporary header so * that the extension proc will be called. * This allows the servlet to handle 'Translate: f'. */ if (translate && &translate) { if (!pfp->AddHeader(pfc, TOMCAT_TRANSLATE_HEADER_NAME, translate)) { jk_log(logger, JK_LOG_ERROR, "error while adding Tomcat-Translate headers"); rv = SF_STATUS_REQ_ERROR; goto cleanup; } clear_header(pfp, pfc, TRANSLATE_HEADER); } ld = (isapi_log_data_t *)pfc->pFilterContext; if (ld == NULL) { ld = (isapi_log_data_t *)pfc->AllocMem(pfc, sizeof(isapi_log_data_t), 0); if (ld == NULL) { jk_log(logger, JK_LOG_ERROR, "error while allocating memory"); SetLastError(ERROR_NOT_ENOUGH_MEMORY); rv = SF_STATUS_REQ_ERROR; goto cleanup; } pfc->pFilterContext = ld; } memset(ld, 0, sizeof(isapi_log_data_t)); StringCbCopy(ld->uri, sizeof(ld->uri), forwardURI); if (query) StringCbCopy(ld->query, sizeof(ld->query), query); ld->request_matched = JK_TRUE; if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "forwarding to : %s", extension_uri); jk_log(logger, JK_LOG_DEBUG, "forward URI : %s%s", URI_HEADER_NAME, forwardURI); if (query) jk_log(logger, JK_LOG_DEBUG, "forward query : %s%s", QUERY_HEADER_NAME, query); jk_log(logger, JK_LOG_DEBUG, "forward worker: %s%s", WORKER_HEADER_NAME, worker); jk_log(logger, JK_LOG_DEBUG, "worker index : %s%s", WORKER_HEADER_INDEX, swindex); } } else { if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "[%s] is not a servlet url", uri); if (strip_session) { char *jsessionid = strstr(uri, JK_PATH_SESSION_IDENTIFIER); if (jsessionid) { if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "removing session identifier [%s] for non servlet url [%s]", jsessionid, uri); *jsessionid = '\0'; pfp->SetHeader(pfc, "url", uri); } } } cleanup: jk_close_pool(&pool); return rv; } DWORD WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD dwNotificationType, LPVOID pvNotification) { /* Initialise jk */ EnterCriticalSection(&log_cs); if (is_inited && !is_mapread) { char serverName[MAX_SERVERNAME] = ""; char instanceId[MAX_INSTANCEID] = ""; DWORD dwLen = MAX_SERVERNAME - MAX_INSTANCEID - 1; if (pfc->GetServerVariable(pfc, "SERVER_NAME", serverName, &dwLen)) { dwLen = MAX_INSTANCEID; if (pfc->GetServerVariable(pfc, "INSTANCE_ID", instanceId, &dwLen)) { if (dwLen > 1) { StringCbCat(serverName, MAX_SERVERNAME, "_"); StringCbCat(serverName, MAX_SERVERNAME, instanceId); } } if (!is_mapread) { WaitForSingleObject(init_cs, INFINITE); if (!is_mapread) is_mapread = init_jk(serverName); ReleaseMutex(init_cs); } } /* If we can't read the map we become dormant */ if (!is_mapread) is_inited = JK_FALSE; } LeaveCriticalSection(&log_cs); if (!is_inited) { /* In case the initialization failed * return error. This will make entire IIS * unusable like with Apache servers */ SetLastError(ERROR_INVALID_FUNCTION); return SF_STATUS_REQ_ERROR; } if (iis_info.filter_notify_event == dwNotificationType) { return handle_notify_event(pfc, pvNotification); } else if (dwNotificationType == SF_NOTIFY_LOG) { if (pfc->pFilterContext) { isapi_log_data_t *ld = (isapi_log_data_t *)pfc->pFilterContext; if (ld->request_matched) { HTTP_FILTER_LOG *pl = (HTTP_FILTER_LOG *)pvNotification; pl->pszTarget = ld->uri; pl->pszParameters = ld->query; } } } return SF_STATUS_REQ_NEXT_NOTIFICATION; } BOOL WINAPI GetExtensionVersion(HSE_VERSION_INFO * pVer) { BOOL rv = TRUE; pVer->dwExtensionVersion = MAKELONG(HSE_VERSION_MINOR, HSE_VERSION_MAJOR); StringCbCopy(pVer->lpszExtensionDesc, HSE_MAX_EXT_DLL_NAME_LEN, (VERSION_STRING)); WaitForSingleObject(init_cs, INFINITE); if (!is_inited) { rv = initialize_extension(); } ReleaseMutex(init_cs); return rv; } DWORD WINAPI HttpExtensionProc(LPEXTENSION_CONTROL_BLOCK lpEcb) { DWORD rc = HSE_STATUS_ERROR; isapi_private_data_t private_data; jk_ws_service_t s; jk_pool_atom_t buf[SMALL_POOL_SIZE]; char *worker_name; lpEcb->dwHttpStatusCode = HTTP_STATUS_SERVER_ERROR; JK_TRACE_ENTER(logger); /* Initialise jk */ EnterCriticalSection(&log_cs); if (is_inited && !is_mapread) { char serverName[MAX_SERVERNAME] = ""; char instanceId[MAX_INSTANCEID] = ""; DWORD dwLen = MAX_SERVERNAME - MAX_INSTANCEID - 1; if (lpEcb->GetServerVariable(lpEcb->ConnID, "SERVER_NAME", serverName, &dwLen)) { dwLen = MAX_INSTANCEID; if (lpEcb->GetServerVariable(lpEcb->ConnID, "INSTANCE_ID", instanceId, &dwLen)) { if (dwLen > 1) { StringCbCat(serverName, MAX_SERVERNAME, "_"); StringCbCat(serverName, MAX_SERVERNAME, instanceId); } } if (!is_mapread) { WaitForSingleObject(init_cs, INFINITE); if (!is_mapread) is_mapread = init_jk(serverName); ReleaseMutex(init_cs); } } if (!is_mapread) is_inited = JK_FALSE; } LeaveCriticalSection(&log_cs); if (!is_inited) { jk_log(logger, JK_LOG_ERROR, "not initialized"); JK_TRACE_EXIT(logger); return HSE_STATUS_ERROR; } if (!watchdog_interval) wc_maintain(logger); jk_init_ws_service(&s); jk_open_pool(&private_data.p, buf, sizeof(buf)); private_data.bytes_read_so_far = 0; private_data.lpEcb = lpEcb; private_data.chunk_content = JK_FALSE; s.ws_private = &private_data; s.pool = &private_data.p; if (init_ws_service(&private_data, &s, &worker_name)) { jk_endpoint_t *e = NULL; jk_worker_t *worker = wc_get_worker_for_name(worker_name, logger); if (!worker) { jk_log(logger, JK_LOG_ERROR, "could not get a worker for name %s", worker_name); jk_close_pool(&private_data.p); JK_TRACE_EXIT(logger); return rc; } if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "got a worker for name %s", worker_name); if (worker->get_endpoint(worker, &e, logger)) { int is_error = JK_HTTP_SERVER_ERROR; int result; if ((result = e->service(e, &s, logger, &is_error)) > 0) { if (s.extension.use_server_error_pages && s.http_response_status >= s.extension.use_server_error_pages) { if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Forwarding status=%d" " for worker=%s", s.http_response_status, worker_name); lpEcb->dwHttpStatusCode = s.http_response_status; write_error_message(lpEcb, s.http_response_status, private_data.err_hdrs); } else { rc = HSE_STATUS_SUCCESS; lpEcb->dwHttpStatusCode = s.http_response_status; if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "service() returned OK"); } } else { if ((result == JK_CLIENT_ERROR) && (is_error == JK_HTTP_OK)) { jk_log(logger, JK_LOG_INFO, "service() failed because client aborted connection"); } else { jk_log(logger, JK_LOG_ERROR, "service() failed with http error %d", is_error); } lpEcb->dwHttpStatusCode = is_error; write_error_message(lpEcb, is_error, private_data.err_hdrs); } e->done(&e, logger); } else { int is_error = JK_HTTP_SERVER_BUSY; jk_log(logger, JK_LOG_ERROR, "Failed to obtain an endpoint to service request - " "your connection_pool_size is probably less than the threads in your web server!"); lpEcb->dwHttpStatusCode = is_error; write_error_message(lpEcb, is_error, private_data.err_hdrs); } } else { jk_log(logger, JK_LOG_ERROR, "failed to init service for request."); } jk_close_pool(&private_data.p); JK_TRACE_EXIT(logger); return rc; } BOOL WINAPI TerminateExtension(DWORD dwFlags) { return TerminateFilter(dwFlags); } BOOL WINAPI TerminateFilter(DWORD dwFlags) { UNREFERENCED_PARAMETER(dwFlags); if (dll_process_detach) { /* Simple case */ if (!is_inited) return TRUE; watchdog_interval = 0; if (watchdog_handle) { WaitForSingleObject(watchdog_handle, INFINITE); CloseHandle(watchdog_handle); watchdog_handle = NULL; } jk_shm_close(logger); if (logger) jk_close_file_logger(&logger); return TRUE; } EnterCriticalSection(&log_cs); if (!is_inited) { LeaveCriticalSection(&log_cs); return TRUE; } WaitForSingleObject(init_cs, INFINITE); if (is_inited) { is_inited = JK_FALSE; jk_log(logger, JK_LOG_INFO, "%s stopping", (FULL_VERSION_STRING)); watchdog_interval = 0; if (watchdog_handle) { WaitForSingleObject(watchdog_handle, INFINITE); CloseHandle(watchdog_handle); watchdog_handle = NULL; } wc_close(logger); if (is_mapread) { uri_worker_map_free(&uw_map, logger); is_mapread = JK_FALSE; } if (workers_map) { jk_map_free(&workers_map); } if (rewrite_map) { jk_map_free(&rewrite_map); } if (rregexp_map) { int i; for (i = 0; i < jk_map_size(rregexp_map); i++) { ap_regex_t *regexp = (ap_regex_t *)jk_map_value_at(rregexp_map, i); if (regexp) { ap_regfree(regexp); free(regexp); } } jk_map_free(&rregexp_map); } jk_shm_close(logger); if (logger) { jk_close_file_logger(&logger); } } ReleaseMutex(&init_cs); LeaveCriticalSection(&log_cs); return TRUE; } BOOL WINAPI DllMain(HINSTANCE hInst, /* Instance Handle of the DLL */ ULONG ulReason, /* Reason why NT called this DLL */ LPVOID lpReserved) /* Reserved parameter for future use */ { char fname[MAX_PATH]; UNREFERENCED_PARAMETER(lpReserved); switch (ulReason) { case DLL_PROCESS_ATTACH: if (GetModuleFileName(hInst, fname, sizeof(fname) - 12)) { char *p = strrchr(fname, '.'); if (p) { *p = '\0'; StringCbCopy(ini_file_name, MAX_PATH, fname); StringCbCat(ini_file_name, MAX_PATH, ".properties"); StringCbCopy(ini_mutex_name, MAX_PATH, "Global\\JK_"); StringCbCat(ini_mutex_name, MAX_PATH, fname); StringCbCat(ini_mutex_name, MAX_PATH, "_mutex"); p = &ini_mutex_name[10]; while (*p) { if (!isalnum((unsigned char)*p)) *p = '_'; else *p = toupper(*p); p++; } } else { /* Cannot obtain file name ? */ return FALSE; } if ((p = strrchr(fname, '\\'))) { *p++ = '\0'; StringCbCopy(dll_file_path, MAX_PATH, fname); jk_map_alloc(&jk_environment_map); jk_map_add(jk_environment_map, "JKISAPI_PATH", dll_file_path); jk_map_add(jk_environment_map, "JKISAPI_NAME", p); } else { /* Cannot obtain file name ? */ return JK_FALSE; } } else { return JK_FALSE; } /* Construct redirector headers to use for this redirector instance */ StringCbPrintf(URI_HEADER_NAME, RES_BUFFER_SIZE, HEADER_TEMPLATE, URI_HEADER_NAME_BASE, hInst); StringCbPrintf(QUERY_HEADER_NAME, RES_BUFFER_SIZE, HEADER_TEMPLATE, QUERY_HEADER_NAME_BASE, hInst); StringCbPrintf(WORKER_HEADER_NAME, RES_BUFFER_SIZE, HEADER_TEMPLATE, WORKER_HEADER_NAME_BASE, hInst); StringCbPrintf(WORKER_HEADER_INDEX, RES_BUFFER_SIZE, HEADER_TEMPLATE, WORKER_HEADER_INDEX_BASE, hInst); StringCbPrintf(TOMCAT_TRANSLATE_HEADER_NAME, RES_BUFFER_SIZE, HEADER_TEMPLATE, TOMCAT_TRANSLATE_HEADER_NAME_BASE, hInst); /* Construct the HTTP_ headers that will be seen in ExtensionProc */ StringCbPrintf(HTTP_URI_HEADER_NAME, RES_BUFFER_SIZE, HTTP_HEADER_TEMPLATE, URI_HEADER_NAME_BASE, hInst); StringCbPrintf(HTTP_QUERY_HEADER_NAME, RES_BUFFER_SIZE, HTTP_HEADER_TEMPLATE, QUERY_HEADER_NAME_BASE, hInst); StringCbPrintf(HTTP_WORKER_HEADER_NAME, RES_BUFFER_SIZE, HTTP_HEADER_TEMPLATE, WORKER_HEADER_NAME_BASE, hInst); StringCbPrintf(HTTP_WORKER_HEADER_INDEX, RES_BUFFER_SIZE, HTTP_HEADER_TEMPLATE, WORKER_HEADER_INDEX_BASE, hInst); InitializeCriticalSection(&log_cs); init_cs = CreateMutex(jk_get_sa_with_null_dacl(), FALSE, ini_mutex_name); if (init_cs == NULL && GetLastError() == ERROR_ALREADY_EXISTS) init_cs = OpenMutex(MUTEX_ALL_ACCESS, FALSE, ini_mutex_name); if (init_cs == NULL) return JK_FALSE; break; case DLL_PROCESS_DETACH: dll_process_detach = TRUE; __try { TerminateFilter(HSE_TERM_MUST_UNLOAD); } __except(1) { } if (init_cs != NULL) CloseHandle(init_cs); DeleteCriticalSection(&log_cs); break; default: break; } return TRUE; } static DWORD WINAPI watchdog_thread(void *param) { int i; if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Watchdog thread initialized with %u second interval", watchdog_interval); } while (watchdog_interval) { for (i = 0; i < (watchdog_interval * 10); i++) { if (!watchdog_interval) break; Sleep(100); } if (!watchdog_interval) break; if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Watchdog thread running"); } if (worker_mount_file[0]) { jk_shm_lock(); uri_worker_map_update(uw_map, 0, logger); jk_shm_unlock(); } wc_maintain(logger); } if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Watchdog thread finished"); } return 0; } /* * Reinitializes the logger, formatting the log file name if rotation is enabled, * and calculating the next rotation time if applicable. */ static int init_logger(int rotate) { int rc = JK_TRUE; int log_open = rotate; /* log is assumed open if a rotate is requested */ char *log_file_name; char log_file_name_buf[MAX_PATH*2]; jk_logger_t *org = NULL; /* If log rotation is enabled, format the log filename */ if ((log_rotationtime > 0) || (log_filesize > 0)) { time_t t; t = time(NULL); if (log_rotationtime > 0) { /* Align time to rotationtime intervals */ t = (t / log_rotationtime) * log_rotationtime; /* Calculate rotate time */ log_next_rotate_time = t + log_rotationtime; } log_file_name = log_file_name_buf; if (strchr(log_file, '%')) { struct tm *tm_now; /* If there are % format patterns in the log file name, * treat it as a strftime format */ tm_now = localtime(&t); strftime(log_file_name, sizeof(log_file_name_buf), log_file, tm_now); } else { /* Otherwise append the number of seconds to the base name */ StringCbPrintf(log_file_name, sizeof(log_file_name_buf), "%s.%d", log_file, (long)t); } } else { log_file_name = log_file; } /* Close the current log file if required, and the effective log file name has changed */ if (log_open && strncmp(log_file_name, log_file_effective, strlen(log_file_name)) != 0) { FILE* lf = ((jk_file_logger_t* )logger->logger_private)->logfile; fprintf(lf, "Log rotated to %s\n", log_file_name); fflush(lf); org = logger; log_open = JK_FALSE; } if (!log_open) { if (jk_open_file_logger(&logger, log_file_name, log_level)) { logger->log = iis_log_to_file; /* Remember the current log file name for the next potential rotate */ StringCbCopy(log_file_effective, sizeof(log_file_effective), log_file_name); rc = JK_TRUE; } else { logger = org; org = NULL; rc = JK_FALSE; } } if (org) jk_close_file_logger(&org); return rc; } /* * Checks whether the log needs to be rotated. Must be called while holding the log lock. * The behaviour here is based on the Apache rotatelogs program. * http://httpd.apache.org/docs/2.0/programs/rotatelogs.html */ static int JK_METHOD rotate_log_file(void) { int rc = JK_TRUE; int rotate = JK_FALSE; if (log_rotationtime > 0) { time_t t = time(NULL); if (t >= log_next_rotate_time) { rotate = JK_TRUE; } } else if (log_filesize > 0 && logger) { LARGE_INTEGER filesize; HANDLE h = (HANDLE)_get_osfhandle(fileno(((jk_file_logger_t *)(logger)->logger_private)->logfile)); GetFileSizeEx(h, &filesize); if ((ULONGLONG)filesize.QuadPart >= log_filesize) { rotate = JK_TRUE; } } if (rotate) { rc = init_logger(JK_TRUE); } return rc; } /* * Log messages to the log file, rotating the log when required. */ static int JK_METHOD iis_log_to_file(jk_logger_t *l, int level, int used, char *what) { int rc = JK_FALSE; if (l && (l->level <= level || level == JK_LOG_REQUEST_LEVEL) && l->logger_private && what && used > 0) { jk_file_logger_t *p = l->logger_private; rc = JK_TRUE; if (p->logfile) { #if 0 what[used++] = '\r'; #endif what[used++] = '\n'; what[used] = '\0'; /* Perform logging within critical section to protect rotation */ EnterCriticalSection(&log_cs); if (rotate_log_file() && logger) { /* The rotation process will reallocate the jk_logger_t structure, so refetch */ FILE *rotated = ((jk_file_logger_t *)logger->logger_private)->logfile; fputs(what, rotated); fflush(rotated); } LeaveCriticalSection(&log_cs); } } return rc; } static int init_jk(char *serverName) { char *p, shm_name[MAX_PATH]; int i, rc = JK_FALSE; init_logger(JK_FALSE); /* TODO: Use System logging to notify the user that * we cannot open the configured log file. */ StringCbCopy(shm_name, MAX_PATH, SHM_DEF_PREFIX); jk_log(logger, JK_LOG_INFO, "Starting " FULL_VERSION_STRING); StringCbCat(shm_name, MAX_PATH, serverName); StringCbCat(shm_name, MAX_PATH, "_"); StringCbCat(shm_name, MAX_PATH, extension_uri + 1); if ((p = strrchr(shm_name, '.'))) *p = '\0'; jk_set_worker_def_cache_size(DEFAULT_WORKER_THREADS); /* Logging the initialization type: registry or properties file in virtual dir */ if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Detected IIS version %d.%d", iis_info.major, iis_info.minor); if (using_ini_file) { jk_log(logger, JK_LOG_DEBUG, "Using ini file %s.", ini_file_name); } else { jk_log(logger, JK_LOG_DEBUG, "Using registry."); } jk_log(logger, JK_LOG_DEBUG, "Using log file %s.", log_file); jk_log(logger, JK_LOG_DEBUG, "Using log level %d.", log_level); jk_log(logger, JK_LOG_DEBUG, "Using log rotation time %d seconds.", log_rotationtime); jk_log(logger, JK_LOG_DEBUG, "Using log file size %d bytes.", log_filesize); jk_log(logger, JK_LOG_DEBUG, "Using extension uri %s.", extension_uri); jk_log(logger, JK_LOG_DEBUG, "Using worker file %s.", worker_file); jk_log(logger, JK_LOG_DEBUG, "Using worker mount file %s.", worker_mount_file); jk_log(logger, JK_LOG_DEBUG, "Using rewrite rule file %s.", rewrite_rule_file); jk_log(logger, JK_LOG_DEBUG, "Using uri select %d.", uri_select_option); jk_log(logger, JK_LOG_DEBUG, "Using%s chunked encoding.", (chunked_encoding_enabled ? "" : " no")); jk_log(logger, JK_LOG_DEBUG, "Using notification event %s (0x%08x)", (iis_info.filter_notify_event == SF_NOTIFY_AUTH_COMPLETE) ? "SF_NOTIFY_AUTH_COMPLETE" : ((iis_info.filter_notify_event == SF_NOTIFY_PREPROC_HEADERS) ? "SF_NOTIFY_PREPROC_HEADERS" : "UNKNOWN"), iis_info.filter_notify_event); if (error_page) { jk_log(logger, JK_LOG_DEBUG, "Using error page '%s'.", error_page); } jk_log(logger, JK_LOG_DEBUG, "Using uri header %s.", URI_HEADER_NAME); jk_log(logger, JK_LOG_DEBUG, "Using query header %s.", QUERY_HEADER_NAME); jk_log(logger, JK_LOG_DEBUG, "Using worker header %s.", WORKER_HEADER_NAME); jk_log(logger, JK_LOG_DEBUG, "Using worker index %s.", WORKER_HEADER_INDEX); jk_log(logger, JK_LOG_DEBUG, "Using translate header %s.", TOMCAT_TRANSLATE_HEADER_NAME); jk_log(logger, JK_LOG_DEBUG, "Using a default of %d connections per pool.", DEFAULT_WORKER_THREADS); } if ((log_rotationtime > 0) && (log_filesize > 0)) { jk_log(logger, JK_LOG_WARNING, "%s is defined in configuration, but will be ignored because %s is set. ", LOG_FILESIZE_TAG, LOG_ROTATION_TIME_TAG); } if (rewrite_rule_file[0] && jk_map_alloc(&rewrite_map)) { if (jk_map_read_properties(rewrite_map, NULL, rewrite_rule_file, NULL, JK_MAP_HANDLE_RAW, logger)) { if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Loaded rewrite rule file %s.", rewrite_rule_file); } jk_map_alloc(&rregexp_map); for (i = 0; i < jk_map_size(rewrite_map); i++) { const char *src = jk_map_name_at(rewrite_map, i); if (*src == '~') { ap_regex_t *regexp = malloc(sizeof(ap_regex_t)); const char *val = jk_map_value_at(rewrite_map, i); /* Skip leading tilde */ regexp->real = src + 1; regexp->fake = val; if (!ap_regcomp(regexp, regexp->real, AP_REG_EXTENDED)) { jk_map_add(rregexp_map, regexp->real, regexp); if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Added regular expression rule %s -> %s", regexp->real, regexp->fake); } } else { jk_log(logger, JK_LOG_ERROR, "Unable to compile regular expression %s", regexp->real); free(regexp); } } } } else { jk_map_free(&rewrite_map); rewrite_map = NULL; } } if (uri_worker_map_alloc(&uw_map, NULL, logger)) { rc = JK_FALSE; if (reject_unsafe) uw_map->reject_unsafe = 1; else uw_map->reject_unsafe = 0; uw_map->collapse_slashes = collapse_slashes; uw_map->reload = worker_mount_reload; if (worker_mount_file[0]) { uw_map->fname = worker_mount_file; rc = uri_worker_map_load(uw_map, logger); } } if (rc) { rc = JK_FALSE; if (jk_map_alloc(&workers_map)) { if (jk_map_read_properties(workers_map, NULL, worker_file, NULL, JK_MAP_HANDLE_DUPLICATES, logger)) { int rv = -1; /* we add the URI->WORKER MAP since workers using AJP14 will feed it */ if (jk_map_resolve_references(workers_map, "worker.", 1, 1, logger) == JK_FALSE) { jk_log(logger, JK_LOG_ERROR, "Error in resolving configuration references"); } /* * Create named shared memory for each server */ if (shm_config_size == -1) { shm_config_size = jk_shm_calculate_size(workers_map, logger); } else if (shm_config_size > 0) { jk_log(logger, JK_LOG_WARNING, "The optimal shared memory size can now be determined automatically."); jk_log(logger, JK_LOG_WARNING, "You can remove the shm_size attribute if you want to use the optimal size."); } if ((shm_config_size > 0) && (rv = jk_shm_open(shm_name, shm_config_size, logger)) != 0) { jk_log(logger, JK_LOG_ERROR, "Initializing shm:%s errno=%d. Load balancing workers will not function properly", jk_shm_name(), rv); } if (rv != 0 && (rv = jk_shm_open(NULL, shm_config_size, logger)) != 0) { /* Do not try to open the worker if we cannot create * the shared memory segment or heap memory. */ jk_log(logger, JK_LOG_EMERG, "Initializing shm:%s errno=%d. Cannot continue", jk_shm_name(), rv); jk_map_free(&workers_map); workers_map = NULL; return JK_FALSE; } else { if (shm_loaded_name[0]) { if (strcmp(shm_loaded_name, shm_name)) { jk_log(logger, JK_LOG_WARNING, "Loading different shared memory %s. Already loaded %s", shm_name, shm_loaded_name); } } else { StringCbCopy(shm_loaded_name, MAX_PATH, shm_name); } } worker_env.uri_to_worker = uw_map; worker_env.server_name = serverName; worker_env.pool = NULL; if (wc_open(workers_map, &worker_env, logger)) { rc = JK_TRUE; uri_worker_map_ext(uw_map, logger); uri_worker_map_switch(uw_map, logger); } else { jk_shm_close(logger); } } else { jk_log(logger, JK_LOG_EMERG, "Unable to read worker file %s. (errno=%d, err=%s)", worker_file, errno, strerror(errno)); } if (rc != JK_TRUE) { jk_map_free(&workers_map); workers_map = NULL; } } } if (rc) { if (watchdog_interval) { DWORD wi; watchdog_handle = CreateThread(NULL, 0, watchdog_thread, NULL, 0, &wi); if (!watchdog_handle) { jk_log(logger, JK_LOG_EMERG, "Error %d (0x%08x) creating Watchdog thread", GetLastError(), GetLastError()); watchdog_interval = 0; } } jk_log(logger, JK_LOG_INFO, "%s initialized", (FULL_VERSION_STRING)); } return rc; } static BOOL initialize_extension(void) { if (read_registry_init_data()) { if (get_iis_info(&iis_info) != JK_TRUE) { jk_log(logger, JK_LOG_ERROR, "Could not retrieve IIS version from registry"); } else { if (use_auth_notification_flags) iis_info.filter_notify_event = SF_NOTIFY_AUTH_COMPLETE; else iis_info.filter_notify_event = SF_NOTIFY_PREPROC_HEADERS; } is_inited = JK_TRUE; } return is_inited; } int parse_uri_select(const char *uri_select) { if (!strcasecmp(uri_select, URI_SELECT_PARSED_VERB)) return URI_SELECT_OPT_PARSED; if (!strcasecmp(uri_select, URI_SELECT_UNPARSED_VERB)) return URI_SELECT_OPT_UNPARSED; if (!strcasecmp(uri_select, URI_SELECT_ESCAPED_VERB)) return URI_SELECT_OPT_ESCAPED; if (!strcasecmp(uri_select, URI_SELECT_PROXY_VERB)) return URI_SELECT_OPT_PROXY; return -1; } int parse_collapse_slashes(const char *collapse_slashes) { if (!strcasecmp(collapse_slashes, COLLAPSE_SLASHES_ALL_VERB)) return JK_COLLAPSE_ALL; if (!strcasecmp(collapse_slashes, COLLAPSE_SLASHES_NONE_VERB)) return JK_COLLAPSE_NONE; if (!strcasecmp(collapse_slashes, COLLAPSE_SLASHES_UNMOUNT_VERB)) return JK_COLLAPSE_UNMOUNT; return -1; } static int read_registry_init_data(void) { char tmpbuf[MAX_PATH]; int ok = JK_FALSE; LPVOID src; HKEY hkey; int remain; jk_map_t *map = NULL; remain = jk_check_buffer_size(); if (remain < 0) { jk_log(logger, JK_LOG_ERROR, "mod_jk: JK_MAX_ATTRIBUTE_NAME_LEN in jk_util.c is too small, " "increase by %d", -1 * remain); } if (jk_map_alloc(&map)) { if (jk_map_read_properties(map, jk_environment_map, ini_file_name, NULL, JK_MAP_HANDLE_DUPLICATES, logger)) { using_ini_file = JK_TRUE; src = map; } else { jk_map_free(&map); } } if (!using_ini_file) { long rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGISTRY_LOCATION, (DWORD)0, KEY_READ, &hkey); if (ERROR_SUCCESS != rc) { return JK_FALSE; } else { src = hkey; } } if (!get_config_parameter(src, JK_LOG_FILE_TAG, log_file, sizeof(log_file))) goto cleanup; if (is_path_relative(log_file)) { char *fp = path_merge(dll_file_path, log_file); if (fp) { StringCbCopy(log_file, sizeof(log_file), fp); free(fp); } } if (get_config_parameter(src, JK_LOG_LEVEL_TAG, tmpbuf, sizeof(tmpbuf))) { log_level = jk_parse_log_level(tmpbuf); } if (get_config_parameter(src, LOG_ROTATION_TIME_TAG, tmpbuf, sizeof(tmpbuf))) { log_rotationtime = atol(tmpbuf); if (log_rotationtime < 0) { log_rotationtime = 0; } } if (get_config_parameter(src, LOG_FILESIZE_TAG, tmpbuf, sizeof(tmpbuf))) { int tl = lstrlenA(tmpbuf); if (tl > 0) { /* rotatelogs has an 'M' suffix on filesize, which we optionally support for consistency */ if (tmpbuf[tl - 1] == 'M') { tmpbuf[tl - 1] = '\0'; } log_filesize = atol(tmpbuf); if (log_filesize < 0) { log_filesize = 0; } /* Convert to MB as per Apache rotatelogs */ log_filesize *= (1000 * 1000); } } if (!get_config_parameter(src, EXTENSION_URI_TAG, extension_uri, sizeof(extension_uri))) goto cleanup; if (!get_config_parameter(src, JK_WORKER_FILE_TAG, worker_file, sizeof(worker_file))) goto cleanup; if (is_path_relative(worker_file)) { char *fp = path_merge(dll_file_path, worker_file); if (fp) { StringCbCopy(worker_file, sizeof(worker_file), fp); free(fp); } } if (!get_config_parameter(src, JK_MOUNT_FILE_TAG, worker_mount_file, sizeof(worker_mount_file))) goto cleanup; if (is_path_relative(worker_mount_file)) { char *fp = path_merge(dll_file_path, worker_mount_file); if (fp) { StringCbCopy(worker_mount_file, sizeof(worker_mount_file), fp); free(fp); } } if (get_config_parameter(src, URI_REWRITE_TAG, rewrite_rule_file, sizeof(rewrite_rule_file))) { if (is_path_relative(rewrite_rule_file)) { char *fp = path_merge(dll_file_path, rewrite_rule_file); if (fp) { StringCbCopy(rewrite_rule_file, sizeof(rewrite_rule_file), fp); free(fp); } } } if (get_config_parameter(src, URI_SELECT_TAG, tmpbuf, sizeof(tmpbuf))) { int opt = parse_uri_select(tmpbuf); if (opt >= 0) { uri_select_option = opt; } else { jk_log(logger, JK_LOG_ERROR, "Invalid value '%s' for configuration item '" URI_SELECT_TAG "'", tmpbuf); } } if (get_config_parameter(src, COLLAPSE_SLASHES_TAG, tmpbuf, sizeof(tmpbuf))) { int opt = parse_collapse_slashes(tmpbuf); if (opt >= 0) { collapse_slashes = opt; } else { jk_log(logger, JK_LOG_ERROR, "Invalid value '%s' for configuration item '" COLLAPSE_SLASHES_TAG "'", tmpbuf); } } shm_config_size = get_config_int(src, SHM_SIZE_TAG, -1); worker_mount_reload = get_config_int(src, WORKER_MOUNT_RELOAD_TAG, JK_URIMAP_DEF_RELOAD); strip_session = get_config_bool(src, STRIP_SESSION_TAG, JK_FALSE); use_auth_notification_flags = get_config_int(src, AUTH_COMPLETE_TAG, 1); reject_unsafe = get_config_bool(src, REJECT_UNSAFE_TAG, JK_FALSE); watchdog_interval = get_config_int(src, WATCHDOG_INTERVAL_TAG, 0); if (watchdog_interval < 0) watchdog_interval = 0; chunked_encoding_enabled = get_config_bool(src, ENABLE_CHUNKED_ENCODING_TAG, JK_FALSE); if (get_config_parameter(src, ERROR_PAGE_TAG, error_page_buf, sizeof(error_page_buf))) { error_page = error_page_buf; } ok = JK_TRUE; cleanup: if (using_ini_file) { jk_map_free(&map); } else { RegCloseKey(hkey); } return ok; } static int get_config_parameter(LPVOID src, const char *tag, char *val, size_t sz) { const char *tmp = NULL; if (using_ini_file) { tmp = jk_map_get_string((jk_map_t*)src, tag, NULL); if (tmp && (strlen(tmp) < sz)) { StringCbCopy(val, sz, tmp); return JK_TRUE; } else { return JK_FALSE; } } else { return get_registry_config_parameter((HKEY)src, tag, val, sz); } } static int get_config_int(LPVOID src, const char *tag, int def) { if (using_ini_file) { return jk_map_get_int((jk_map_t*)src, tag, def); } else { int val; if (get_registry_config_number(src, tag, &val) ) { return val; } else { return def; } } } static int get_config_bool(LPVOID src, const char *tag, int def) { if (using_ini_file) { return jk_map_get_bool((jk_map_t*)src, tag, def); } else { char tmpbuf[128]; if (get_registry_config_parameter(src, tag, tmpbuf, sizeof(tmpbuf))) { return jk_get_bool_code(tmpbuf, def); } else { return def; } } } static int get_registry_config_parameter(HKEY hkey, const char *tag, char *b, size_t sz) { DWORD type = 0; LONG lrc; DWORD ssz = (DWORD)sz -1; b[ssz] = '\0'; /* Null terminate in case RegQueryValueEx doesn't */ lrc = RegQueryValueEx(hkey, tag, NULL, &type, (LPBYTE)b, &ssz); if ((ERROR_SUCCESS != lrc) || (type != REG_SZ)) { return JK_FALSE; } return JK_TRUE; } static int get_registry_config_number(HKEY hkey, const char *tag, int *val) { DWORD type = 0; DWORD data = 0; DWORD sz = sizeof(DWORD); LONG lrc; lrc = RegQueryValueEx(hkey, tag, NULL, &type, (LPBYTE)&data, &sz); if ((ERROR_SUCCESS != lrc) || (type != REG_DWORD)) { return JK_FALSE; } *val = (int)data; return JK_TRUE; } static int init_ws_service(isapi_private_data_t * private_data, jk_ws_service_t *s, char **worker_name) { char *all_headers; int worker_index = -1; rule_extension_t *e; char temp_buf[64]; BOOL unknown_content_length = FALSE; unsigned int cnt = 0; char *tmp; JK_TRACE_ENTER(logger); s->start_response = start_response; s->read = iis_read; s->write = iis_write; s->done = iis_done; GET_SERVER_VARIABLE_VALUE(HTTP_WORKER_HEADER_NAME, (*worker_name)); GET_SERVER_VARIABLE_VALUE(HTTP_URI_HEADER_NAME, s->req_uri); GET_SERVER_VARIABLE_VALUE(HTTP_QUERY_HEADER_NAME, s->query_string); GET_SERVER_VARIABLE_VALUE_INT(HTTP_WORKER_HEADER_INDEX, worker_index, -1); if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Reading extension header %s: %s", HTTP_WORKER_HEADER_NAME, (*worker_name)); jk_log(logger, JK_LOG_DEBUG, "Reading extension header %s: %d", HTTP_WORKER_HEADER_INDEX, worker_index); jk_log(logger, JK_LOG_DEBUG, "Reading extension header %s: %s", HTTP_URI_HEADER_NAME, s->req_uri); jk_log(logger, JK_LOG_DEBUG, "Reading extension header %s: %s", HTTP_QUERY_HEADER_NAME, s->query_string); } if (s->req_uri == NULL) { if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "No URI header value provided. Defaulting to old behaviour" ); s->query_string = private_data->lpEcb->lpszQueryString; *worker_name = DEFAULT_WORKER_NAME; GET_SERVER_VARIABLE_VALUE("URL", s->req_uri); if (unescape_url(s->req_uri) < 0) { JK_TRACE_EXIT(logger); return JK_FALSE; } getparents(s->req_uri); } GET_SERVER_VARIABLE_VALUE("AUTH_TYPE", s->auth_type); GET_SERVER_VARIABLE_VALUE("REMOTE_USER", s->remote_user); GET_SERVER_VARIABLE_VALUE("SERVER_PROTOCOL", s->protocol); GET_SERVER_VARIABLE_VALUE("REMOTE_HOST", s->remote_host); GET_SERVER_VARIABLE_VALUE("REMOTE_ADDR", s->remote_addr); GET_SERVER_VARIABLE_VALUE("REMOTE_PORT", s->remote_port); GET_SERVER_VARIABLE_VALUE("SERVER_NAME", s->server_name); GET_SERVER_VARIABLE_VALUE("LOCAL_ADDR", s->local_addr); GET_SERVER_VARIABLE_VALUE_INT("SERVER_PORT", s->server_port, 80); GET_SERVER_VARIABLE_VALUE("SERVER_SOFTWARE", s->server_software); GET_SERVER_VARIABLE_VALUE_INT("SERVER_PORT_SECURE", s->is_ssl, 0); s->method = private_data->lpEcb->lpszMethod; /* Check for Transfer Encoding */ if (get_server_value(private_data->lpEcb, "HTTP_TRANSFER_ENCODING", temp_buf, sizeof(temp_buf))) { if (strcasecmp(temp_buf, TRANSFER_ENCODING_CHUNKED_VALUE) == 0) { s->is_chunked = JK_TRUE; if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Request is Transfer-Encoding: chunked"); } } else { /* XXX: What to do with non chunked T-E ? */ if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Unsupported Transfer-Encoding: %s", temp_buf); } } if (private_data->lpEcb->cbTotalBytes == 0xFFFFFFFF) { /* We have size larger then 4Gb or Transfer-Encoding: chunked * ReadClient should be called until no more data is returned */ unknown_content_length = TRUE; } else { /* Use the IIS provided content length */ s->content_length = (jk_uint64_t)private_data->lpEcb->cbTotalBytes; } e = get_uri_to_worker_ext(uw_map, worker_index); if (e) { if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "Applying service extensions" ); s->extension.reply_timeout = e->reply_timeout; s->extension.sticky_ignore = e->sticky_ignore; s->extension.stateless = e->stateless; s->extension.use_server_error_pages = e->use_server_error_pages; if (e->activation) { s->extension.activation = jk_pool_alloc(s->pool, e->activation_size * sizeof(int)); memcpy(s->extension.activation, e->activation, e->activation_size * sizeof(int)); } if (e->fail_on_status_size > 0) { s->extension.fail_on_status_size = e->fail_on_status_size; s->extension.fail_on_status = jk_pool_alloc(s->pool, e->fail_on_status_size * sizeof(int)); memcpy(s->extension.fail_on_status, e->fail_on_status, e->fail_on_status_size * sizeof(int)); } if (e->session_cookie) { s->extension.session_cookie = jk_pool_strdup(s->pool, e->session_cookie); } if (e->session_path) { s->extension.session_path = jk_pool_strdup(s->pool, e->session_path); } if (e->set_session_cookie) { s->extension.set_session_cookie = e->set_session_cookie; } if (e->session_cookie_path) { s->extension.session_cookie_path = jk_pool_strdup(s->pool, e->session_cookie_path); } } s->uw_map = uw_map; /* * Add SSL IIS environment */ if (s->is_ssl) { char *ssl_env_names[9] = { "CERT_ISSUER", "CERT_SUBJECT", "CERT_COOKIE", "HTTPS_SERVER_SUBJECT", "CERT_FLAGS", "HTTPS_SECRETKEYSIZE", "CERT_SERIALNUMBER", "HTTPS_SERVER_ISSUER", "HTTPS_KEYSIZE" }; char *ssl_env_values[9] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; unsigned int i; unsigned int num_of_vars = 0; for (i = 0; i < 9; i++) { GET_SERVER_VARIABLE_VALUE(ssl_env_names[i], ssl_env_values[i]); if (ssl_env_values[i]) { num_of_vars++; } } /* XXX: To make the isapi plugin more consistent with the other web servers */ /* we should also set s->ssl_cipher, s->ssl_session, and s->ssl_key_size. */ if (num_of_vars) { unsigned int j = 0; s->attributes_names = jk_pool_alloc(&private_data->p, num_of_vars * sizeof(char *)); s->attributes_values = jk_pool_alloc(&private_data->p, num_of_vars * sizeof(char *)); if (!s->attributes_names || !s->attributes_values) { JK_TRACE_EXIT(logger); return JK_FALSE; } for (i = 0; i < 9; i++) { if (ssl_env_values[i]) { s->attributes_names[j] = ssl_env_names[i]; s->attributes_values[j] = ssl_env_values[i]; j++; } } s->num_attributes = num_of_vars; if (ssl_env_values[4] && ssl_env_values[4][0] == '1') { CERT_CONTEXT_EX cc; BYTE *cb = jk_pool_alloc(&private_data->p, AJP13_MAX_PACKET_SIZE); if (!cb) { JK_TRACE_EXIT(logger); return JK_FALSE; } cc.cbAllocated = AJP13_MAX_PACKET_SIZE; cc.CertContext.pbCertEncoded = cb; cc.CertContext.cbCertEncoded = 0; if (private_data->lpEcb->ServerSupportFunction(private_data->lpEcb->ConnID, HSE_REQ_GET_CERT_INFO_EX, &cc, NULL, NULL) != FALSE) { jk_log(logger, JK_LOG_DEBUG, "Client Certificate encoding:%d sz:%d flags:%ld", cc.CertContext. dwCertEncodingType & X509_ASN_ENCODING, cc.CertContext.cbCertEncoded, cc.dwCertificateFlags); s->ssl_cert = jk_pool_alloc(&private_data->p, base64_encode_cert_len(cc.CertContext.cbCertEncoded)); s->ssl_cert_len = base64_encode_cert(s->ssl_cert, cb, cc.CertContext.cbCertEncoded) - 1; } } } } GET_SERVER_VARIABLE_VALUE(ALL_HEADERS, all_headers); if (!all_headers) { JK_TRACE_EXIT(logger); return JK_FALSE; } for (tmp = all_headers; *tmp; tmp++) { if (*tmp == '\n') { cnt++; } } if (cnt) { char *headers_buf = all_headers; unsigned int i; BOOL need_content_length_header = FALSE; if (s->content_length == 0 && unknown_content_length == FALSE) { /* Add content-length=0 only if really zero */ need_content_length_header = TRUE; } /* allocate an extra header slot in case we need to add a content-length header */ s->headers_names = jk_pool_alloc(&private_data->p, (cnt + 1) * sizeof(char *)); s->headers_values = jk_pool_alloc(&private_data->p, (cnt + 1) * sizeof(char *)); if (!s->headers_names || !s->headers_values) { JK_TRACE_EXIT(logger); return JK_FALSE; } for (i = 0, tmp = headers_buf; *tmp && i < cnt;) { int real_header = JK_TRUE; #ifdef USE_CGI_HEADERS /* Skip the HTTP_ prefix to the beginning of the header name */ tmp += HTTP_HEADER_PREFIX_LEN; #endif if (!strnicmp(tmp, URI_HEADER_NAME, strlen(URI_HEADER_NAME)) || !strnicmp(tmp, WORKER_HEADER_NAME, strlen(WORKER_HEADER_NAME)) || !strnicmp(tmp, WORKER_HEADER_INDEX, strlen(WORKER_HEADER_INDEX)) || !strnicmp(tmp, QUERY_HEADER_NAME, strlen(QUERY_HEADER_NAME))) { /* Skip redirector headers */ cnt--; real_header = JK_FALSE; } else if (!strnicmp(tmp, CONTENT_LENGTH, sizeof(CONTENT_LENGTH) - 1)) { need_content_length_header = FALSE; /* If the content-length is unknown * or larger then 4Gb do not send it. * IIS can also create a synthetic Content-Length header to make * lpcbTotalBytes and the CONTENT_LENGTH server variable agree * on small requests where the entire chunk encoded message is * read into the available buffer. */ if (unknown_content_length || s->is_chunked) { if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Disregarding Content-Length in request - content is %s", s->is_chunked ? "chunked" : "unknown length"); } cnt--; real_header = JK_FALSE; } else { s->headers_names[i] = tmp; } } else if (!strnicmp(tmp, TOMCAT_TRANSLATE_HEADER_NAME, strlen(TOMCAT_TRANSLATE_HEADER_NAME))) { s->headers_names[i] = TRANSLATE_HEADER_NAME_LC; } else { s->headers_names[i] = tmp; } while (':' != *tmp && *tmp) { #ifdef USE_CGI_HEADERS if (real_header) { if ('_' == *tmp) { *tmp = '-'; } else { *tmp = JK_TOLOWER(*tmp); } } #endif tmp++; } *tmp++ = '\0'; /* Skip all the WS chars after the ':' to the beginning of the header value */ while (' ' == *tmp || '\t' == *tmp || '\v' == *tmp) { tmp++; } if (real_header) { s->headers_values[i] = tmp; } while (*tmp && *tmp != '\n' && *tmp != '\r') { tmp++; } *tmp++ = '\0'; /* skip CR LF */ while (*tmp == '\n' || *tmp == '\r') { tmp++; } if (real_header) { if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Forwarding request header %s : %s", s->headers_names[i], s->headers_values[i]); } i++; } } /* Add a content-length = 0 header if needed. * Ajp13 assumes an absent content-length header means an unknown, * but non-zero length body. */ if (need_content_length_header) { if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Incoming request needs explicit Content-Length: 0 in AJP13"); } s->headers_names[cnt] = "Content-Length"; s->headers_values[cnt] = "0"; cnt++; } s->num_headers = cnt; } else { JK_TRACE_EXIT(logger); return JK_FALSE; } /* Dump all connection param so we can trace what's going to * the remote tomcat */ if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Service protocol=%s method=%s host=%s addr=%s name=%s port=%d " "auth=%s user=%s uri=%s", STRNULL_FOR_NULL(s->protocol), STRNULL_FOR_NULL(s->method), STRNULL_FOR_NULL(s->remote_host), STRNULL_FOR_NULL(s->remote_addr), STRNULL_FOR_NULL(s->server_name), s->server_port, STRNULL_FOR_NULL(s->auth_type), STRNULL_FOR_NULL(s->remote_user), STRNULL_FOR_NULL(s->req_uri)); jk_log(logger, JK_LOG_DEBUG, "Service request headers=%d attributes=%d " "chunked=%s content-length=%" JK_UINT64_T_FMT " available=%u", s->num_headers, s->num_attributes, (s->is_chunked == JK_TRUE) ? "yes" : "no", s->content_length, private_data->lpEcb->cbTotalBytes); } JK_TRACE_EXIT(logger); return JK_TRUE; } static BOOL get_server_value(LPEXTENSION_CONTROL_BLOCK lpEcb, char *name, char *buf, size_t bufsz) { DWORD sz = (DWORD)bufsz; buf[0] = '\0'; return lpEcb->GetServerVariable(lpEcb->ConnID, name, buf, &sz); } static char *dup_server_value(LPEXTENSION_CONTROL_BLOCK lpEcb, const char *name, jk_pool_t *p) { DWORD sz = HDR_BUFFER_SIZE; char buf[HDR_BUFFER_SIZE]; char *dp; if (lpEcb->GetServerVariable(lpEcb->ConnID, (LPSTR)name, buf, &sz)) return jk_pool_strdup(p, buf); if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return NULL; if ((dp = jk_pool_alloc(p, sz))) { if (lpEcb->GetServerVariable(lpEcb->ConnID, (LPSTR)name, dp, &sz)) return dp; } return NULL; } static const char begin_cert[] = "-----BEGIN CERTIFICATE-----\r\n"; static const char end_cert[] = "-----END CERTIFICATE-----\r\n"; static const char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static int base64_encode_cert_len(int len) { int n = ((len + 2) / 3 * 4) + 1; /* base64 encoded size */ n += (n + 63 / 64) * 2; /* add CRLF's */ n += sizeof(begin_cert) + sizeof(end_cert) - 2; /* add enclosing strings. */ return n; } static int base64_encode_cert(char *encoded, const char *string, int len) { int i, c; char *p; const char *t; p = encoded; t = begin_cert; while (*t != '\0') *p++ = *t++; c = 0; for (i = 0; i < len - 2; i += 3) { *p++ = basis_64[(string[i] >> 2) & 0x3F]; *p++ = basis_64[((string[i] & 0x3) << 4) | ((int)(string[i + 1] & 0xF0) >> 4)]; *p++ = basis_64[((string[i + 1] & 0xF) << 2) | ((int)(string[i + 2] & 0xC0) >> 6)]; *p++ = basis_64[string[i + 2] & 0x3F]; c += 4; if (c >= 64) { *p++ = '\r'; *p++ = '\n'; c = 0; } } if (i < len) { *p++ = basis_64[(string[i] >> 2) & 0x3F]; if (i == (len - 1)) { *p++ = basis_64[((string[i] & 0x3) << 4)]; *p++ = '='; } else { *p++ = basis_64[((string[i] & 0x3) << 4) | ((int)(string[i + 1] & 0xF0) >> 4)]; *p++ = basis_64[((string[i + 1] & 0xF) << 2)]; } *p++ = '='; c++; } if (c != 0) { *p++ = '\r'; *p++ = '\n'; } t = end_cert; while (*t != '\0') *p++ = *t++; *p++ = '\0'; return (int)(p - encoded); } /** * Determine version info and the primary notification event */ static int get_iis_info(iis_info_t* iis_info) { HKEY hkey; int rv = JK_FALSE; iis_info->major = 0; iis_info->minor = 0; /* Retrieve the IIS version Major/Minor */ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, W3SVC_REGISTRY_KEY, 0, KEY_READ, &hkey) == ERROR_SUCCESS) { if (get_registry_config_number(hkey, "MajorVersion", &iis_info->major) == JK_TRUE && get_registry_config_number(hkey, "MinorVersion", &iis_info->minor) == JK_TRUE) { rv = JK_TRUE; } CloseHandle(hkey); } return rv; } /* * 1. Remove //?/ prefix * 2. Replace UNC/ with // */ static __inline char *NO2UNC(char *fname) { if (fname[0] == '/' && fname[1] == '/' && fname[2] == '?' && fname[3] == '/') { fname += 4; if (fname[0] == 'U' && fname[1] == 'N' && fname[2] == 'C' && fname[3] == '/') { fname += 2; *fname = '/'; } else if (fname[0] == 'U' && fname[1] == 'N' && fname[2] == '/' && fname[3] == '/') { fname += 2; /* Already modified in-place. */ fname += 2; } } return fname; } static __inline void FS2BSA(char *str) { for (; *str != 0; str++) { if (*str == '/') *str = '\\'; } } static __inline void BS2FSA(char *str) { for (; *str != 0; str++) { if (*str == '\\') *str = '/'; } } #define NON_UNC_PATH_LENGTH 248 #define IS_PATH_SEP(C) ((C) == '/' || (C) == '\0') #define IS_DRIVE_CHAR(C) (((C) >= 'A' && (C) <= 'Z') || \ ((C) >= 'a' && (C) <= 'z')) #define _INS_TRAILING_PATH_SEP(s, l) \ if (l > 0 && s[l - 1] != '/') s[l++] = '/', s[l] = '\0' #define _DEL_TRAILING_PATH_SEP(s, l) \ do { \ if (l > 1 && s[l - 1] == '/') { \ if (s[l - 2] != '/' && s[l - 2] != ':') \ s[--l] = '\0'; \ } \ } while(0) static char *skip_prefix(char *path, char **sp) { size_t size; char *cp; /* Convert everything to forward slashes */ BS2FSA(path); /* Remove \\?\ and replace \\?\UNC\ with \\ */ path = NO2UNC(path); size = strlen(path); *sp = path; if (size < 2) { if (path[0] == ' ') { /* Single Trailing space is invalid path */ SetLastError(ERROR_BAD_PATHNAME); return 0; } return path; } else { /* Remove any trailing slash unless this is * a single slash path. */ _DEL_TRAILING_PATH_SEP(path, size); if (path[size - 1] == ' ' || path[size - 1] == '.') { /* Trailing space and dot are invalid file or dir names */ SetLastError(ERROR_BAD_PATHNAME); return 0; } } if (size > 1 && path[1] == ':' && IS_DRIVE_CHAR(path[0])) { /* Never go above C: */ path += 2; } else if (path[0] == '/' && path[1] == '/') { /* Never go above //share/ */ if (path[2] == '.' && path[3] == '/') { /* This is probably //./pipe/ */ return path; } cp = strchr(path + 2, '/'); if (cp != 0) path = cp; else { /* We only have //share */ return path; } } return path; } static char *relative_path(char *path, int* remain) { char *sp; char *cp; int ch = '/'; path = skip_prefix(path, &sp); if (!path) return 0; if (path != sp) { /* Unexpected. Expected a relative path, but it starts with C: or //share/ */ SetLastError(ERROR_BAD_PATHNAME); return 0; } cp = path; while (*path) { if (IS_PATH_SEP(ch) && *path == '.') { /* nd: number of consecutive dot characters */ int nd = 0; while (path[nd] == '.') nd++; if (IS_PATH_SEP(path[nd])) { if (nd > 2) { SetLastError(ERROR_BAD_PATHNAME); return 0; } path += nd; if (*path) path++; if (nd > 1) { if (cp > sp + 1) { cp--; while (cp > sp) { if (IS_PATH_SEP(*(cp - 1))) break; cp--; } } else { (*remain)++; } } } else { ch = *cp++ = *path++; } } else { ch = *cp++ = *path++; } } *cp = '\0'; return sp; } static char *path_merge(const char *root, const char *path) { char merge[8192]; char dir[MAX_PATH]; char *rel; char *out = 0; size_t sz; size_t rsz; int remain = 0; if (root == NULL || path == NULL) { SetLastError(ERROR_INVALID_PARAMETER ); return 0; } if (FAILED(StringCbCopy(dir, MAX_PATH, root))) { SetLastError(ERROR_FILENAME_EXCED_RANGE); return 0; } if (FAILED(StringCbCopy(merge, 8190, path))) { /* TODO: Use dynamic buffer with larger size */ SetLastError(ERROR_FILENAME_EXCED_RANGE); return 0; } sz = strlen(merge); rsz = strlen(dir); /* Normalize path */ if ((rel = relative_path(merge, &remain))) { size_t bl; if (remain > 0) { char *skip = dir + rsz - 1; char *spr; char *start = skip_prefix(dir, &spr); if (*skip == '/') skip--; while (remain > 0 && skip >= start) { if (*skip == '/') { remain--; } skip--; } if (remain > 0) { SetLastError(ERROR_BAD_PATHNAME); return 0; } if (skip < start) { skip = start; } *++skip = '\0'; } /* one additional byte for trailing '\0', * one additional byte for eventual path * separator between dir and merge */ bl = strlen(dir) + sz + 2; out = malloc(bl); if (out == 0) return 0; /* Prepend dir */ StringCbCopy(out, bl, dir); sz = strlen(out); BS2FSA(out); _INS_TRAILING_PATH_SEP(out, sz); if ((IS_DRIVE_CHAR(rel[0]) && rel[1] == ':')) rel += 2; if (rel[0] == '/') ++rel; if (*rel != '\0') StringCbCopy(out + sz, bl - sz, rel); FS2BSA(out); } return out; } static int is_path_relative(const char *path) { if ((IS_DRIVE_CHAR(path[0]) && path[1] == ':') || path[0] == '/' || path[0] == '\\') return 0; else return 1; } tomcat-connectors-1.2.41-src/native/iis/Makefile.ia640000644000000000000020000001616111726114766020607 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Microsoft Developer Studio Generated NMAKE File, Based on isapi.dsp # Use Platform SDK: # SetEnv.cmd /SRV64 /RETAIL # nmake -f Makefile.ia64 # TARGET=isapi_redirect$(SO_VERSION) CPP=cl.exe MTL=midl.exe RSC=rc.exe OUTDIR=.\Release_ia64 INTDIR=.\Release_ia64 # Begin Custom Macros OutDir=.\Release_ia64 # End Custom Macros ALL : "pcre_ia64" "$(OUTDIR)\$(TARGET).dll" !IF "$(RECURSE)" == "1" CLEAN :"pcre_ia64CLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\jk.res" -@erase "$(INTDIR)\isapi_redirector_src.idb" -@erase "$(INTDIR)\isapi_redirector_src.pdb" -@erase "$(INTDIR)\jk_ajp12_worker.obj" -@erase "$(INTDIR)\jk_ajp13.obj" -@erase "$(INTDIR)\jk_ajp13_worker.obj" -@erase "$(INTDIR)\jk_ajp14.obj" -@erase "$(INTDIR)\jk_ajp14_worker.obj" -@erase "$(INTDIR)\jk_ajp_common.obj" -@erase "$(INTDIR)\jk_connect.obj" -@erase "$(INTDIR)\jk_context.obj" -@erase "$(INTDIR)\jk_isapi_plugin.obj" -@erase "$(INTDIR)\jk_lb_worker.obj" -@erase "$(INTDIR)\jk_map.obj" -@erase "$(INTDIR)\jk_md5.obj" -@erase "$(INTDIR)\jk_msg_buff.obj" -@erase "$(INTDIR)\jk_nwmain.obj" -@erase "$(INTDIR)\jk_pool.obj" -@erase "$(INTDIR)\jk_shm.obj" -@erase "$(INTDIR)\jk_sockbuf.obj" -@erase "$(INTDIR)\jk_status.obj" -@erase "$(INTDIR)\jk_uri_worker_map.obj" -@erase "$(INTDIR)\jk_url.obj" -@erase "$(INTDIR)\jk_util.obj" -@erase "$(INTDIR)\jk_worker.obj" -@erase "$(OUTDIR)\$(TARGET).dll" -@erase "$(OUTDIR)\isapi_redirect.exp" -@erase "$(OUTDIR)\isapi_redirect.lib" -@erase "$(OUTDIR)\$(TARGET).pdb" "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\isapi.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib strsafe.lib bufferoverflowu.lib $(EXTRA_LIBS) /nologo /dll /incremental:no /pdb:"$(OUTDIR)\$(TARGET).pdb" /debug /machine:IA64 /def:".\isapi.def" /out:"$(OUTDIR)\$(TARGET).dll" /implib:"$(OUTDIR)\isapi_redirect.lib" DEF_FILE= \ ".\isapi.def" LINK32_OBJS= \ "$(INTDIR)\jk_ajp12_worker.obj" \ "$(INTDIR)\jk_ajp13.obj" \ "$(INTDIR)\jk_ajp13_worker.obj" \ "$(INTDIR)\jk_ajp14.obj" \ "$(INTDIR)\jk_ajp14_worker.obj" \ "$(INTDIR)\jk_ajp_common.obj" \ "$(INTDIR)\jk_connect.obj" \ "$(INTDIR)\jk_context.obj" \ "$(INTDIR)\jk_isapi_plugin.obj" \ "$(INTDIR)\jk_lb_worker.obj" \ "$(INTDIR)\jk_map.obj" \ "$(INTDIR)\jk_md5.obj" \ "$(INTDIR)\jk_msg_buff.obj" \ "$(INTDIR)\jk_nwmain.obj" \ "$(INTDIR)\jk_pool.obj" \ "$(INTDIR)\jk_shm.obj" \ "$(INTDIR)\jk_sockbuf.obj" \ "$(INTDIR)\jk_status.obj" \ "$(INTDIR)\jk_uri_worker_map.obj" \ "$(INTDIR)\jk_url.obj" \ "$(INTDIR)\jk_util.obj" \ "$(INTDIR)\jk_worker.obj" \ "$(INTDIR)\jk.res" \ ".\pcre\Release_ia64\pcre.lib" "$(OUTDIR)\$(TARGET).dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << IF EXIST $(OUTDIR)\$(TARGET).manifest \ mt -nologo -manifest $(OUTDIR)\$(TARGET).manifest -outputresource:$(OUTDIR)\$(TARGET).dll;2 CPP_PROJ=-nologo -MD -W3 -O2 -Ob2 -Zi -EHsc /I "..\common" /I "pcre" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_IA64_=1" -DWIN64 /D "_WIN64" /D "JK_ISAPI" /D "ISAPI_EXPORTS" /D "HAS_PCRE" /D "PCRE_STATIC" $(CFLAGS) /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\isapi_redirector_src" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 RSC_PROJ=/l 0x409 /fo"$(INTDIR)\jk.res" /i "..\common" /d "JK_ISAPI" /d "NDEBUG" SOURCE=..\common\jk.rc "$(INTDIR)\jk.res" : $(SOURCE) "$(INTDIR)" $(RSC) $(RSC_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp12_worker.c "$(INTDIR)\jk_ajp12_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp13.c "$(INTDIR)\jk_ajp13.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp13_worker.c "$(INTDIR)\jk_ajp13_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp14.c "$(INTDIR)\jk_ajp14.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp14_worker.c "$(INTDIR)\jk_ajp14_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp_common.c "$(INTDIR)\jk_ajp_common.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_connect.c "$(INTDIR)\jk_connect.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_context.c "$(INTDIR)\jk_context.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=.\jk_isapi_plugin.c "$(INTDIR)\jk_isapi_plugin.obj" : $(SOURCE) "$(INTDIR)" SOURCE=..\common\jk_lb_worker.c "$(INTDIR)\jk_lb_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_map.c "$(INTDIR)\jk_map.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_md5.c "$(INTDIR)\jk_md5.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_msg_buff.c "$(INTDIR)\jk_msg_buff.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_nwmain.c "$(INTDIR)\jk_nwmain.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_pool.c "$(INTDIR)\jk_pool.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_shm.c "$(INTDIR)\jk_shm.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_sockbuf.c "$(INTDIR)\jk_sockbuf.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_status.c "$(INTDIR)\jk_status.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_uri_worker_map.c "$(INTDIR)\jk_uri_worker_map.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_url.c "$(INTDIR)\jk_url.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_util.c "$(INTDIR)\jk_util.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_worker.c "$(INTDIR)\jk_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) "pcre_ia64" : cd ".\pcre" $(MAKE) /$(MAKEFLAGS) /F ".\pcre.ia64" cd ".." "pcre_ia64CLEAN" : cd ".\pcre" $(MAKE) /$(MAKEFLAGS) /F ".\pcre.ia64" CLEAN cd ".." tomcat-connectors-1.2.41-src/native/iis/installer/0000755000000000000020000000000012555256552020376 5ustar rootbintomcat-connectors-1.2.41-src/native/iis/installer/tomcat.ico0000644000000000000020000005217610475557345022377 0ustar rootbin (–h¾h& èŽ ¨v ¨ 00hÆ"00¨.)00¨Ö7( À€€€€€€€€€ÀÀÀ€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿðÿÿÿ÷ˆ€ø÷ˆ‡ðˆ€ˆˆxðøx‡xˆÿðwˆwˆw‡ð÷ˆ‡ˆxðÿw‡xxð÷x‡wxðÿÿÿˆˆˆðÿÿÿ‡ÿxðÿÿÿÿÿÿðÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ( @ÿÿÿôôôìììäääÜÜÜÑÒÒÌÌÌÄÉÍÄÆÇ¼¾¿¶¹½«±¶¤¬²¤¤¤˜¥¯’£®†¦¶‰¡¬Ÿ§‚œ§ƒ— “™ž†“š”ŽŽŽqÇçeÌólÇênÁãfÄês¯Çn¼Ýn·Ôyª¾p¨¾q§¼n ³y• u“ n’¦’œq‘ž|—nŒ˜k…’d‡œ]œ¹W°]‘«X‰¥C’¼J޳N®V…OƒŸ<—Å5–Ê*šÐ,—Ì–Ï|}~uz}ft~\mwYYY "$ÿÿÿBBBBBBBBBBBBBBBBBBBBB -BB ,/4BB(=A '2:1BB?7379;8.%BB(38820BB >65!$BB ,!#BB@  !BB&,*&+BB= <BBBBBBBBBBBBBBBBBBBBBÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ( @ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€”«±¶ÿÿÿÿÿÿÿÿÿëëëùùùÿÿÿÿÿÿÿÿÿåå嘥¯d‡œ“¥­³i„”ÿÿÿþþþŽŽŽŽŽŽðððùùùÐÒÓŸ§W°N®ÄÉÍüüüþþþ†“š~‘tz~ "$£«±’£®n’¦D“½,—ÌX‰¥ÄÆÇÿÿÿÿÿÿÿÿÿôôô\mw8—ÇJޱ?–Ã*šÐ–Ï7•È]œ¹y• ìììÿÿÿÿÿÿÿÿÿÞÞÞÚÚÚ’šIŽ´4—Ë4—ËAº]‘«qÇçeËò‚œ§âââþþþÿÿÿÑÑÑýýýþþþ¶¹½ft~OƒŸV…s¯Çp¨¿n ³nÁã“™žþþþÿÿÿÐÐÐîîîÿÿÿõõõÝÝݹ¼¾m†‘lÇëp¨½q§¼n¼Ý‰¡¬þþþÿÿÿðððÌÌÌÐÐÐYYY¤¤¤ÿÿÿ†¦¶dÌón·ÔkÆéfÄêyª¾õõõÿÿÿÿÿÿüüüñññõõõÿÿÿùùùu“ j†’ƒ— |—q‘žnŒ˜õõõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüüvy{¿¿¿þþþýýýÖÖÖ|}~÷÷÷ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ( @€€€€€€€€€€ÀÀÀ€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿðˆÿÿÿÿÿÿÿÿÿÿˆˆ€ˆÿÿÿÿÿÿÿÿÿxˆˆ€ˆÿÿøˆÿÿÿˆ‡xðˆÿÿ€ˆÿÿ÷ˆ‡wÿðøˆÿpÿÿxˆ‡wˆÿð÷ˆˆxˆˆwwx‡ÿÿðÿxˆˆˆˆ‡wwxˆÿÿðÿøˆwˆwwwwˆˆÿÿðÿøˆwˆ‡wwx‡÷‡ÿÿðÿxøˆ‡wwwˆøÿðÿ‡ÿ€ˆ‡ˆˆ‡÷ww‡ðÿÿ÷€ˆ€÷ˆ÷ˆð÷ÿÿ÷€‡ˆwˆˆ‡xÿðÿÿÿÿøˆˆˆwøðÿ‡ÿÿÿÿ÷ˆwˆx‡xðÿxÿÿˆ‡ÿˆwxwˆwðÿ÷ˆxÿ‡xxwwwðÿÿ÷w‡ÿÿ‡÷w‡ÿ÷ðÿÿÿÿÿÿÿ‡ˆwx‡ðÿÿÿÿÿÿÿˆwˆxðÿÿÿÿÿÿÿ€ÿÿÿ€ðÿÿÿÿÿÿÿxÿÿÿÿøðÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿð( @€ÿÿÿôôôëëëäääÚÚÚÕÕÕÌÌ̽½½´´´«««££¤žžž”””‘‘…‹‰ŠŠ…ˆŠ‚…ˆ„†pÆæcÐùiÌóaÏøcÍõiÈìjÅèkÂädÆíZÍù]ÌöUÌøTË÷^Åìk¿âqº×r·Ñp²Ìq¯Èr­Äm¿ßn¹Ön±ËnªÂq¦ºq£·o¥¹n¡µmš«n—¨l’¢{…‹~ƒjŽœjŠ–k‡“e…’h€‹eƒQ‡£J¶B’½K޳GŽ´KŒ­O†£X„›Z–S‚›0šÐ:˜Æ;–Ä3˜Ì6—Ë7–Æ+šÐ'šÐ"—Ð.™Í“Îs|oy€gx‚gwS}”^zŠ]vƒRzUvŠSs…{||qy~sssku{mptgqwjnranxbmtiiiccc]t~[ozXksVlxRhtUdiMbnZ_dLZbYYYQY^PWYUUUHX_FSZMMMCCC>DF<<<59:048+./ÿÿÿ|||||||||||||||||||||||||||||||||||||||||  RBCp||l=D b@G@U ||B= nn ]AKJP||>ad|Z f>HHG]||b<t|q ]X=KKNDo||V>Q u||c SX>HLEENAV|| D=mTWYk>=GNLKHHKGTm||mGMMGTLENHHHHK=g5b|| ^;LKGXGHHHHHK?e#6|| TDGIHHNHNLGh9||  xGG>L=F=•Â<–ÃJµ'šÐ@“¾:˜ÆB“½H¶Qhts«ÂZÌ÷p·Òl¿ßp®ÆcËòjÅèjnrÒÒÒåååÿÿÿÿÿÿÿÿÿÿÿÿðððˆˆˆüüüÿÿÿÿÿÿÿÿÿÚÚÚw}048L‹¬S€˜HX_4—ËO‡£FSZ>DFm³ÍXÌønªÂ]s}mš¬_Ì÷l¹×Udi[[[°°°ÿÿÿÿÿÿÿÿÿÿÿÿããã“““ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¶¶¶Z_dSr„“Î9–ÆRhtt¶Ð`Çïm¡µXksl™«^t~k cËòk¿âgqwìììÿÿÿÿÿÿÿÿÿÿÿÿêêꌌŒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷÷÷­­­px}Z€•N…¤]u€cÏ÷]Íùq¥¹q¥¹hÁão¸Õn—¨aÍõ^Íõk‡“ÜÜÜÿÿÿÿÿÿÿÿÿÿÿÿüüü‰‰‰åååÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿãããzzzeƒ^ÅìlÁãn—¨_w‚l¢¶mš¬^t~o¥¹bÌôn ³žžžÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÒÒÒ‰‰‰ñññÿÿÿÿÿÿëëëVVVXXXºººÿÿÿÿÿÿ———hŠ—fÇîdÌóhÌóq£·kÊðaËóq§¼o¡´fÄêmÄç~ƒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¾¾¾ŠŠŠ¬¬¬µµµtttKKKÛÛÛÿÿÿÿÿÿy|~eÏ÷`Î÷o¥¹o±Êo£·hÎöbÐùcÏ÷p²Ìn¹×cÏ÷s{€þþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõõõÚÚÚÕÕÕÙÙÙšššÁÁÁýýýÿÿÿÿÿÿþþþrzeÏ÷XÌødÐùn°ÉiÈìjŸn¿ÞXÌøUÌøTË÷dÐùjtzüüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþq{€fÎöl“£e…’m©Áq¯Èlžl°Ên™ªl“£gÍômw}üüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ{…‹l‘¡hhhÃÃ󳳩©©­­­¹¹¹{{{hŠ—{…‹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ…ˆŠ49:<<<êêêÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøøøZZZ+./„†ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¶¶¶qqqèèèÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõõõ¨¨¨ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(0`€€€€€€€€€ÀÀÀ€€€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðwwÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿxˆˆ€ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿxˆwx€‡xÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ€ˆwˆˆðˆxÿÿÿÿøÿÿÿÿÿÿ€ˆw€wÿðpxÿÿÿ÷€ÿÿÿÿ÷€ˆwwˆÿÿðø‡ÿÿÿpwÿÿÿÿx€ˆwˆxÿÿðÿˆ€ÿøÿÿÿ÷ˆ‡ww€ÿÿÿðÿðˆÿ€ÿ÷ˆˆwwwˆxÿÿÿðÿ÷ˆˆˆ‡wwwwxÿÿÿÿðÿÿ€wˆˆˆwwwwwwxˆÿÿÿÿðÿÿø‡wwˆwwwwwwx€€ÿÿÿÿðÿÿÿ€wwwˆwwwwww€‡÷ÿÿÿÿðÿÿ÷ˆ‡wwˆwwwwwxÿpÿÿÿðÿÿø€‡ˆˆwwwww€ww÷‡ÿÿÿðÿÿˆÿ÷wwwwwwˆ÷÷xÿÿðÿÿÿÿøx‡x‡ˆˆ÷‡xx‡ÿðÿ÷ÿÿÿ€€‡€‡ˆ€‡x÷x‡ÿðÿøÿÿÿÿ€ˆ‡ˆ‡÷ˆˆ‡x€‡ÿðÿøÿÿÿÿ÷€wxÿpˆˆÿøÿðÿøÿÿÿÿÿÿ€ˆx‡wxw‡ÿxÿðÿ÷ÿÿÿÿÿÿÿˆ‡wx‡w‡w÷ÿðÿÿˆÿÿÿÿÿÿÿÿp‡÷ˆˆˆˆ‡÷ÿðÿÿpÿÿxÿp‡÷ÿxwˆÿðÿÿ÷ÿÿÿÿˆÿx÷‡÷÷ˆˆÿðÿÿÿxˆˆÿÿˆ÷xˆww÷xÿðÿÿÿÿÿÿxÿÿÿ‡÷ÿww‡wÿxÿðÿÿÿÿÿÿÿÿÿÿÿ‡÷‡ø÷wxÿðÿÿÿÿÿÿÿÿÿÿÿ‡p€€xÿðÿÿÿÿÿÿÿÿÿÿÿˆ€÷www€xÿðÿÿÿÿÿÿÿÿÿÿÿxÿÿÿÿøˆÿðÿÿÿÿÿÿÿÿÿÿÿpÿÿÿÿÿÿ€ÿðÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿ÷ÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ(0`€ ÿÿÿöööìììåååÛÛÛÔÔÔÌÌÌÃÃü¼¼³³³­­­£££›››—™™”””ŒŒŒ„„„dÐùkÊðaÏøeÎõjÉîkÆêlÂäeÆì\Íù[Ì÷RË÷l¿áq¼Úp¹Öp·Òq³Ìq¯Èp¬Än¼Ûo¹Öo¶Òo±Êo«ÃA”Àp¦»q¢´n¨¿o¥¼nž±n™«n—¨l“£njŽi‰–gŠ˜g‰–f…’e‚ŽQ‡£I‘¸K¶D‘ºJµM‹«Q‚œ0šÐ;–Ã3˜Ì3—Ê6•Å+šÐ'šÑ"—Ð.™Î*—Í%™Ï!–Ï•Î?’¾d~‰a{†R|’_w‚SyŽSv‹Sq‚{{{tttat}kkkccc]r|[oyQl|WiqPfs_abUemUaeOfrNcn]^aQ]dL^hLZcHWaGX`GWa]^^TXZUUUHX_KU[LQTGT\IOTCMRKKKDJLAFJFFF>EKB<<<38:47:012.23./0*,.'))&')"ÿÿÿ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰Wofdf~‰‰{f[]je@EA<@Ab ‰‰U>Lu‰‰‰ ^pQ;?EGGD:p} ‰‰t;Lyj‰‰‰‰ X}p>;GE?AAG;=Df ‰‰x@@[os‰‰‰‰‰WTcqfS8;GE?AAAAAGGg| ‰‰ rBHp[>OO>rR;@BGED?AAAAAAGE=Rb‰‰ mhSEEEEK[>FGGAAAAAAAAAG@by`…‰‰XBGAAAERREAAAAAAAAAAD@zV y‰‰jUfBDADD8aDAAAAAAAAADLr1t ‰‰j r(G8@@>>IZaRl{Pgu/23ìììÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿúúúÄÄÄ___L^hKŽ´'šÐ'šÐ4™ÎTxŒsss···Qkz•Í'šÐKXaíííÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþþþþþþþþþþþþþþþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóóó°°°OPQNblJµ#™Ï6•ÅSrƒSkzS\a“““öööþþþ___KŽ´–ÏOfrÌÌÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿööö~~~HHHOOO===˜˜˜ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóóó”””./0RjyB“½*šÐ&™Ï9—ÅFNT¶¶¶åååøøøÿÿÿÿÿÿÿÿÿÌÌÌ?GM3˜ÌQ‡£ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿäääVVV½½½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ××׉‰‰EJKSp€E’¼#˜Ñ*šÐ-šÐ4—ËL[d±±±ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ———Peq3˜Í:CHÀÀÀÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ°°°ÌÌÌäääïïïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿââ⢢¢\]^IY`Qƒ=—Ä'™Ò1™ÏJµ>•Â5˜ÌNbl···ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿuuuR‚?’¾CGKÏÏÏÿÿÿÿÿÿÿÿÿüüüŒŒŒ†††ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷÷÷ÑÑÑ™™™_abGSZRzG‘»0šÐ'šÐ/™Ï-˜Ì*šÐK¶GU_27;­­­ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîîîEHIA’¼>“¾9=@———÷÷÷÷÷÷___¿¿¿ÿÿÿþþþöööØØØŸŸŸfff678GT]Q€˜D‘».˜Î'™Ò0šÐ4™Í3˜Ì.™ÍF’¹KŒ­*šÐK]g¤¤¤ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÅÅÅ:AF9•Â;•ÂQm}NSULLLnnnyz{]^aHOTJZaSp€P†¢B“½.™Í'šÐ0šÐ4™Î3˜Ì3˜Ì3˜Ì3˜Ì)™Ï-˜ÌHWa38<—™™ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯¯¯AKQ0–Ê*—ÍERZQoQƒS{’R|‘R™@LRTvŠE‘¸>•Â4—Ë.™Í'šÐ*šÐ0šÐ1™Í3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì.™Í'šÐKŠ«QwNco———ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ©©©HX_GX`Srƒ'šÐ'šÐ'šÐ'šÐ•ÍQoP„ž"—Ð.™Í.™Í4™Î3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì,™Ï9–ÆNco9>CRafÌÌÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿccc-125—È,™Ï5˜Ì3˜Ì3˜Ì'™ÒTvŠTvŠ'™Ò3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì*šÐ;•Â7?Dat}kÈì[Íùp°É8<@¹¹¹ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÏÏÏ___tttJ\f3–É-šÐ4™Î-šÐ*šÐQ‡£Ofr-šÐ3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì-šÐ?’¾AKQn[ÍùaÎùdÐù[Íùl¾àGMO³³³ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿüüü___ÅÅÅÿÿÿŸŸŸCNSA”À/™ÏQ‡£9—Å9—ÅJµ4™Î3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì3˜Ì-šÐ?’¼6<@oš«ZÌ÷aÏødÐùdÐùdÐù[ÍùiÄçKU[½½½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ   qqqÿÿÿÿÿÿÿÿÿ¾¾¾@DH?GMGWa0šÐ.™Í&˜Ñ3˜Ì4—Ë3˜Ì.™Í.™Í4—Ë.™Í'šÐ&™Ï2—ÌIXbr¢²[ÍùcÏ÷gËòaÎùaÎùdÌókÊï]ÍùeÆíWadÞÞÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿùùùKKKÈÈÈÿÿÿÿÿÿÿÿÿÿÿÿèèèbbbAMS9—Å'šÐMŠªSrƒ4—Ë'šÐ=—ÄN‹«-šÐF¹Sw‹R|“J\f49:jÃæ_ÎúfÎöa{†n¨¿lÅè]s}q¯È]ÍùfÌó\pzTTT«««ÖÖÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙÙÙSSSøøøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿøøø———AFKM_iN‰©!–ÏN‹«38DHo©¿XÌøaÏøkÆém”¤ENQccc™™™ÑÑÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¯¯¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿèèè~~~*,/Q‡£Rn~=•À*šÐE‘¸Su‰.23O[bk nÁáaÎùqµÏ^r|o˜©n¨¿[oynž±dÐùkÇîk’¢e012ÖÖÖÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¤¤¤žžžÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÙÙÙ}}}HV`'™Ò*šÐ'šÐF¹=DGgÅè[ÍùaÎùlÃå?EG^t~l“£l“£g…‘:@Bp¦»[Íù_Îú]Íù]s}½½½ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ­­­ŽŽŽÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿççç022L^hNŒ®*šÐQp‚FNQkÊïaÏøaÏøaÏøe…’iÅëaÏødÐù[Íùk’¢l½Ü[Íù_ÎúiÈìg…‘qqqÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖÖÖUUUøøøÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿîîî±±±ikkIOS-12o˜©gËòaÏøkÆéq¼Úf†“mœ®p½ÛoºØp»Ùay„n°Én·ÔlÅè_ÎújÈïTXZõõõÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿZZZ¥¥¥ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýýýùùùüüüÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿååå'))n—¨q¼Ú_Îúp¹Öl“¢f†“P]dn™ªm”¤n™ª]q{Wiqmš¬n¹×aÏøn¨¿389ÒÒÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÜÜÜHHHÌÌÌÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÓÓÓyyyNNN<< ]> 1252 Installation Database ##ID_STRING5## ##COMPANY_NAME## Installer,MSI,Database ##ID_STRING6## Administrator {C3AC9A0C-8E2C-4998-8FD3-894123CF9D37} 06/21/1999 09:00 07/14/2000 12:50 200 0 FLEXnet InstallShield 1 ActionDescriptionTemplate
Advertise##IDS_ACTIONTEXT_Advertising## AllocateRegistrySpace##IDS_ACTIONTEXT_AllocatingRegistry####IDS_ACTIONTEXT_FreeSpace## AppSearch##IDS_ACTIONTEXT_SearchInstalled####IDS_ACTIONTEXT_PropertySignature## BindImage##IDS_ACTIONTEXT_BindingExes####IDS_ACTIONTEXT_File## CCPSearch##IDS_ACTIONTEXT_UnregisterModules## CostFinalize##IDS_ACTIONTEXT_ComputingSpace3## CostInitialize##IDS_ACTIONTEXT_ComputingSpace## CreateFolders##IDS_ACTIONTEXT_CreatingFolders####IDS_ACTIONTEXT_Folder## CreateShortcuts##IDS_ACTIONTEXT_CreatingShortcuts####IDS_ACTIONTEXT_Shortcut## DeleteServices##IDS_ACTIONTEXT_DeletingServices####IDS_ACTIONTEXT_Service## DuplicateFiles##IDS_ACTIONTEXT_CreatingDuplicate####IDS_ACTIONTEXT_FileDirectorySize## FileCost##IDS_ACTIONTEXT_ComputingSpace2## FindRelatedProducts##IDS_ACTIONTEXT_SearchForRelated####IDS_ACTIONTEXT_FoundApp## GenerateScript##IDS_ACTIONTEXT_GeneratingScript####IDS_ACTIONTEXT_1## InstallAdminPackage##IDS_ACTIONTEXT_CopyingNetworkFiles####IDS_ACTIONTEXT_FileDirSize## InstallFiles##IDS_ACTIONTEXT_CopyingNewFiles####IDS_ACTIONTEXT_FileDirSize2## InstallODBC##IDS_ACTIONTEXT_InstallODBC## InstallSFPCatalogFile##IDS_ACTIONTEXT_InstallingSystemCatalog####IDS_ACTIONTEXT_FileDependencies## InstallServices##IDS_ACTIONTEXT_InstallServices####IDS_ACTIONTEXT_Service2## InstallValidate##IDS_ACTIONTEXT_Validating## LaunchConditions##IDS_ACTIONTEXT_EvaluateLaunchConditions## MigrateFeatureStates##IDS_ACTIONTEXT_MigratingFeatureStates####IDS_ACTIONTEXT_Application## MoveFiles##IDS_ACTIONTEXT_MovingFiles####IDS_ACTIONTEXT_FileDirSize3## PatchFiles##IDS_ACTIONTEXT_PatchingFiles####IDS_ACTIONTEXT_FileDirSize4## ProcessComponents##IDS_ACTIONTEXT_UpdateComponentRegistration## PublishComponents##IDS_ACTIONTEXT_PublishingQualifiedComponents####IDS_ACTIONTEXT_ComponentIDQualifier## PublishFeatures##IDS_ACTIONTEXT_PublishProductFeatures####IDS_ACTIONTEXT_FeatureColon## PublishProduct##IDS_ACTIONTEXT_PublishProductInfo## RMCCPSearch##IDS_ACTIONTEXT_SearchingQualifyingProducts## RegisterClassInfo##IDS_ACTIONTEXT_RegisterClassServer####IDS_ACTIONTEXT_ClassId## RegisterComPlus##IDS_ACTIONTEXT_RegisteringComPlus####IDS_ACTIONTEXT_AppIdAppTypeRSN## RegisterExtensionInfo##IDS_ACTIONTEXT_RegisterExtensionServers####IDS_ACTIONTEXT_Extension2## RegisterFonts##IDS_ACTIONTEXT_RegisterFonts####IDS_ACTIONTEXT_Font## RegisterMIMEInfo##IDS_ACTIONTEXT_RegisterMimeInfo####IDS_ACTIONTEXT_ContentTypeExtension## RegisterProduct##IDS_ACTIONTEXT_RegisteringProduct####IDS_ACTIONTEXT_1b## RegisterProgIdInfo##IDS_ACTIONTEXT_RegisteringProgIdentifiers####IDS_ACTIONTEXT_ProgID2## RegisterTypeLibraries##IDS_ACTIONTEXT_RegisterTypeLibs####IDS_ACTIONTEXT_LibId## RegisterUser##IDS_ACTIONTEXT_RegUser####IDS_ACTIONTEXT_1c## RemoveDuplicateFiles##IDS_ACTIONTEXT_RemovingDuplicates####IDS_ACTIONTEXT_FileDir## RemoveEnvironmentStrings##IDS_ACTIONTEXT_UpdateEnvironmentStrings####IDS_ACTIONTEXT_NameValueAction2## RemoveExistingProducts##IDS_ACTIONTEXT_RemoveApps####IDS_ACTIONTEXT_AppCommandLine## RemoveFiles##IDS_ACTIONTEXT_RemovingFiles####IDS_ACTIONTEXT_FileDir2## RemoveFolders##IDS_ACTIONTEXT_RemovingFolders####IDS_ACTIONTEXT_Folder1## RemoveIniValues##IDS_ACTIONTEXT_RemovingIni####IDS_ACTIONTEXT_FileSectionKeyValue## RemoveODBC##IDS_ACTIONTEXT_RemovingODBC## RemoveRegistryValues##IDS_ACTIONTEXT_RemovingRegistry####IDS_ACTIONTEXT_KeyName## RemoveShortcuts##IDS_ACTIONTEXT_RemovingShortcuts####IDS_ACTIONTEXT_Shortcut1## Rollback##IDS_ACTIONTEXT_RollingBack####IDS_ACTIONTEXT_1d## RollbackCleanup##IDS_ACTIONTEXT_RemovingBackup####IDS_ACTIONTEXT_File2## SelfRegModules##IDS_ACTIONTEXT_RegisteringModules####IDS_ACTIONTEXT_FileFolder## SelfUnregModules##IDS_ACTIONTEXT_UnregisterModules####IDS_ACTIONTEXT_FileFolder2## SetODBCFolders##IDS_ACTIONTEXT_InitializeODBCDirs## StartServices##IDS_ACTIONTEXT_StartingServices####IDS_ACTIONTEXT_Service3## StopServices##IDS_ACTIONTEXT_StoppingServices####IDS_ACTIONTEXT_Service4## UnmoveFiles##IDS_ACTIONTEXT_RemovingMoved####IDS_ACTIONTEXT_FileDir3## UnpublishComponents##IDS_ACTIONTEXT_UnpublishQualified####IDS_ACTIONTEXT_ComponentIdQualifier2## UnpublishFeatures##IDS_ACTIONTEXT_UnpublishProductFeatures####IDS_ACTIONTEXT_Feature## UnpublishProduct##IDS_ACTIONTEXT_UnpublishingProductInfo## UnregisterClassInfo##IDS_ACTIONTEXT_UnregisterClassServers####IDS_ACTIONTEXT_ClsID## UnregisterComPlus##IDS_ACTIONTEXT_UnregisteringComPlus####IDS_ACTIONTEXT_AppId## UnregisterExtensionInfo##IDS_ACTIONTEXT_UnregisterExtensionServers####IDS_ACTIONTEXT_Extension## UnregisterFonts##IDS_ACTIONTEXT_UnregisteringFonts####IDS_ACTIONTEXT_Font2## UnregisterMIMEInfo##IDS_ACTIONTEXT_UnregisteringMimeInfo####IDS_ACTIONTEXT_ContentTypeExtension2## UnregisterProgIdInfo##IDS_ACTIONTEXT_UnregisteringProgramIds####IDS_ACTIONTEXT_ProgID## UnregisterTypeLibraries##IDS_ACTIONTEXT_UnregTypeLibs####IDS_ACTIONTEXT_Libid2## WriteEnvironmentStrings##IDS_ACTIONTEXT_EnvironmentStrings####IDS_ACTIONTEXT_NameValueAction## WriteIniValues##IDS_ACTIONTEXT_WritingINI####IDS_ACTIONTEXT_FileSectionKeyValue2## WriteRegistryValues##IDS_ACTIONTEXT_WritingRegistry####IDS_ACTIONTEXT_KeyNameValue## caCreateVRoots##IDS_ACTIONTEXT_CreatingIISRoots## caRemoveVRoots##IDS_ACTIONTEXT_RemovingIISRoots##
ActionConditionSequenceISCommentsISAttributes
CostFinalize1000CostFinalize CostInitialize800CostInitialize FileCost900FileCost InstallAdminPackage3900InstallAdminPackage InstallFiles4000InstallFiles InstallFinalize6600InstallFinalize InstallInitialize1500InstallInitialize InstallValidate1400InstallValidate ScheduleRebootISSCHEDULEREBOOT4010ScheduleReboot
ActionConditionSequenceISCommentsISAttributes
AdminWelcome1010AdminWelcome CostFinalize1000CostFinalize CostInitialize800CostInitialize ExecuteAction1300ExecuteAction FileCost900FileCost SetupCompleteError-3SetupCompleteError SetupCompleteSuccess-1SetupCompleteSuccess SetupInitialization50SetupInitialization SetupInterrupted-2SetupInterrupted SetupProgress1020SetupProgress
ActionConditionSequenceISCommentsISAttributes
CostFinalize1000CostFinalize CostInitialize800CostInitialize CreateShortcuts4500CreateShortcuts InstallFinalize6600InstallFinalize InstallInitialize1500InstallInitialize InstallValidate1400InstallValidate MsiPublishAssemblies6250MsiPublishAssemblies PublishComponents6200PublishComponents PublishFeatures6300PublishFeatures PublishProduct6400PublishProduct RegisterClassInfo4600RegisterClassInfo RegisterExtensionInfo4700RegisterExtensionInfo RegisterMIMEInfo4900RegisterMIMEInfo RegisterProgIdInfo4800RegisterProgIdInfo RegisterTypeLibraries4910RegisterTypeLibraries ScheduleRebootISSCHEDULEREBOOT6410ScheduleReboot
ActionConditionSequenceISCommentsISAttributes
AppIdRemoteServerNameLocalServiceServiceParametersDllSurrogateActivateAtStorageRunAsInteractiveUser
PropertySignature_
IISROOTFOLDER_IISROOTFOLDER IIS_VERSION_IIS_VERSION
Billboard_BBControlTypeXYWidthHeightAttributesText
BillboardFeature_ActionOrdering
NameDataISBuildSourcePath
ISSELFREG.DLL<ISProductFolder>\redist\language independent\i386\isregsvr.dll NewBinary1<ISProductFolder>\Redist\Language Independent\OS Independent\IsDialogBanner.ibd NewBinary10<ISProductFolder>\Redist\Language Independent\OS Independent\CompleteSetupIco.ibd NewBinary11<ISProductFolder>\Redist\Language Independent\OS Independent\CustomSetupIco.ibd NewBinary12<ISProductFolder>\Redist\Language Independent\OS Independent\DestIcon.ibd NewBinary13<ISProductFolder>\Redist\Language Independent\OS Independent\NetworkInstall.ico NewBinary14<ISProductFolder>\Redist\Language Independent\OS Independent\DontInstall.ico NewBinary15<ISProductFolder>\Redist\Language Independent\OS Independent\Install.ico NewBinary16<ISProductFolder>\Redist\Language Independent\OS Independent\InstallFirstUse.ico NewBinary17<ISProductFolder>\Redist\Language Independent\OS Independent\InstallPartial.ico NewBinary18<ISProductFolder>\Redist\Language Independent\OS Independent\InstallStateMenu.ico NewBinary19<ISProjectFolder>\iisfilter.vbs NewBinary2<ISProductFolder>\Redist\Language Independent\OS Independent\New.ibd NewBinary3<ISProductFolder>\Redist\Language Independent\OS Independent\Up.ibd NewBinary4<ISProductFolder>\Redist\Language Independent\OS Independent\WarningIcon.ibd NewBinary5<ISProductFolder>\Redist\Language Independent\OS Independent\IsDialogBitmap.ibd NewBinary6<ISProductFolder>\Redist\Language Independent\OS Independent\CustomSetupIco.ibd NewBinary7<ISProductFolder>\Redist\Language Independent\OS Independent\ReinstIco.ibd NewBinary8<ISProductFolder>\Redist\Language Independent\OS Independent\RemoveIco.ibd NewBinary9<ISProductFolder>\Redist\Language Independent\OS Independent\SetupIcon.ibd SetAllUsers.dll<ISProductFolder>\redist\language independent\i386\SetAllUsers.dll binIISHelper<ISProductFolder>\Support\IISHelper.dll
File_Path
Signature_
PropertyValue
ISCHECKFORPRODUCTUPDATES1 LAUNCHPROGRAM1
CLSIDContextComponent_ProgId_DefaultDescriptionAppId_FileTypeMaskIcon_IconIndexDefInprocHandlerArgumentFeature_Attributes
PropertyOrderValueText
IS_SQLSERVER_SERVER1TestValue
Signature_ComponentIdType
Component_ExpType
ComponentComponentIdDirectory_AttributesConditionKeyPathISAttributesISCommentsISScanAtBuildFileISRegFileToMergeAtBuildISDotNetInstallerArgsInstallISDotNetInstallerArgsCommitISDotNetInstallerArgsUninstallISDotNetInstallerArgsRollback
AllOtherFiles{01621138-5B6F-47D3-B183-8F6107690955}BIN817/LogFile=/LogFile=/LogFile=/LogFile= AllOtherFiles1{918FECBF-6B1D-4648-A0C9-BAE694AB1DF3}CONF817/LogFile=/LogFile=/LogFile=/LogFile= AllOtherFiles10{E461BDCC-5045-469B-96DF-CDB381D7413E}BIN817/LogFile=/LogFile=/LogFile=/LogFile= AllOtherFiles11{BE301E37-3373-4655-B6E0-B39ACCEC85DB}BIN817/LogFile=/LogFile=/LogFile=/LogFile= AllOtherFiles12{CEBD938A-39BA-4ACD-94F4-E87FF5D65383}LOG817/LogFile=/LogFile=/LogFile=/LogFile= AllOtherFiles2{BC4C5E05-7E81-40D6-A477-29D1658190F8}LOG817/LogFile=/LogFile=/LogFile=/LogFile= AllOtherFiles3{66FFA73A-17D7-46D7-911F-3E515C813FFC}INSTALLDIR817/LogFile=/LogFile=/LogFile=/LogFile= AllOtherFiles4{F7546761-05DF-4ED7-9F6D-854F42CE2333}INSTALLDIR8145/LogFile=/LogFile=/LogFile=/LogFile= AllOtherFiles5{56403C1F-20CA-423C-A296-D95AB3E1E7FF}CONF817/LogFile=/LogFile=/LogFile=/LogFile= AllOtherFiles6{2D786CD4-E0CB-47FF-9981-F3F1FC266B1A}INSTALLDIR817/LogFile=/LogFile=/LogFile=/LogFile= AllOtherFiles7{990D5874-56BB-457E-A316-C048C7AF214A}INSTALLDIR817/LogFile=/LogFile=/LogFile=/LogFile= AllOtherFiles8{C8EC2CC3-13A1-4EED-B195-D44739A00048}BIN8145/LogFile=/LogFile=/LogFile=/LogFile= AllOtherFiles9{80382F22-06B4-4290-B60B-908D38ECBA4D}CONF817/LogFile=/LogFile=/LogFile=/LogFile= ISRegistryComponent{60AC5270-5430-4CC4-AF22-BE198804A039}INSTALLDIR817/LogFile=/LogFile=/LogFile=/LogFile= ISRegistryComponent1{695FA56F-E422-429B-AA91-884E5F5DEDCF}INSTALLDIR817/LogFile=/LogFile=/LogFile=/LogFile= VirtualDirComponent{F2BD5AC6-AB0C-4ED5-889E-148870C25009}INSTALLDIR817/LogFile=/LogFile=/LogFile=/LogFile=
Feature_LevelCondition
Dialog_ControlTypeXYWidthHeightAttributesPropertyTextControl_NextHelpISWindowStyleISControlIdISBuildSourcePathBinary_
AdminChangeFolderBannerBitmap003744410NewBinary1 AdminChangeFolderBannerLineLine044374010 AdminChangeFolderBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 AdminChangeFolderBranding2Text3228501365537##IDS_INSTALLSHIELD##0 AdminChangeFolderCancelPushButton30124366173##IDS_CANCEL##ComboText0 AdminChangeFolderComboDirectoryCombo216427780458755TARGETDIR##IDS__IsAdminInstallBrowse_4##Up0 AdminChangeFolderComboTextText215099143##IDS__IsAdminInstallBrowse_LookIn##Combo0 AdminChangeFolderDlgDescText21232922565539##IDS__IsAdminInstallBrowse_BrowseDestination##0 AdminChangeFolderDlgLineLine48234326010 AdminChangeFolderDlgTitleText1362922565539##IDS__IsAdminInstallBrowse_ChangeDestination##0 AdminChangeFolderListDirectoryList2190332977TARGETDIR##IDS__IsAdminInstallBrowse_8##TailText0 AdminChangeFolderNewFolderPushButton3356619193670019List##IDS__IsAdminInstallBrowse_CreateFolder##0NewBinary2 AdminChangeFolderOKPushButton23024366173##IDS_OK##Cancel0 AdminChangeFolderTailPathEdit21207332173TARGETDIR##IDS__IsAdminInstallBrowse_11##OK0 AdminChangeFolderTailTextText2119399133##IDS__IsAdminInstallBrowse_FolderName##Tail0 AdminChangeFolderUpPushButton3106619193670019NewFolder##IDS__IsAdminInstallBrowse_UpOneLevel##0NewBinary3 AdminNetworkLocationBackPushButton16424366173##IDS_BACK##InstallNow0 AdminNetworkLocationBannerBitmap003744410NewBinary1 AdminNetworkLocationBannerLineLine044374010 AdminNetworkLocationBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 AdminNetworkLocationBranding2Text3228501365537##IDS_INSTALLSHIELD##0 AdminNetworkLocationBrowsePushButton28612466173##IDS__IsAdminInstallPoint_Change##Back0 AdminNetworkLocationCancelPushButton30124366173##IDS_CANCEL##SetupPathEdit0 AdminNetworkLocationDlgDescText21232922565539##IDS__IsAdminInstallPoint_SpecifyNetworkLocation##0 AdminNetworkLocationDlgLineLine48234326010 AdminNetworkLocationDlgTextText2151326403##IDS__IsAdminInstallPoint_EnterNetworkLocation##0 AdminNetworkLocationDlgTitleText1362922565539##IDS__IsAdminInstallPoint_NetworkLocationFormatted##0 AdminNetworkLocationInstallNowPushButton23024366173##IDS__IsAdminInstallPoint_Install##Cancel0 AdminNetworkLocationLBBrowseText2190100103##IDS__IsAdminInstallPoint_NetworkLocation##0 AdminNetworkLocationSetupPathEditPathEdit21102330173TARGETDIRBrowse0 AdminWelcomeBackPushButton16424366171##IDS_BACK##Next0 AdminWelcomeCancelPushButton30124366173##IDS_CANCEL##Back0 AdminWelcomeDlgLineLine0234326010 AdminWelcomeImageBitmap0037423410NewBinary5 AdminWelcomeNextPushButton23024366173##IDS_NEXT##Cancel0 AdminWelcomeTextLine1Text13582254565539##IDS__IsAdminInstallPointWelcome_Wizard##0 AdminWelcomeTextLine2Text135552284565539##IDS__IsAdminInstallPointWelcome_ServerImage##0 CancelSetupIconIcon1515242452428810NewBinary4 CancelSetupNoPushButton1355766173##IDS__IsCancelDlg_No##Yes0 CancelSetupTextText4815194303##IDS__IsCancelDlg_ConfirmCancel##0 CancelSetupYesPushButton625766173##IDS__IsCancelDlg_Yes##No0 CustomSetupBackPushButton16424366173##IDS_BACK##Next0 CustomSetupBannerBitmap003744410NewBinary1 CustomSetupBannerLineLine044374010 CustomSetupBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 CustomSetupBranding2Text3228501365537##IDS_INSTALLSHIELD##0 CustomSetupCancelPushButton30124366173##IDS_CANCEL##Tree0 CustomSetupChangeFolderPushButton30120366173##IDS__IsCustomSelectionDlg_Change##Help0 CustomSetupDetailsPushButton9324366173##IDS__IsCustomSelectionDlg_Space##Back0 CustomSetupDlgDescText17232922565539##IDS__IsCustomSelectionDlg_SelectFeatures##0 CustomSetupDlgLineLine48234326010 CustomSetupDlgTextText951360103##IDS__IsCustomSelectionDlg_ClickFeatureIcon##0 CustomSetupDlgTitleText962922565539##IDS__IsCustomSelectionDlg_CustomSetup##0 CustomSetupFeatureGroupGroupBox235671311201##IDS__IsCustomSelectionDlg_FeatureDescription##0 CustomSetupHelpPushButton2224366173##IDS__IsCustomSelectionDlg_Help##Details0 CustomSetupInstallLabelText8190360103##IDS__IsCustomSelectionDlg_InstallTo##0 CustomSetupItemDescriptionText24180120503##IDS__IsCustomSelectionDlg_MultilineDescription##0 CustomSetupLocationText8203291203##IDS__IsCustomSelectionDlg_FeaturePath##0 CustomSetupNextPushButton23024366173##IDS_NEXT##Cancel0 CustomSetupSizeText241133120503##IDS__IsCustomSelectionDlg_FeatureSize##0 CustomSetupTreeSelectionTree8702201187_BrowsePropertyChangeFolder0 CustomSetupTipsBannerBitmap003744410NewBinary1 CustomSetupTipsBannerLineLine044374010 CustomSetupTipsBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 CustomSetupTipsBranding2Text3228501365537##IDS_INSTALLSHIELD##0 CustomSetupTipsDlgDescText21232922565539##IDS_SetupTips_CustomSetupDescription##0 CustomSetupTipsDlgLineLine48234326010 CustomSetupTipsDlgTitleText1362922565539##IDS_SetupTips_CustomSetup##0 CustomSetupTipsDontInstallIcon21155242452428810NewBinary14 CustomSetupTipsDontInstallTextText60155300203##IDS_SetupTips_WillNotBeInstalled##0 CustomSetupTipsFirstInstallTextText60180300203##IDS_SetupTips_Advertise##0 CustomSetupTipsInstallIcon21105242452428810NewBinary15 CustomSetupTipsInstallFirstUseIcon21180242452428810NewBinary16 CustomSetupTipsInstallPartialIcon21130242452428810NewBinary17 CustomSetupTipsInstallStateMenuIcon2152242452428810NewBinary18 CustomSetupTipsInstallStateTextText2191300103##IDS_SetupTips_InstallState##0 CustomSetupTipsInstallTextText60105300203##IDS_SetupTips_AllInstalledLocal##0 CustomSetupTipsMenuTextText5052300363##IDS_SetupTips_IconInstallState##0 CustomSetupTipsNetworkInstallIcon21205242452428810NewBinary13 CustomSetupTipsNetworkInstallTextText60205300203##IDS_SetupTips_Network##0 CustomSetupTipsOKPushButton30124366173##IDS_SetupTips_OK##0 CustomSetupTipsPartialTextText60130300203##IDS_SetupTips_SubFeaturesInstalledLocal##0 CustomerInformationBackPushButton16424366173##IDS_BACK##Next0 CustomerInformationBannerBitmap003744410NewBinary1 CustomerInformationBannerLineLine044374010 CustomerInformationBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 CustomerInformationBranding2Text3228501365537##IDS_INSTALLSHIELD##0 CustomerInformationCancelPushButton30124366173##IDS_CANCEL##NameLabel0 CustomerInformationCompanyEditEdit21100237173COMPANYNAME##IDS__IsRegisterUserDlg_Tahoma80##SerialLabel0 CustomerInformationCompanyLabelText218975103##IDS__IsRegisterUserDlg_Organization##CompanyEdit0 CustomerInformationDlgDescText21232922565539##IDS__IsRegisterUserDlg_PleaseEnterInfo##0 CustomerInformationDlgLineLine48234326010 CustomerInformationDlgRadioGroupTextText21161300143##IDS__IsRegisterUserDlg_InstallFor##0 CustomerInformationDlgTitleText1362922565539##IDS__IsRegisterUserDlg_CustomerInformation##0 CustomerInformationNameEditEdit2163237173USERNAME##IDS__IsRegisterUserDlg_Tahoma50##CompanyLabel0 CustomerInformationNameLabelText215275103##IDS__IsRegisterUserDlg_UserName##NameEdit0 CustomerInformationNextPushButton23024366173##IDS_NEXT##Cancel0 CustomerInformationRadioGroupRadioButtonGroup63170300503ApplicationUsers##IDS__IsRegisterUserDlg_16##Back0 CustomerInformationSerialLabelText21127109102##IDS__IsRegisterUserDlg_SerialNumber##SerialNumber0 CustomerInformationSerialNumberMaskedEdit21138237172ISX_SERIALNUMRadioGroup0 DatabaseFolderBackPushButton16424366173##IDS_BACK##Next0 DatabaseFolderBannerBitmap003744410NewBinary1 DatabaseFolderBannerLineLine044374010 DatabaseFolderBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 DatabaseFolderBranding2Text3228501365537##IDS_INSTALLSHIELD##0 DatabaseFolderCancelPushButton30124366173##IDS_CANCEL##ChangeFolder0 DatabaseFolderChangeFolderPushButton3016566173##IDS_CHANGE##Back0 DatabaseFolderDatabaseFolderIcon2152242452428810NewBinary12 DatabaseFolderDlgDescText21232922565539##IDS__DatabaseFolder_ChangeFolder##0 DatabaseFolderDlgLineLine48234326010 DatabaseFolderDlgTitleText1362922565539##IDS__DatabaseFolder_DatabaseFolder##0 DatabaseFolderLocLabelText5752290103##IDS_DatabaseFolder_InstallDatabaseTo##0 DatabaseFolderLocationText5765240403_BrowseProperty##IDS__DatabaseFolder_DatabaseDir##0 DatabaseFolderNextPushButton23024366173##IDS_NEXT##Cancel0 DestinationFolderBackPushButton16424366173##IDS_BACK##Next0 DestinationFolderBannerBitmap003744410NewBinary1 DestinationFolderBannerLineLine044374010 DestinationFolderBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 DestinationFolderBranding2Text3228501365537##IDS_INSTALLSHIELD##0 DestinationFolderCancelPushButton30124366173##IDS_CANCEL##ChangeFolder0 DestinationFolderChangeFolderPushButton3016566173##IDS__DestinationFolder_Change##Back0 DestinationFolderDestFolderIcon2152242452428810NewBinary12 DestinationFolderDlgDescText21232922565539##IDS__DestinationFolder_ChangeFolder##0 DestinationFolderDlgLineLine48234326010 DestinationFolderDlgTitleText1362922565539##IDS__DestinationFolder_DestinationFolder##0 DestinationFolderLocLabelText5752290103##IDS__DestinationFolder_InstallTo##0 DestinationFolderLocationText5765240403_BrowseProperty##IDS_INSTALLDIR##0 DestinationFolderNextPushButton23024366173##IDS_NEXT##Cancel0 DiskSpaceRequirementsBannerBitmap003744410NewBinary1 DiskSpaceRequirementsBannerLineLine044374010 DiskSpaceRequirementsBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 DiskSpaceRequirementsBranding2Text3228501365537##IDS_INSTALLSHIELD##0 DiskSpaceRequirementsDlgDescText17232922565539##IDS__IsFeatureDetailsDlg_SpaceRequired##0 DiskSpaceRequirementsDlgLineLine48234326010 DiskSpaceRequirementsDlgTextText10185358413##IDS__IsFeatureDetailsDlg_VolumesTooSmall##0 DiskSpaceRequirementsDlgTitleText962922565539##IDS__IsFeatureDetailsDlg_DiskSpaceRequirements##0 DiskSpaceRequirementsListVolumeCostList855358125393223##IDS__IsFeatureDetailsDlg_Numbers##0 DiskSpaceRequirementsOKPushButton30124366173##IDS__IsFeatureDetailsDlg_OK##0 FilesInUseBannerBitmap003744410NewBinary1 FilesInUseBannerLineLine044374010 FilesInUseBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 FilesInUseBranding2Text3228501365537##IDS_INSTALLSHIELD##0 FilesInUseDlgDescText21232922565539##IDS__IsFilesInUse_FilesInUseMessage##0 FilesInUseDlgLineLine48234326010 FilesInUseDlgTextText2151348293##IDS__IsFilesInUse_ApplicationsUsingFiles##0 FilesInUseDlgTitleText1362922565539##IDS__IsFilesInUse_FilesInUse##0 FilesInUseExitPushButton30124366173##IDS__IsFilesInUse_Exit##List0 FilesInUseIgnorePushButton23024366173##IDS__IsFilesInUse_Ignore##Exit0 FilesInUseListListBox21873311357FileInUseProcessRetry0 FilesInUseRetryPushButton16424366173##IDS__IsFilesInUse_Retry##Ignore0 InstallChangeFolderBannerBitmap003744410NewBinary1 InstallChangeFolderBannerLineLine044374010 InstallChangeFolderBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 InstallChangeFolderBranding2Text3228501365537##IDS_INSTALLSHIELD##0 InstallChangeFolderCancelPushButton30124366173##IDS_CANCEL##ComboText0 InstallChangeFolderComboDirectoryCombo2164277804128779_BrowseProperty##IDS__IsBrowseFolderDlg_4##Up0 InstallChangeFolderComboTextText215099143##IDS__IsBrowseFolderDlg_LookIn##Combo0 InstallChangeFolderDlgDescText21232922565539##IDS__IsBrowseFolderDlg_BrowseDestFolder##0 InstallChangeFolderDlgLineLine48234326010 InstallChangeFolderDlgTitleText1362922565539##IDS__IsBrowseFolderDlg_ChangeCurrentFolder##0 InstallChangeFolderListDirectoryList21903329715_BrowseProperty##IDS__IsBrowseFolderDlg_8##TailText0 InstallChangeFolderNewFolderPushButton3356619193670019List##IDS__IsBrowseFolderDlg_CreateFolder##0NewBinary2 InstallChangeFolderOKPushButton23024366173##IDS__IsBrowseFolderDlg_OK##Cancel0 InstallChangeFolderTailPathEdit212073321715_BrowseProperty##IDS__IsBrowseFolderDlg_11##OK0 InstallChangeFolderTailTextText2119399133##IDS__IsBrowseFolderDlg_FolderName##Tail0 InstallChangeFolderUpPushButton3106619193670019NewFolder##IDS__IsBrowseFolderDlg_UpOneLevel##0NewBinary3 InstallWelcomeBackPushButton16424366171##IDS_BACK##Copyright0 InstallWelcomeCancelPushButton30124366173##IDS_CANCEL##Back0 InstallWelcomeCopyrightText1351442287365539##IDS__IsWelcomeDlg_WarningCopyright##Next0 InstallWelcomeDlgLineLine0234374010 InstallWelcomeImageBitmap0037423410NewBinary5 InstallWelcomeNextPushButton23024366173##IDS_NEXT##Cancel0 InstallWelcomeTextLine1Text13582254565539##IDS__IsWelcomeDlg_WelcomeProductName##0 InstallWelcomeTextLine2Text135552284565539##IDS__IsWelcomeDlg_InstallProductName##0 LicenseAgreementAgreeRadioButtonGroup8190291403AgreeToLicenseBack0 LicenseAgreementBackPushButton16424366173##IDS_BACK##Next0 LicenseAgreementBannerBitmap003744410NewBinary1 LicenseAgreementBannerLineLine044374010 LicenseAgreementBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 LicenseAgreementBranding2Text3228501365537##IDS_INSTALLSHIELD##0 LicenseAgreementCancelPushButton30124366173##IDS_CANCEL##ISPrintButton0 LicenseAgreementDlgDescText21232922565539##IDS__IsLicenseDlg_ReadLicenseAgreement##0 LicenseAgreementDlgLineLine48234326010 LicenseAgreementDlgTitleText1362922565539##IDS__IsLicenseDlg_LicenseAgreement##0 LicenseAgreementISPrintButtonPushButton30118865173##IDS_PRINT_BUTTON##Agree0 LicenseAgreementMemoScrollableText85535813070<ISProjectFolder>\License.rtf LicenseAgreementNextPushButton23024366173##IDS_NEXT##Cancel0 MaintenanceTypeBackPushButton16424366173##IDS_BACK##Next0 MaintenanceTypeBannerBitmap003744410NewBinary1 MaintenanceTypeBannerLineLine044374010 MaintenanceTypeBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 MaintenanceTypeBranding2Text3228501365537##IDS_INSTALLSHIELD##0 MaintenanceTypeCancelPushButton30124366173##IDS_CANCEL##RadioGroup0 MaintenanceTypeDlgDescText21232922565539##IDS__IsMaintenanceDlg_MaitenanceOptions##0 MaintenanceTypeDlgLineLine48234326010 MaintenanceTypeDlgTitleText1362922565539##IDS__IsMaintenanceDlg_ProgramMaintenance##0 MaintenanceTypeIco1Icon3575242452428810NewBinary6 MaintenanceTypeIco2Icon35135242452428810NewBinary7 MaintenanceTypeIco3Icon35195242452428810NewBinary8 MaintenanceTypeNextPushButton23024366173##IDS_NEXT##Cancel0 MaintenanceTypeRadioGroupRadioButtonGroup21552901703_IsMaintenance##IDS__IsMaintenanceDlg_11##Back0 MaintenanceTypeText1Text8072260353##IDS__IsMaintenanceDlg_ChangeFeatures##0 MaintenanceTypeText2Text80135260353##IDS__IsMaintenanceDlg_RepairMessage##0 MaintenanceTypeText3Text80192260353##IDS__IsMaintenanceDlg_RemoveProductName##0 MaintenanceWelcomeBackPushButton16424366171##IDS_BACK##Next0 MaintenanceWelcomeCancelPushButton30124366173##IDS_CANCEL##Back0 MaintenanceWelcomeDlgLineLine0234374010 MaintenanceWelcomeImageBitmap0037423410NewBinary5 MaintenanceWelcomeNextPushButton23024366173##IDS_NEXT##Cancel0 MaintenanceWelcomeTextLine1Text13582254565539##IDS__IsMaintenanceWelcome_WizardWelcome##0 MaintenanceWelcomeTextLine2Text135552285065539##IDS__IsMaintenanceWelcome_MaintenanceOptionsDescription##0 OutOfSpaceBannerBitmap003744410NewBinary1 OutOfSpaceBannerLineLine044374010 OutOfSpaceBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 OutOfSpaceBranding2Text3228501365537##IDS_INSTALLSHIELD##0 OutOfSpaceDlgDescText21232922565539##IDS__IsDiskSpaceDlg_DiskSpace##0 OutOfSpaceDlgLineLine48234326010 OutOfSpaceDlgTextText2151326433##IDS__IsDiskSpaceDlg_HighlightedVolumes##0 OutOfSpaceDlgTitleText1362922565539##IDS__IsDiskSpaceDlg_OutOfDiskSpace##0 OutOfSpaceListVolumeCostList2195332120393223##IDS__IsDiskSpaceDlg_Numbers##0 OutOfSpaceResumePushButton30124366173##IDS__IsDiskSpaceDlg_OK##0 PatchWelcomeBackPushButton16424366171##IDS_BACK##Next0 PatchWelcomeCancelPushButton30124366173##IDS_CANCEL##Back0 PatchWelcomeDlgLineLine0234374010 PatchWelcomeImageBitmap0037423410NewBinary5 PatchWelcomeNextPushButton23024366173##IDS__IsPatchDlg_Update##Cancel0 PatchWelcomeTextLine1Text13582254565539##IDS__IsPatchDlg_WelcomePatchWizard##0 PatchWelcomeTextLine2Text135542284565539##IDS__IsPatchDlg_PatchClickUpdate##0 ReadyToInstallBackPushButton16424366173##IDS_BACK##InstallNow0 ReadyToInstallBannerBitmap003744410NewBinary1 ReadyToInstallBannerLineLine044374010 ReadyToInstallBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 ReadyToInstallBranding2Text3228501365537##IDS_INSTALLSHIELD##0 ReadyToInstallCancelPushButton30124366173##IDS_CANCEL##Back0 ReadyToInstallDlgDescText21232922565539##IDS__IsVerifyReadyDlg_WizardReady##0 ReadyToInstallDlgLineLine48234374010 ReadyToInstallDlgTextText2151326203##IDS__IsVerifyReadyDlg_ClickInstall##0 ReadyToInstallDlgText1Text2170330243##IDS__IsVerifyReadyDlg_BackOrCancel##0 ReadyToInstallDlgTitleText1362922565538##IDS__IsVerifyReadyDlg_ModifyReady##0 ReadyToInstallDlgTitle2Text1362922565538##IDS__IsVerifyReadyDlg_ReadyRepair##0 ReadyToInstallDlgTitle3Text1362922565538##IDS__IsVerifyReadyDlg_ReadyInstall##0 ReadyToInstallInstallNowPushButton23024366173##IDS__IsVerifyReadyDlg_Install##Cancel0 ReadyToRemoveBackPushButton16424366173##IDS_BACK##RemoveNow0 ReadyToRemoveBannerBitmap003744410NewBinary1 ReadyToRemoveBannerLineLine044374010 ReadyToRemoveBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 ReadyToRemoveBranding2Text3228501365537##IDS_INSTALLSHIELD##0 ReadyToRemoveCancelPushButton30124366173##IDS_CANCEL##Back0 ReadyToRemoveDlgDescText21232922565539##IDS__IsVerifyRemoveAllDlg_ChoseRemoveProgram##0 ReadyToRemoveDlgLineLine48234326010 ReadyToRemoveDlgTextText2151326243##IDS__IsVerifyRemoveAllDlg_ClickRemove##0 ReadyToRemoveDlgText1Text2179330233##IDS__IsVerifyRemoveAllDlg_ClickBack##0 ReadyToRemoveDlgText2Text211023302430 ReadyToRemoveDlgTitleText1362922565539##IDS__IsVerifyRemoveAllDlg_RemoveProgram##0 ReadyToRemoveRemoveNowPushButton23024366173##IDS__IsVerifyRemoveAllDlg_Remove##Cancel0 SQLBrowseBranding1Text422750133##IDS_INSTALLSHIELD_FORMATTED##00 SQLBrowseBranding2Text3226501365537##IDS_INSTALLSHIELD##00 SQLBrowseCancelPushButton19424166173##IDS_CANCEL##TxtSQLBrowse0 SQLBrowseDlgLineLine482322240100 SQLBrowseOKPushButton12524166173##IDS_OK##lstSQLServer0 SQLBrowseTxtSQLBrowseText1382453165539##IDS_SQLBROWSE_INTRO##OK0 SQLBrowselstSQLServerListBox14452451657IS_SQLSERVER_LISTCancel0 SQLLoginBackPushButton16424366173##IDS_BACK##Next0 SQLLoginBannerBitmap003744410NewBinary1 SQLLoginBannerLineLine044374010 SQLLoginBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 SQLLoginBranding2Text3228501365537##IDS_INSTALLSHIELD##0 SQLLoginBtnSQLBrowsePushButton30110666173##IDS_SQLLOGIN_BROWSE##lblAuthentication0 SQLLoginCancelPushButton30124366173##IDS_CANCEL##lblServer0 SQLLoginDlgDescText21232922565539##IDS_SQLLOGIN_DESC##0 SQLLoginDlgLineLine48234326010 SQLLoginDlgTitleText1372922565539##IDS_SQLLOGIN_TITLE##0 SQLLoginEdtLoginEdit92184218163IS_SQLSERVER_USERNAMElblPswd0 SQLLoginEdtPswdEdit92208218162097155IS_SQLSERVER_PASSWORDBack0 SQLLoginNextPushButton22924366173##IDS_NEXT##Cancel0 SQLLoginRadioButtonGroup1RadioButtonGroup25145343343IS_SQLSERVER_AUTHENTICATIONlblLoginID0 SQLLogincboServersComboBox181062788065539IS_SQLSERVER_SERVERBtnSQLBrowse0 SQLLoginlblAuthenticationText1812933414131075##IDS_SQLLOGIN_CONNECT##RadioButtonGroup10 SQLLoginlblLoginIDText4318648133##IDS_SQLLOGIN_ID##EdtLogin0 SQLLoginlblPswdText4320847133##IDS_SQLLOGIN_PSWD##EdtPswd0 SQLLoginlblSQLLoginIntroText17503454065539##IDS_SQLLOGIN_INTRO##cboServers0 SQLLoginlblServerText189288143##IDS_SQLLOGIN_SERVER##lblSQLLoginIntro0 SetupCompleteErrorBackPushButton16424366171##IDS_BACK##Finish0 SetupCompleteErrorCancelPushButton30124366171##IDS_CANCEL##Back0 SetupCompleteErrorDlgLineLine0234374010 SetupCompleteErrorFinishPushButton23024366173##IDS__IsFatalError_Finish##Cancel0 SetupCompleteErrorFinishText1Text135802285065539##IDS__IsFatalError_NotModified##0 SetupCompleteErrorFinishText2Text1351352282565539##IDS__IsFatalError_ClickFinish##0 SetupCompleteErrorImageBitmap0037423410NewBinary5 SetupCompleteErrorRestContText1Text135802285065539##IDS__IsFatalError_KeepOrRestore##0 SetupCompleteErrorRestContText2Text1351352282565539##IDS__IsFatalError_RestoreOrContinueLater##0 SetupCompleteErrorTextLine1Text13582254565539##IDS__IsFatalError_WizardCompleted##0 SetupCompleteErrorTextLine2Text135552282565539##IDS__IsFatalError_WizardInterrupted##0 SetupCompleteSuccessBackPushButton16424366171##IDS_BACK##OK0 SetupCompleteSuccessCancelPushButton30124366171##IDS_CANCEL##Image0 SetupCompleteSuccessCheckBoxUpdatesCheckBox1351641092ISCHECKFORPRODUCTUPDATESCheckBox1Back0 SetupCompleteSuccessCheckForUpdatesTextText1521621903065538##IDS__IsExitDialog_Update_YesCheckForUpdates##0 SetupCompleteSuccessCheckLaunchProgramCheckBox1511141092LAUNCHPROGRAM0 SetupCompleteSuccessCheckLaunchReadmeCheckBox1511481092LAUNCHREADME0 SetupCompleteSuccessDlgLineLine0234374010 SetupCompleteSuccessImageBitmap003742341CheckBoxUpdates0NewBinary5 SetupCompleteSuccessLaunchProgramTextText1641121981565538Launch [ProductName]0 SetupCompleteSuccessLaunchReadmeTextText1641481981365538##IDS__IsExitDialog_ShowReadMe##0 SetupCompleteSuccessOKPushButton23024366173##IDS__IsExitDialog_Finish##Cancel0 SetupCompleteSuccessTextLine1Text13582254565539##IDS__IsExitDialog_WizardCompleted##0 SetupCompleteSuccessTextLine2Text135552284565538##IDS__IsExitDialog_InstallSuccess##0 SetupCompleteSuccessTextLine3Text135552284565538##IDS__IsExitDialog_UninstallSuccess##0 SetupCompleteSuccessUpdateTextLine1Text135302284565538##IDS__IsExitDialog_Update_SetupFinished##0 SetupCompleteSuccessUpdateTextLine2Text135802284565538##IDS__IsExitDialog_Update_PossibleUpdates##0 SetupCompleteSuccessUpdateTextLine3Text1351202284565538##IDS__IsExitDialog_Update_InternetConnection##0 SetupErrorAPushButton1928066173##IDS__IsErrorDlg_Abort##0 SetupErrorCPushButton1928066173##IDS_CANCEL2##0 SetupErrorErrorIconIcon1515242452428810NewBinary4 SetupErrorErrorTextText5015200503##IDS__IsErrorDlg_ErrorText##0 SetupErrorIPushButton1928066173##IDS__IsErrorDlg_Ignore##0 SetupErrorNPushButton1928066173##IDS__IsErrorDlg_NO##0 SetupErrorOPushButton1928066173##IDS__IsErrorDlg_OK##0 SetupErrorRPushButton1928066173##IDS__IsErrorDlg_Retry##0 SetupErrorYPushButton1928066173##IDS__IsErrorDlg_Yes##0 SetupInitializationActionDataText1351252281265539##IDS__IsInitDlg_1##0 SetupInitializationActionTextText1351092203665539##IDS__IsInitDlg_2##0 SetupInitializationBackPushButton16424366171##IDS_BACK##0 SetupInitializationCancelPushButton30124366173##IDS_CANCEL##0 SetupInitializationDlgLineLine0234374010 SetupInitializationImageBitmap0037423410NewBinary5 SetupInitializationNextPushButton23024366171##IDS_NEXT##0 SetupInitializationTextLine1Text13582254565539##IDS__IsInitDlg_WelcomeWizard##0 SetupInitializationTextLine2Text135552283065539##IDS__IsInitDlg_PreparingWizard##0 SetupInterruptedBackPushButton16424366171##IDS_BACK##0 SetupInterruptedCancelPushButton30124366171##IDS_CANCEL##0 SetupInterruptedDlgLineLine0234374010 SetupInterruptedFinishPushButton23024366173##IDS__IsUserExit_Finish##0 SetupInterruptedFinishText1Text135802285065539##IDS__IsUserExit_NotModified##0 SetupInterruptedFinishText2Text1351352282565539##IDS__IsUserExit_ClickFinish##0 SetupInterruptedImageBitmap0037423410NewBinary5 SetupInterruptedRestContText1Text135802285065539##IDS__IsUserExit_KeepOrRestore##0 SetupInterruptedRestContText2Text1351352282565539##IDS__IsUserExit_RestoreOrContinue##0 SetupInterruptedTextLine1Text13582254565539##IDS__IsUserExit_WizardCompleted##0 SetupInterruptedTextLine2Text135552282565539##IDS__IsUserExit_WizardInterrupted##0 SetupProgressActionProgress95ProgressBar591132751265537##IDS__IsProgressDlg_ProgressDone##0 SetupProgressActionTextText59100275123##IDS__IsProgressDlg_2##0 SetupProgressBackPushButton16424366171##IDS_BACK##Next0 SetupProgressBannerBitmap003744410NewBinary1 SetupProgressBannerLineLine044374010 SetupProgressBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 SetupProgressBranding2Text3228501365537##IDS_INSTALLSHIELD##0 SetupProgressCancelPushButton30124366173##IDS_CANCEL##Back0 SetupProgressDlgDescText21232922565538##IDS__IsProgressDlg_UninstallingFeatures2##0 SetupProgressDlgDesc2Text21232922565538##IDS__IsProgressDlg_UninstallingFeatures##0 SetupProgressDlgLineLine48234326010 SetupProgressDlgTextText59512753065538##IDS__IsProgressDlg_WaitUninstall2##0 SetupProgressDlgText2Text59512753065538##IDS__IsProgressDlg_WaitUninstall##0 SetupProgressDlgTitleText1362922565538##IDS__IsProgressDlg_InstallingProductName##0 SetupProgressDlgTitle2Text1362922565538##IDS__IsProgressDlg_Uninstalling##0 SetupProgressLbSecText17213932122##IDS__IsProgressDlg_SecHidden##0 SetupProgressLbStatusText598570123##IDS__IsProgressDlg_Status##0 SetupProgressNextPushButton23024366171##IDS_NEXT##Cancel0 SetupProgressSetupIconIcon2151242452428810NewBinary9 SetupProgressShowTimeText15513917122##IDS__IsProgressDlg_Hidden##0 SetupProgressTextTimeText5913996122##IDS__IsProgressDlg_HiddenTimeRemaining##0 SetupResumeBackPushButton16424366171##IDS_BACK##Next0 SetupResumeCancelPushButton30124366173##IDS_CANCEL##Back0 SetupResumeDlgLineLine0234374010 SetupResumeImageBitmap0037423410NewBinary5 SetupResumeNextPushButton23024366173##IDS_NEXT##Cancel0 SetupResumePreselectedTextText135552284565539##IDS__IsResumeDlg_WizardResume##0 SetupResumeResumeTextText135462284565539##IDS__IsResumeDlg_ResumeSuspended##0 SetupResumeTextLine1Text13582254565539##IDS__IsResumeDlg_Resuming##0 SetupTypeBackPushButton16424366173##IDS_BACK##Next0 SetupTypeBannerBitmap003744410NewBinary1 SetupTypeBannerLineLine044374010 SetupTypeBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 SetupTypeBranding2Text3228501365537##IDS_INSTALLSHIELD##0 SetupTypeCancelPushButton30124366173##IDS_CANCEL##RadioGroup0 SetupTypeCompTextText8094246353##IDS__IsSetupTypeMinDlg_AllFeatures##0 SetupTypeCompleteIcoIcon3494242452428810NewBinary10 SetupTypeCustTextText80154246353##IDS__IsSetupTypeMinDlg_ChooseFeatures##0 SetupTypeCustomIcoIcon34154242452428810NewBinary6 SetupTypeDlgDescText21232922565539##IDS__IsSetupTypeMinDlg_ChooseSetupType##0 SetupTypeDlgLineLine48234326010 SetupTypeDlgTextText2151326103##IDS__IsSetupTypeMinDlg_SelectSetupType##0 SetupTypeDlgTitleText1362922565539##IDS__IsSetupTypeMinDlg_SetupType##0 SetupTypeNextPushButton23024366173##IDS_NEXT##Cancel0 SetupTypeRadioGroupRadioButtonGroup21792641203_IsSetupTypeMin##IDS__IsSetupTypeMinDlg_13##Back0 SplashBitmapBackPushButton16424366171##IDS_BACK##Next0 SplashBitmapBranding1Text422950133##IDS_INSTALLSHIELD_FORMATTED##0 SplashBitmapBranding2Text3228501365537##IDS_INSTALLSHIELD##0 SplashBitmapCancelPushButton30124366173##IDS_CANCEL##Back0 SplashBitmapDlgLineLine48234374010 SplashBitmapImageBitmap131234921110NewBinary5 SplashBitmapNextPushButton23024366173##IDS_NEXT##Cancel0
Dialog_Control_ActionCondition
CustomSetupChangeFolderHideInstalled CustomSetupDetailsHideInstalled CustomSetupInstallLabelHideInstalled CustomerInformationDlgRadioGroupTextHideNOT Privileged CustomerInformationDlgRadioGroupTextHideProductState > 0 CustomerInformationDlgRadioGroupTextHideVersion9X CustomerInformationRadioGroupHideNOT Privileged CustomerInformationRadioGroupHideProductState > 0 CustomerInformationRadioGroupHideVersion9X CustomerInformationSerialLabelShowSERIALNUMSHOW CustomerInformationSerialNumberShowSERIALNUMSHOW InstallWelcomeCopyrightHideSHOWCOPYRIGHT="No" InstallWelcomeCopyrightShowSHOWCOPYRIGHT="Yes" LicenseAgreementNextDisableAgreeToLicense <> "Yes" LicenseAgreementNextEnableAgreeToLicense = "Yes" ReadyToInstallDlgTitleShowProgressType0="Modify" ReadyToInstallDlgTitle2ShowProgressType0="Repair" ReadyToInstallDlgTitle3ShowProgressType0="install" SQLLoginEdtLoginDisableIS_SQLSERVER_AUTHENTICATION=0 SQLLoginEdtLoginEnableIS_SQLSERVER_AUTHENTICATION=1 SQLLoginEdtPswdDisableIS_SQLSERVER_AUTHENTICATION=0 SQLLoginEdtPswdEnableIS_SQLSERVER_AUTHENTICATION=1 SQLLoginlblLoginIDDisableIS_SQLSERVER_AUTHENTICATION=0 SQLLoginlblLoginIDEnableIS_SQLSERVER_AUTHENTICATION=1 SQLLoginlblPswdDisableIS_SQLSERVER_AUTHENTICATION=0 SQLLoginlblPswdEnableIS_SQLSERVER_AUTHENTICATION=1 SetupCompleteErrorBackDefaultUpdateStarted SetupCompleteErrorBackDisableNOT UpdateStarted SetupCompleteErrorBackEnableUpdateStarted SetupCompleteErrorCancelDisableNOT UpdateStarted SetupCompleteErrorCancelEnableUpdateStarted SetupCompleteErrorFinishDefaultNOT UpdateStarted SetupCompleteErrorFinishText1HideUpdateStarted SetupCompleteErrorFinishText1ShowNOT UpdateStarted SetupCompleteErrorFinishText2HideUpdateStarted SetupCompleteErrorFinishText2ShowNOT UpdateStarted SetupCompleteErrorRestContText1HideNOT UpdateStarted SetupCompleteErrorRestContText1ShowUpdateStarted SetupCompleteErrorRestContText2HideNOT UpdateStarted SetupCompleteErrorRestContText2ShowUpdateStarted SetupCompleteSuccessCheckBoxUpdatesShowISENABLEDWUSFINISHDIALOG And NOT Installed And ACTION="INSTALL" SetupCompleteSuccessCheckForUpdatesTextShowISENABLEDWUSFINISHDIALOG And NOT Installed And ACTION="INSTALL" SetupCompleteSuccessCheckLaunchProgramShowSHOWLAUNCHPROGRAM="-1" And PROGRAMFILETOLAUNCHATEND <> "" And NOT Installed And NOT ISENABLEDWUSFINISHDIALOG SetupCompleteSuccessCheckLaunchReadmeShowSHOWLAUNCHREADME="-1" And READMEFILETOLAUNCHATEND <> "" And NOT Installed And NOT ISENABLEDWUSFINISHDIALOG SetupCompleteSuccessLaunchProgramTextShowSHOWLAUNCHPROGRAM="-1" And PROGRAMFILETOLAUNCHATEND <> "" And NOT Installed And NOT ISENABLEDWUSFINISHDIALOG SetupCompleteSuccessLaunchReadmeTextShowSHOWLAUNCHREADME="-1" And READMEFILETOLAUNCHATEND <> "" And NOT Installed And NOT ISENABLEDWUSFINISHDIALOG SetupCompleteSuccessTextLine2ShowProgressType2="installed" And ((ACTION<>"INSTALL") OR (NOT ISENABLEDWUSFINISHDIALOG) OR (ISENABLEDWUSFINISHDIALOG And Installed)) SetupCompleteSuccessTextLine3ShowProgressType2="uninstalled" And ((ACTION<>"INSTALL") OR (NOT ISENABLEDWUSFINISHDIALOG) OR (ISENABLEDWUSFINISHDIALOG And Installed)) SetupCompleteSuccessUpdateTextLine1ShowISENABLEDWUSFINISHDIALOG And NOT Installed And ACTION="INSTALL" SetupCompleteSuccessUpdateTextLine2ShowISENABLEDWUSFINISHDIALOG And NOT Installed And ACTION="INSTALL" SetupCompleteSuccessUpdateTextLine3ShowISENABLEDWUSFINISHDIALOG And NOT Installed And ACTION="INSTALL" SetupInterruptedBackDefaultUpdateStarted SetupInterruptedBackDisableNOT UpdateStarted SetupInterruptedBackEnableUpdateStarted SetupInterruptedCancelDisableNOT UpdateStarted SetupInterruptedCancelEnableUpdateStarted SetupInterruptedFinishDefaultNOT UpdateStarted SetupInterruptedFinishText1HideUpdateStarted SetupInterruptedFinishText1ShowNOT UpdateStarted SetupInterruptedFinishText2HideUpdateStarted SetupInterruptedFinishText2ShowNOT UpdateStarted SetupInterruptedRestContText1HideNOT UpdateStarted SetupInterruptedRestContText1ShowUpdateStarted SetupInterruptedRestContText2HideNOT UpdateStarted SetupInterruptedRestContText2ShowUpdateStarted SetupProgressDlgDescShowProgressType2="installed" SetupProgressDlgDesc2ShowProgressType2="uninstalled" SetupProgressDlgTextShowProgressType3="installs" SetupProgressDlgText2ShowProgressType3="uninstalls" SetupProgressDlgTitleShowProgressType1="Installing" SetupProgressDlgTitle2ShowProgressType1="Uninstalling" SetupResumePreselectedTextHideRESUME SetupResumePreselectedTextShowNOT RESUME SetupResumeResumeTextHideNOT RESUME SetupResumeResumeTextShowRESUME
Dialog_Control_EventArgumentConditionOrdering
AdminChangeFolderCancelEndDialogReturn12 AdminChangeFolderCancelReset011 AdminChangeFolderNewFolderDirectoryListNew010 AdminChangeFolderOKEndDialogReturn10 AdminChangeFolderOKSetTargetPathTARGETDIR11 AdminChangeFolderUpDirectoryListUp010 AdminNetworkLocationBackNewDialogAdminWelcome10 AdminNetworkLocationBrowseSpawnDialogAdminChangeFolder10 AdminNetworkLocationCancelSpawnDialogCancelSetup10 AdminNetworkLocationInstallNowEndDialogReturnOutOfNoRbDiskSpace <> 13 AdminNetworkLocationInstallNowNewDialogOutOfSpaceOutOfNoRbDiskSpace = 12 AdminNetworkLocationInstallNowSetTargetPathTARGETDIR11 AdminWelcomeCancelSpawnDialogCancelSetup10 AdminWelcomeNextNewDialogAdminNetworkLocation10 CancelSetupNoEndDialogReturn10 CancelSetupYesEndDialogExit12 CustomSetupBackNewDialogDestinationFolderInstalled0 CustomSetupBackNewDialogSetupTypeNOT Installed0 CustomSetupCancelSpawnDialogCancelSetup10 CustomSetupChangeFolderSelectionBrowseInstallChangeFolder10 CustomSetupDetailsSelectionBrowseDiskSpaceRequirements11 CustomSetupHelpSpawnDialogCustomSetupTips11 CustomSetupNextNewDialogOutOfSpaceOutOfNoRbDiskSpace = 10 CustomSetupNextNewDialogReadyToInstallOutOfNoRbDiskSpace <> 10 CustomSetupNext[_IsSetupTypeMin]Custom10 CustomSetupTipsOKEndDialogReturn11 CustomerInformationBackNewDialogLicenseAgreement11 CustomerInformationCancelSpawnDialogCancelSetup10 CustomerInformationNextEndDialogExit(SERIALNUMVALRETRYLIMIT) And (SERIALNUMVALRETRYLIMIT<0) And (SERIALNUMVALRETURN<>SERIALNUMVALSUCCESSRETVAL)3 CustomerInformationNextNewDialogSetupType(Not SERIALNUMVALRETURN) OR (SERIALNUMVALRETURN=SERIALNUMVALSUCCESSRETVAL)4 CustomerInformationNext[ALLUSERS]1ApplicationUsers = "AllUsers" And Privileged1 CustomerInformationNext[ALLUSERS]{}ApplicationUsers = "OnlyCurrentUser" And Privileged2 DatabaseFolderBackNewDialogCustomerInformation11 DatabaseFolderCancelSpawnDialogCancelSetup11 DatabaseFolderChangeFolderSpawnDialogInstallChangeFolder11 DatabaseFolderChangeFolder[_BrowseProperty]DATABASEDIR12 DatabaseFolderNextNewDialogSetupType11 DestinationFolderBackNewDialogLicenseAgreement10 DestinationFolderCancelSpawnDialogCancelSetup11 DestinationFolderChangeFolderSpawnDialogInstallChangeFolder11 DestinationFolderChangeFolder[_BrowseProperty]INSTALLDIR12 DestinationFolderNextNewDialogReadyToInstall10 DiskSpaceRequirementsOKEndDialogReturn10 FilesInUseExitEndDialogExit10 FilesInUseIgnoreEndDialogIgnore10 FilesInUseRetryEndDialogRetry10 InstallChangeFolderCancelEndDialogReturn12 InstallChangeFolderCancelReset011 InstallChangeFolderNewFolderDirectoryListNew010 InstallChangeFolderOKEndDialogReturn13 InstallChangeFolderOKSetTargetPath[_BrowseProperty]12 InstallChangeFolderUpDirectoryListUp010 InstallWelcomeBackNewDialogSplashBitmapDisplay_IsBitmapDlg0 InstallWelcomeCancelSpawnDialogCancelSetup10 InstallWelcomeNextNewDialogLicenseAgreement10 LicenseAgreementBackNewDialogInstallWelcome10 LicenseAgreementCancelSpawnDialogCancelSetup10 LicenseAgreementISPrintButtonDoActionISPrint10 LicenseAgreementNextNewDialogDestinationFolderAgreeToLicense = "Yes"0 MaintenanceTypeBackNewDialogMaintenanceWelcome10 MaintenanceTypeCancelSpawnDialogCancelSetup10 MaintenanceTypeNextNewDialogCustomSetup_IsMaintenance = "Change"12 MaintenanceTypeNextNewDialogReadyToInstall_IsMaintenance = "Reinstall"13 MaintenanceTypeNextNewDialogReadyToRemove_IsMaintenance = "Remove"11 MaintenanceTypeNextReinstallALL_IsMaintenance = "Reinstall"10 MaintenanceTypeNextReinstallMode[ReinstallModeText]_IsMaintenance = "Reinstall"9 MaintenanceTypeNext[ProgressType0]Modify_IsMaintenance = "Change"2 MaintenanceTypeNext[ProgressType0]Repair_IsMaintenance = "Reinstall"1 MaintenanceTypeNext[ProgressType1]Modifying_IsMaintenance = "Change"3 MaintenanceTypeNext[ProgressType1]Repairing_IsMaintenance = "Reinstall"4 MaintenanceTypeNext[ProgressType2]modified_IsMaintenance = "Change"6 MaintenanceTypeNext[ProgressType2]repairs_IsMaintenance = "Reinstall"5 MaintenanceTypeNext[ProgressType3]modifies_IsMaintenance = "Change"7 MaintenanceTypeNext[ProgressType3]repairs_IsMaintenance = "Reinstall"8 MaintenanceWelcomeCancelSpawnDialogCancelSetup10 MaintenanceWelcomeNextNewDialogMaintenanceType10 OutOfSpaceResumeNewDialogAdminNetworkLocationACTION = "ADMIN"0 OutOfSpaceResumeNewDialogCustomSetupACTION <> "ADMIN"0 PatchWelcomeBackNewDialogSplashBitmapDisplay_IsBitmapDlg0 PatchWelcomeCancelSpawnDialogCancelSetup11 PatchWelcomeNextEndDialogReturn13 PatchWelcomeNextReinstallALLPATCH And REINSTALL=""1 PatchWelcomeNextReinstallModeomusPATCH And REINSTALLMODE=""2 ReadyToInstallBackNewDialogCustomSetupInstalled OR _IsSetupTypeMin = "Custom"2 ReadyToInstallBackNewDialogDestinationFolderNOT Installed AND _IsSetupTypeMin <> "Custom"1 ReadyToInstallBackNewDialogMaintenanceTypeInstalled AND _IsMaintenance = "Reinstall"3 ReadyToInstallCancelSpawnDialogCancelSetup10 ReadyToInstallInstallNowEndDialogReturnOutOfNoRbDiskSpace <> 10 ReadyToInstallInstallNowNewDialogOutOfSpaceOutOfNoRbDiskSpace = 10 ReadyToInstallInstallNow[ProgressType1]Installing10 ReadyToInstallInstallNow[ProgressType2]installed10 ReadyToInstallInstallNow[ProgressType3]installs10 ReadyToRemoveBackNewDialogMaintenanceType10 ReadyToRemoveCancelSpawnDialogCancelSetup10 ReadyToRemoveRemoveNowEndDialogReturnOutOfNoRbDiskSpace <> 12 ReadyToRemoveRemoveNowNewDialogOutOfSpaceOutOfNoRbDiskSpace = 12 ReadyToRemoveRemoveNowRemoveALL11 ReadyToRemoveRemoveNow[ProgressType1]Uninstalling10 ReadyToRemoveRemoveNow[ProgressType2]uninstalled10 ReadyToRemoveRemoveNow[ProgressType3]uninstalls10 SQLBrowseCancelEndDialogReturn11 SQLBrowseOKEndDialogReturn12 SQLBrowseOK[IS_SQLSERVER_SERVER][IS_SQLSERVER_LIST]11 SQLLoginBackNewDialogCustomerInformation11 SQLLoginBtnSQLBrowseDoActionISSQLServerList12 SQLLoginBtnSQLBrowseSpawnDialogSQLBrowse13 SQLLoginBtnSQLBrowse[IS_SQLSERVER_LIST][IS_SQLSERVER_SERVER]11 SQLLoginCancelSpawnDialogCancelSetup11 SQLLoginNextDoActionISSQLServerValidate13 SQLLoginNextNewDialogSetupTypeIS_SQLSERVER_STATUS=04 SetupCompleteErrorBackEndDialogReturn12 SetupCompleteErrorBack[Suspend]{}11 SetupCompleteErrorCancelEndDialogReturn12 SetupCompleteErrorCancel[Suspend]111 SetupCompleteErrorFinishEndDialogExit12 SetupCompleteSuccessOKDoActionCheckForProductUpdatesISCHECKFORPRODUCTUPDATES="1" And ISENABLEDWUSFINISHDIALOG And NOT ISREBOOTREQUIRED And NOT Installed And ACTION="INSTALL"4 SetupCompleteSuccessOKDoActionCheckForProductUpdatesOnRebootISCHECKFORPRODUCTUPDATES="1" And ISENABLEDWUSFINISHDIALOG And ISREBOOTREQUIRED And NOT Installed And ACTION="INSTALL"5 SetupCompleteSuccessOKDoActionIS_LAUNCH_MY_PROGRAM_PLEASELAUNCHPROGRAM SetupCompleteSuccessOKEndDialogExit12 SetupErrorAEndDialogErrorAbort10 SetupErrorCEndDialogErrorCancel10 SetupErrorIEndDialogErrorIgnore10 SetupErrorNEndDialogErrorNo10 SetupErrorOEndDialogErrorOk10 SetupErrorREndDialogErrorRetry10 SetupErrorYEndDialogErrorYes10 SetupInitializationCancelSpawnDialogCancelSetup10 SetupInterruptedBackEndDialogExit12 SetupInterruptedBack[Suspend]{}11 SetupInterruptedCancelEndDialogExit12 SetupInterruptedCancel[Suspend]111 SetupInterruptedFinishEndDialogExit12 SetupProgressCancelSpawnDialogCancelSetup10 SetupResumeCancelSpawnDialogCancelSetup10 SetupResumeNextEndDialogReturnOutOfNoRbDiskSpace <> 10 SetupResumeNextNewDialogOutOfSpaceOutOfNoRbDiskSpace = 10 SetupTypeBackNewDialogDestinationFolder10 SetupTypeCancelSpawnDialogCancelSetup10 SetupTypeNextAddLocalALL_IsSetupTypeMin = "Typical"0 SetupTypeNextNewDialogCustomSetup_IsSetupTypeMin = "Custom"0 SetupTypeNextNewDialogReadyToInstall_IsSetupTypeMin <> "Custom"0 SplashBitmapCancelSpawnDialogCancelSetup10 SplashBitmapNextNewDialogInstallWelcome10
Directory_Component_
BINAllOtherFiles10 BINAllOtherFiles11 BINAllOtherFiles8 CONFAllOtherFiles5 CONFAllOtherFiles9 INSTALLDIRAllOtherFiles4 INSTALLDIRAllOtherFiles5 INSTALLDIRAllOtherFiles6 INSTALLDIRAllOtherFiles7 INSTALLDIRISRegistryComponent INSTALLDIRISRegistryComponent1 INSTALLDIRVirtualDirComponent LOGAllOtherFiles12
ActionTypeSourceTargetISComments
CheckForProductUpdates226ISUpdateServiceFolder[ISUpdateServiceFolder]agent.exe "/au[ProductCode] /EndOfInstall"Checks for product updates CheckForProductUpdatesOnReboot226ISUpdateServiceFolder[ISUpdateServiceFolder]agent.exe "/au[ProductCode] /EndOfInstall /Reboot"Checks for product updates on reboot ISPrint1SetAllUsers.dllPrintScrollableTextPrints the contents of a ScrollableText control on a dialog. ISSelfRegisterCosting1ISSELFREG.DLLISSelfRegisterCosting ISSelfRegisterFiles1025ISSELFREG.DLLISSelfRegisterFiles ISSelfRegisterFinalize1ISSELFREG.DLLISSelfRegisterFinalize ISUnSelfRegisterFiles1025ISSELFREG.DLLISUnSelfRegisterFiles InstallFilter70NewBinary19 SetARPINSTALLLOCATION51ARPINSTALLLOCATION[INSTALLDIR] SetAllUsersProfileNT51ALLUSERSPROFILE[%SystemRoot]\Profiles\All Users caCreateVRoots1025binIISHelperCreateIISVRoots caExtractIISSuppFiles1binIISHelperExtractIISTables caIISCleanup1binIISHelperCleanupVRoots caRemoveVRoots1025binIISHelperRemoveIISVRoots caRlbackVRoots1281binIISHelperRlBackRemoveIISVRoots setAllUsersProfile2K51ALLUSERSPROFILE[%ALLUSERSPROFILE] setUserProfileNT51USERPROFILE[%USERPROFILE]
DialogHCenteringVCenteringWidthHeightAttributesTitleControl_FirstControl_DefaultControl_CancelISCommentsTextStyle_ISWindowStyleISResourceId
AdminChangeFolder50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##TailOKCancelInstall Point Browse0 AdminNetworkLocation50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##InstallNowInstallNowCancelNetwork Location0 AdminWelcome50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##NextNextCancelAdministration Welcome0 CancelSetup5050260853##IDS_PRODUCTNAME_INSTALLSHIELD##NoNoNoCancel0 CustomSetup505037426635##IDS_PRODUCTNAME_INSTALLSHIELD##TreeNextCancelCustom Selection0 CustomSetupTips50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##OKOKOKCustom Setup Tips0 CustomerInformation50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##NameEditNextCancelIdentification0 DatabaseFolder50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##NextNextCancelDatabase Folder0 DestinationFolder50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##NextNextCancelDestination Folder0 DiskSpaceRequirements50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##OKOKOKFeature Details0 FilesInUse505037426619##IDS_PRODUCTNAME_INSTALLSHIELD##RetryRetryExitFiles in Use0 InstallChangeFolder50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##TailOKCancelBrowse0 InstallWelcome50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##NextNextCancelWelcome Panel0 LicenseAgreement50503742662##IDS_PRODUCTNAME_INSTALLSHIELD##AgreeNextCancelLicense Agreement0 MaintenanceType50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##RadioGroupNextCancelChange, Reinstall, Remove0 MaintenanceWelcome50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##NextNextCancelMaintenance Welcome0 OutOfSpace50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##ResumeResumeResumeOut Of Disk Space0 PatchWelcome50503742663##IDS__IsPatchDlg_PatchWizard##NextNextCancelPatch Panel0 ReadyToInstall505037426635##IDS_PRODUCTNAME_INSTALLSHIELD##InstallNowInstallNowCancelReady to Install0 ReadyToRemove50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##RemoveNowRemoveNowCancelVerify Remove0 SQLBrowse50502722653##IDS_PRODUCTNAME_INSTALLSHIELD##lstSQLServerOKCancelSQL Server List Browse0 SQLLogin50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##cboServersNextCancelSQL Server Login0 SetupCompleteError50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##FinishFinishFinishFatal Error0 SetupCompleteSuccess50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##OKOKOKExit0 SetupError505027011065543##IDS__IsErrorDlg_InstallerInfo##ErrorTextOCError0 SetupInitialization50503742665##IDS_PRODUCTNAME_INSTALLSHIELD##CancelCancelCancelSetup Initialization0 SetupInterrupted50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##FinishFinishFinishUser Exit0 SetupProgress50503742665##IDS_PRODUCTNAME_INSTALLSHIELD##CancelCancelCancelProgress0 SetupResume50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##NextNextCancelResume0 SetupType50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##RadioGroupNextCancelSetup Type0 SplashBitmap50503742663##IDS_PRODUCTNAME_INSTALLSHIELD##NextNextCancelWelcome Bitmap0
DirectoryDirectory_ParentDefaultDirISDescriptionISAttributesISFolderName
ALLUSERSPROFILETARGETDIR.:ALLUSE~1|All Users0 APACHE_SOFTWARE_FOUNDATIONProgramFilesFolderAPACHE~1|Apache Software Foundation0 AdminToolsFolderTARGETDIR.:Admint~1|AdminTools0 AppDataFolderTARGETDIR.:APPLIC~1|Application Data0 BININSTALLDIRbin0 CONFINSTALLDIRconf0 CommonAppDataFolderTARGETDIR.:Common~1|CommonAppData0 CommonFiles64FolderTARGETDIR.:Common640 CommonFilesFolderTARGETDIR.:Common0 DATABASEDIRISYourDataBaseDir.0 DesktopFolderTARGETDIR.:Desktop3 FavoritesFolderTARGETDIR.:FAVORI~1|Favorites0 FontsFolderTARGETDIR.:Fonts0 GlobalAssemblyCacheTARGETDIR.:Global~1|GlobalAssemblyCache0 IISROOTFOLDERTARGETDIR.:IISRoo~1|IISRootFolder0 INSTALLDIRTOMCAT_ISAPI_REDIRECTOR.0 ISCommonFilesFolderCommonFilesFolderInstal~1|InstallShield0 ISMyCompanyDirProgramFilesFolderMYCOMP~1|My Company Name0 ISMyProductDirISMyCompanyDirMYPROD~1|My Product Name0 ISUpdateServiceFolderISCommonFilesFolderUPDATE~1|UpdateService0 ISYourDataBaseDirINSTALLDIRDatabase0 TOMCAT_ISAPI_REDIRECTORAPACHE_SOFTWARE_FOUNDATIONTOMCAT~1|Tomcat Isapi Redirector0 LOGINSTALLDIRlog0 LocalAppDataFolderTARGETDIR.:LocalA~1|LocalAppData0 MyPicturesFolderTARGETDIR.:MyPict~1|MyPictures0 PersonalFolderTARGETDIR.:Personal0 PrimaryVolumePathTARGETDIR.:Primar~1|PrimaryVolumePath0 ProgramFiles64FolderTARGETDIR.:Prog64~1|Program Files 640 ProgramFilesFolderTARGETDIR.:PROGRA~1|program files0 ProgramMenuFolderTARGETDIR.:Programs3 SendToFolderTARGETDIR.:SendTo3 StartMenuFolderTARGETDIR.:STARTM~1|Start Menu3 StartupFolderTARGETDIR.:StartUp3 System16FolderTARGETDIR.:System0 System64FolderTARGETDIR.:System640 SystemFolderTARGETDIR.:System320 TARGETDIRSourceDir0 TempFolderTARGETDIR.:Temp0 TemplateFolderTARGETDIR.:ShellNew0 USERPROFILETARGETDIR.:USERPR~1|UserProfile0 WindowsFolderTARGETDIR.:Windows0 WindowsVolumeTARGETDIR.:WinRoot0
Signature_ParentPathDepth
FileKeyComponent_File_DestNameDestFolder
EnvironmentNameValueComponent_
ErrorMessage
0##IDS_ERROR_0## 1##IDS_ERROR_1## 10##IDS_ERROR_8## 11##IDS_ERROR_9## 1101##IDS_ERROR_22## 12##IDS_ERROR_10## 13##IDS_ERROR_11## 1301##IDS_ERROR_23## 1302##IDS_ERROR_24## 1303##IDS_ERROR_25## 1304##IDS_ERROR_26## 1305##IDS_ERROR_27## 1306##IDS_ERROR_28## 1307##IDS_ERROR_29## 1308##IDS_ERROR_30## 1309##IDS_ERROR_31## 1310##IDS_ERROR_32## 1311##IDS_ERROR_33## 1312##IDS_ERROR_34## 1313##IDS_ERROR_35## 1314##IDS_ERROR_36## 1315##IDS_ERROR_37## 1316##IDS_ERROR_38## 1317##IDS_ERROR_39## 1318##IDS_ERROR_40## 1319##IDS_ERROR_41## 1320##IDS_ERROR_42## 1321##IDS_ERROR_43## 1322##IDS_ERROR_44## 1323##IDS_ERROR_45## 1324##IDS_ERROR_46## 1325##IDS_ERROR_47## 1326##IDS_ERROR_48## 1327##IDS_ERROR_49## 1328##IDS_ERROR_122## 14##IDS_ERROR_12## 1401##IDS_ERROR_50## 1402##IDS_ERROR_51## 1403##IDS_ERROR_52## 1404##IDS_ERROR_53## 1405##IDS_ERROR_54## 1406##IDS_ERROR_55## 1407##IDS_ERROR_56## 1408##IDS_ERROR_57## 1409##IDS_ERROR_58## 1410##IDS_ERROR_59## 15##IDS_ERROR_13## 1500##IDS_ERROR_60## 1501##IDS_ERROR_61## 1502##IDS_ERROR_62## 1503##IDS_ERROR_63## 16##IDS_ERROR_14## 1601##IDS_ERROR_64## 1602##IDS_ERROR_65## 1603##IDS_ERROR_66## 1604##IDS_ERROR_67## 1605##IDS_ERROR_68## 1606##IDS_ERROR_69## 1607##IDS_ERROR_70## 1608##IDS_ERROR_71## 17##IDS_ERROR_15## 1701##IDS_ERROR_72## 1702##IDS_ERROR_73## 1703##IDS_ERROR_74## 1704##IDS_ERROR_75## 1705##IDS_ERROR_76## 1706##IDS_ERROR_77## 1707##IDS_ERROR_78## 1708##IDS_ERROR_79## 1709##IDS_ERROR_80## 1710##IDS_ERROR_81## 1711##IDS_ERROR_82## 1712##IDS_ERROR_83## 1713##IDS_ERROR_123## 1714##IDS_ERROR_124## 18##IDS_ERROR_16## 1801##IDS_ERROR_84## 1802##IDS_ERROR_85## 1803##IDS_ERROR_86## 1804##IDS_ERROR_87## 1805##IDS_ERROR_88## 1806##IDS_ERROR_89## 1807##IDS_ERROR_90## 19##IDS_ERROR_17## 1901##IDS_ERROR_91## 1902##IDS_ERROR_92## 1903##IDS_ERROR_93## 1904##IDS_ERROR_94## 1905##IDS_ERROR_95## 1906##IDS_ERROR_96## 1907##IDS_ERROR_97## 1908##IDS_ERROR_98## 1909##IDS_ERROR_99## 1910##IDS_ERROR_100## 1911##IDS_ERROR_101## 1912##IDS_ERROR_102## 1913##IDS_ERROR_103## 1914##IDS_ERROR_104## 1915##IDS_ERROR_105## 1916##IDS_ERROR_106## 1917##IDS_ERROR_107## 1918##IDS_ERROR_108## 1919##IDS_ERROR_109## 1920##IDS_ERROR_110## 1921##IDS_ERROR_111## 1922##IDS_ERROR_112## 1923##IDS_ERROR_113## 1924##IDS_ERROR_114## 1925##IDS_ERROR_115## 1926##IDS_ERROR_116## 1927##IDS_ERROR_117## 1928##IDS_ERROR_118## 1929##IDS_ERROR_119## 1930##IDS_ERROR_125## 1931##IDS_ERROR_126## 1932##IDS_ERROR_127## 1933##IDS_ERROR_128## 1934##IDS_ERROR_129## 2##IDS_ERROR_2## 20##IDS_ERROR_18## 21##IDS_ERROR_19## 22##IDS_ERROR_120## 23##IDS_ERROR_121## 2331##IDS_ERROR_2331## 27500##IDS_ERROR_130## 27501##IDS_ERROR_131## 27502##IDS_ERROR_27502## 27503##IDS_ERROR_27503## 27504##IDS_ERROR_27504## 27505##IDS_ERROR_27505## 27506##IDS_ERROR_27506## 27507##IDS_ERROR_27507## 27508##IDS_ERROR_27508## 27509##IDS_ERROR_27509## 27510##IDS_ERROR_27510## 27511##IDS_ERROR_27511## 27512##IDS_ERROR_27512## 27513##IDS_ERROR_27513## 27514##IDS_ERROR_27514## 27515##IDS_ERROR_27515## 27516##IDS_ERROR_27516## 27517##IDS_ERROR_27517## 27518##IDS_ERROR_27518## 27519##IDS_ERROR_27519## 27520##IDS_ERROR_27520## 27521##IDS_ERROR_27521## 27522##IDS_ERROR_27522## 27523##IDS_ERROR_27523## 27524##IDS_ERROR_27524## 27525##IDS_ERROR_27525## 27526##IDS_ERROR_27526## 27527##IDS_ERROR_27527## 27528##IDS_ERROR_27528## 27529##IDS_ERROR_27529## 27530##IDS_ERROR_27530## 27531##IDS_ERROR_27531## 27532##IDS_ERROR_27532## 27533##IDS_ERROR_27533## 27534##IDS_ERROR_27534## 27535##IDS_ERROR_27535## 27536##IDS_ERROR_27536## 27537##IDS_ERROR_27537## 27538##IDS_ERROR_27538## 27539##IDS_ERROR_27539## 27540##IDS_ERROR_27540## 27541##IDS_ERROR_27541## 27542##IDS_ERROR_27542## 27543##IDS_ERROR_27543## 27544##IDS_ERROR_27544## 27545##IDS_ERROR_27545## 27546##IDS_ERROR_27546## 27547##IDS_ERROR_27547## 27548##IDS_ERROR_27548## 27549##IDS_ERROR_27549## 27550##IDS_ERROR_27550## 27551##IDS_ERROR_27551## 27552##IDS_ERROR_27552## 27553##IDS_ERROR_27553## 27554##IDS_ERROR_27554## 32##IDS_ERROR_20## 33##IDS_ERROR_21## 4##IDS_ERROR_3## 5##IDS_ERROR_4## 7##IDS_ERROR_5## 8##IDS_ERROR_6## 9##IDS_ERROR_7##
Dialog_Control_EventAttribute
CustomSetupItemDescriptionSelectionDescriptionText CustomSetupLocationSelectionPathText CustomSetupSizeSelectionSizeText SetupInitializationActionDataActionDataText SetupInitializationActionTextActionTextText SetupProgressActionProgress95AdminInstallFinalizeProgress SetupProgressActionProgress95InstallFilesProgress SetupProgressActionProgress95MoveFilesProgress SetupProgressActionProgress95RemoveFilesProgress SetupProgressActionProgress95RemoveRegistryValuesProgress SetupProgressActionProgress95SetProgressProgress SetupProgressActionProgress95UnmoveFilesProgress SetupProgressActionProgress95WriteIniValuesProgress SetupProgressActionProgress95WriteRegistryValuesProgress SetupProgressActionTextActionTextText
ExtensionComponent_ProgId_MIME_Feature_
FeatureFeature_ParentTitleDescriptionDisplayLevelDirectory_AttributesISReleaseFlagsISCommentsISFeatureCabNameISProFeatureName
MainFeature##ID_STRING4##21INSTALLDIR0
Feature_Component_
MainFeatureAllOtherFiles MainFeatureAllOtherFiles1 MainFeatureAllOtherFiles2 MainFeatureAllOtherFiles3 MainFeatureISRegistryComponent MainFeatureISRegistryComponent1 MainFeatureVirtualDirComponent
FileComponent_FileNameFileSizeVersionLanguageAttributesSequenceISBuildSourcePathISAttributesISComponentSubFolder_
license.txtAllOtherFiles3LICENSE.TXT01<ISProjectFolder>\LICENSE.TXT1
File_SFPCatalog_
File_FontTitle
TagData
BiildCDROMEnabled BiildInternetEnabled BiildSingleExeEnabled BiildSingleMSIEnabled PROJECT_ASSISTANT_DEFAULT_FEATURENewFeature1 PROJECT_ASSISTANT_FEATURESNonSelectable RegistryPageEnabledYes
AppKeyAppNameCompanyNameDefDirIconPathIconIndexDeviceFileDesktopTargetDirDescriptionDeleteMediaInstallNetCFInstallSQLServerInstallSQLClientInstallSQLDevPreXMLPostXMLNoUninstallSPCFilePVKFileAttributesRawDeviceFileComponent_
AppKeyDirKeyDirParentDirValue
AppKeyFileKeyNameDestinationSourceProcessorPlatformCopyOptionFileOptionAdvancedOptions
AppKeyExtKeyFileKeyDescriptionExtensionIconIndex
CEInstallKeyCEAppNameCEDesktopDirCEIniFileKeyCECabsCEIcoFileDeleteMediaComponent_
AppKeyFileKeyBuildSourcePath
AppKeyRegKeyRootKeyNameValueProcessorPlatformOverwrite
AppKeySetupFileKeyNameSourceProcessorPlatform
AppKeyShtCutKeyDisplayNameDestinationTargetPlatform
ISComCatalogObject_ItemNameItemValue
ISComCatalogCollectionISComCatalogObject_CollectionName
ISComCatalogCollection_ISComCatalogObject_
ISComCatalogObjectDisplayName
ISComCatalogObject_ComputerNameComponent_ISAttributesDepFiles
ISComPlusProxyISComPlusApplication_Component_ISAttributesDepFiles
Component_OSLanguageFilterPropertyPlatformsFTPLocationHTTPLocationMiscellaneous
AllOtherFiles_74B17E30_4D29_487A_8CD4_7B95B8D56A83_FILTER AllOtherFiles1_7B0061CE_6436_4507_9459_93572D569FC1_FILTER AllOtherFiles10_E157B509_E34A_4875_AB50_BA85BE3F5DD2_FILTER AllOtherFiles11_3B6FD6F4_F250_47A8_834C_D7EFD14C3BEF_FILTER AllOtherFiles12_D98A783F_15B1_4E2D_B444_2AFE9178F6F0_FILTER AllOtherFiles2_7322BDD9_A833_41E8_B75C_D99037B19E78_FILTER AllOtherFiles3_C7E1E3F1_ABC8_4A0D_929F_A385EDF1E1F7_FILTER AllOtherFiles4_D740564E_80EF_41ED_958F_95C1F4062224_FILTER AllOtherFiles5_D918C9FE_F0EE_4F2B_870A_095BCA8C2C2F_FILTER AllOtherFiles6_228CD380_C643_4C2C_8ECB_4E7429660108_FILTER AllOtherFiles7_0C21B08E_04C8_4326_8560_DDA770F7D93E_FILTER AllOtherFiles8_845468E3_C693_4547_A32F_F231781A4C8A_FILTER AllOtherFiles9_5F1CCD3B_FD30_4D31_ACEE_707E99BE0281_FILTER ISRegistryComponent_1DEB35F2_294C_4ED0_B0A2_78FB6F4E2EFF_FILTER ISRegistryComponent1_2E54C60F_AF93_4D31_8E1B_F381B381FC92_FILTER VirtualDirComponent_5ACAD922_2F71_4963_BCF2_D05C97252574_FILTER
ISDIMReference_RequiredUUIDRequiredMajorVersionRequiredMinorVersionRequiredBuildVersionRequiredRevisionVersion
ISDIMReferenceISBuildSourcePath
ISDIMReference_ParentISDIMDependency_
ISDIMVariableISDIMReference_NameNewValueType
EntryPointTypeSourceTarget
ISDRMFileFile_ISDRMLicense_Shell
ISDRMFile_PropertyValue
ISDRMLicenseDescriptionProjectVersionAttributesLicenseNumberRequestCodeResponseCode
ISDependencyExclude
ISDisk1FileISBuildSourcePathDisk
Component_SourceFolderIncludeFlagsIncludeFilesExcludeFilesISAttributes
AllOtherFiles<ISProjectFolder>\bin40 AllOtherFiles1<ISProjectFolder>\conf40 AllOtherFiles2<ISProjectFolder>\log40
Feature_ISDIMReference_
Feature_ModuleIDLanguage
Feature_ISMergeModule_Language_
File_Manifest_
AppPoolNameComponent_AttributesUserUserPasswordRecycleMinutesRecycleRequestsRecycleTimesIdleTimeoutQueueLimitCPUMonMaxProc
ISIISCommonISIISCommon_ParentDisplayNameRootDirAttributesDefDocSessionTimeoutScriptTimeoutAnonyUserNameAnonyPasswrdCustomErrorsAppNameSSLCertAppPool_
ISIISCommonVRootISIISCommonWebsite1##ID_STRING3##BIN28069Default.asp2090 ISIISCommonWebsite1Default Web SiteIISROOTFOLDER281132090
ISIISCommon_MetaDataPropMetaDataTypeMetaDataUserTypeMetaDataAttributesOrderMetaDataValue
WebServiceExtensionComponent_FileDescriptionGroupAttributes
EntryPointTypeSourceTarget
ISLanguageIncluded
10331
ISLinkerLibraryLibraryOrder
Isrt.obl<ISProductFolder>\Script\ISRT\Lib\isrt.obl2 Iswi.obl<ISProductFolder>\Script\ISWi\Lib\iswi.obl1
Dialog_Control_ISLanguage_AttributesXYWidthHeightBinary_ISBuildSourcePath
Dialog_ISLanguage_AttributesTextStyle_WidthHeight
PropertyOrderISLanguage_XYWidthHeight
DiskIdISProductConfiguration_ISRelease_LastSequenceDiskPromptCabinetVolumeLabelSource
1ReleaseBin0 1ReleaseMsi0
ISLogicalDisk_ISProductConfiguration_ISRelease_Feature_SequenceISAttributes
ISMergeModuleLanguageNameDestinationISAttributes
ISMergeModule_Language_ModuleConfiguration_ValueFormatTypeContextDataDefaultValueAttributesDisplayNameDescriptionHelpLocationHelpKeyword
ObjectNameLanguage
ObjectNamePropertyValueIncludeInBuild
PalmAppComponent
PalmAppFileKeyDestination
PatchConfiguration_UpgradedImage_
NameCanPCDifferCanPVDifferIncludeWholeFilesLeaveDecompressedOptimizeForSizeEnablePatchCachePatchCacheDirFlagsPatchGuidsToReplaceTargetProductCodesPatchGuidOutputPathMinMsiVersionAttributes
ISPatchConfiguration_PropertyValue
NameISUpgradedImage_FileKeyFilePath
UpgradedImageFileKeyComponent
ISPathVariableValueTestValueType
CommonFilesFolder1 ISPROJECTDIR1 ISProductFolder1 ISProjectDataFolder1 ISProjectFolder1 ProgramFilesFolder1 SystemFolder1 WindowsFolder1
ISProductConfigurationProductConfigurationFlagsGeneratePackageCode
Release1
ISProductConfiguration_InstanceIdPropertyValue
ISProductConfiguration_PropertyValue
ReleaseSetupFileNamesetup
ISReleaseISProductConfiguration_BuildLocationPackageNameTypeSupportedLanguagesUIMsiSourceTypeReleaseTypePlatformsSupportedLanguagesDataDefaultLanguageSupportedOSsDiskSizeDiskSizeUnitDiskClusterSizeReleaseFlagsDiskSpanningSynchMsiMediaLocationURLLocationDigitalURLDigitalPVKDigitalSPCPasswordVersionCopyrightAttributesCDBrowserDotNetBuildConfigurationMsiCommandLineISSetupPrerequisiteLocation
BinRelease<ISProjectDataFolder>PackageName4103321Intel103330100MediaLocationhttp://8988685 MsiRelease<ISProjectDataFolder>PackageName0103321Intel10333650020480MediaLocationhttp://8464397
ISRelease_ISProductConfiguration_PropertyValue
ISRelease_ISProductConfiguration_WebTypeWebURLWebCabSizeOneClickCabNameOneClickHtmlNameWebLocalCachePathEngineLocationWin9xMsiUrlWinNTMsiUrlISEngineLocationISEngineURLOneClickTargetBrowserDigitalCertificateIdNSDigitalCertificateDBaseNSDigitalCertificatePasswordNSDotNetRedistLocationDotNetRedistURLDotNetVersionDotNetBaseLanguageDotNetLangaugePacksDotNetFxCmdLineDotNetLangPackCmdLineJSharpCmdLineAttributesJSharpRedistLocationMsiEngineVersionWinMsi30UrlCertPassword
BinRelease0http://0installinstall[WindowsFolder]Downloaded Installations1http://www.installengine.com/Msiengine20http://www.installengine.com/Msiengine202http://www.installengine.com/cert05/isengine23http://www.installengine.com/cert05/dotnetfx010331634http://www.installengine.com/Msiengine30 MsiRelease0http://0installinstall[WindowsFolder]Downloaded Installations2http://www.installengine.com/Msiengine20http://www.installengine.com/Msiengine202http://www.installengine.com/cert05/isengine3http://www.installengine.com/cert05/dotnetfx010331634http://www.installengine.com/Msiengine30 Release 1Release
ISRelease_ISProductConfiguration_RepositoryDisplayNamePublisherDescriptionISAttributes
ISSQLConnectionServerDatabaseUserNamePasswordAuthenticationAttributesOrderCommentsCmdTimeoutBatchSeparator
ISSQLConnectionDBServerISSQLConnection_ISSQLDBMetaData_Order
ISSQLConnection_ISSQLScriptFile_Order
ISSQLDBMetaDataDisplayNameAdoDriverNameAdoCxnDriverAdoCxnServerAdoCxnDatabaseAdoCxnUserIDAdoCxnPasswordAdoCxnWindowsSecurityAdoCxnNetLibraryTestDatabaseCmdTestTableCmdVersionInfoCmdVersionBeginTokenVersionEndTokenLocalInstanceNamesCreateDbCmdSwitchDbCmdISAttributesTestTableCmd2WinAuthentUserIdDsnODBCName
ISSQLRequirementISSQLConnection_MajorVersionServicePackLevelAttributesISSQLConnectionDBServer_
ErrNumberISSQLScriptFile_ErrHandlingMessageAttributes
ISSQLScriptFileComponent_SchedulingInstallTextUninstallTextISBuildSourcePathCommentsErrorHandlingAttributesVersion
ISSQLScriptFile_ServerDatabaseUserNamePasswordAuthenticationIncludeTablesExcludeTablesAttributes
ISSQLScriptReplaceISSQLScriptFile_SearchReplaceAttributes
ISScriptFile
FileKeyCostOrderCmdLine
ISSetupFileFileNameStreamLanguageSplashPath
ISSetupPrerequisitesISBuildSourcePathOrder
ISSetupTypeDescriptionDisplay_NameDisplayComments
ISSetupType_Feature_
NameISBuildSourcePath
ISStringISLanguage_ValueEncodedCommentTimeStamp
COMPANY_NAME1033Apache Software Foundation02115503849 DN_AlwaysInstall1033Always Install0-1256677244 IDPROP_EXPRESS_LAUNCH_CONDITION_COLOR1033The color settings of your system are not adequate for running [ProductName].0-1256677244 IDPROP_EXPRESS_LAUNCH_CONDITION_OS1033[ProductName] requires that your computer is running Windows NT 4.0 or Windows 2000 or Windows XP or Windows 2003 Server02115550953 IDPROP_EXPRESS_LAUNCH_CONDITION_PROCESSOR1033The processor is not adequate for running [ProductName].0-1256677244 IDPROP_EXPRESS_LAUNCH_CONDITION_RAM1033The amount of RAM is not adequate for running [ProductName].0-1256677244 IDPROP_EXPRESS_LAUNCH_CONDITION_SCREEN1033The screen resolution is not adequate for running [ProductName].0-1256677244 IDPROP_SETUPTYPE_COMPACT1033Compact0-1256677244 IDPROP_SETUPTYPE_COMPACT_DESC1033Compact Description0-1256677244 IDPROP_SETUPTYPE_COMPLETE1033Complete0-1256677244 IDPROP_SETUPTYPE_COMPLETE_DESC1033Complete0-1256677244 IDPROP_SETUPTYPE_CUSTOM1033Custom0-1256677244 IDPROP_SETUPTYPE_CUSTOM_DESC1033Custom Description0-1256677244 IDPROP_SETUPTYPE_CUSTOM_DESC_PRO1033Custom0-1256677244 IDPROP_SETUPTYPE_TYPICAL1033Typical0-1256677244 IDPROP_SETUPTYPE_TYPICAL_DESC1033Typical Description0-1256677244 IDS_ACTIONTEXT_11033[1]0-1256677244 IDS_ACTIONTEXT_1b1033[1]0-1256677244 IDS_ACTIONTEXT_1c1033[1]0-1256677244 IDS_ACTIONTEXT_1d1033[1]0-1256677244 IDS_ACTIONTEXT_Advertising1033Advertising application0-1256677244 IDS_ACTIONTEXT_AllocatingRegistry1033Allocating registry space0-1256677244 IDS_ACTIONTEXT_AppCommandLine1033Application: [1], Command line: [2]0-1256677244 IDS_ACTIONTEXT_AppId1033AppId: [1]{{, AppType: [2]}}0-1256677244 IDS_ACTIONTEXT_AppIdAppTypeRSN1033AppId: [1]{{, AppType: [2], Users: [3], RSN: [4]}}0-1256677244 IDS_ACTIONTEXT_Application1033Application: [1]0-1256677244 IDS_ACTIONTEXT_BindingExes1033Binding executables0-1256677244 IDS_ACTIONTEXT_ClassId1033Class ID: [1]0-1256677244 IDS_ACTIONTEXT_ClsID1033Class ID: [1]0-1256677244 IDS_ACTIONTEXT_ComponentIDQualifier1033Component ID: [1], Qualifier: [2]0-1256677244 IDS_ACTIONTEXT_ComponentIdQualifier21033Component ID: [1], Qualifier: [2]0-1256677244 IDS_ACTIONTEXT_ComputingSpace1033Computing space requirements0-1256677244 IDS_ACTIONTEXT_ComputingSpace21033Computing space requirements0-1256677244 IDS_ACTIONTEXT_ComputingSpace31033Computing space requirements0-1256677244 IDS_ACTIONTEXT_ContentTypeExtension1033MIME Content Type: [1], Extension: [2]0-1256677244 IDS_ACTIONTEXT_ContentTypeExtension21033MIME Content Type: [1], Extension: [2]0-1256677244 IDS_ACTIONTEXT_CopyingNetworkFiles1033Copying files to the network0-1256677244 IDS_ACTIONTEXT_CopyingNewFiles1033Copying new files0-1256677244 IDS_ACTIONTEXT_CreatingDuplicate1033Creating duplicate files0-1256677244 IDS_ACTIONTEXT_CreatingFolders1033Creating folders0-1256677244 IDS_ACTIONTEXT_CreatingIISRoots1033Creating IIS Virtual Roots...0-1256677244 IDS_ACTIONTEXT_CreatingShortcuts1033Creating shortcuts0-1256677244 IDS_ACTIONTEXT_DeletingServices1033Deleting services0-1256677244 IDS_ACTIONTEXT_EnvironmentStrings1033Updating environment strings0-1256677244 IDS_ACTIONTEXT_EvaluateLaunchConditions1033Evaluating launch conditions0-1256677244 IDS_ACTIONTEXT_Extension1033Extension: [1]0-1256677244 IDS_ACTIONTEXT_Extension21033Extension: [1]0-1256677244 IDS_ACTIONTEXT_Feature1033Feature: [1]0-1256677244 IDS_ACTIONTEXT_FeatureColon1033Feature: [1]0-1256677244 IDS_ACTIONTEXT_File1033File: [1]0-1256677244 IDS_ACTIONTEXT_File21033File: [1]0-1256677244 IDS_ACTIONTEXT_FileDependencies1033File: [1], Dependencies: [2]0-1256677244 IDS_ACTIONTEXT_FileDir1033File: [1], Directory: [9]0-1256677244 IDS_ACTIONTEXT_FileDir21033File: [1], Directory: [9]0-1256677244 IDS_ACTIONTEXT_FileDir31033File: [1], Directory: [9]0-1256677244 IDS_ACTIONTEXT_FileDirSize1033File: [1], Directory: [9], Size: [6]0-1256677244 IDS_ACTIONTEXT_FileDirSize21033File: [1], Directory: [9], Size: [6]0-1256677244 IDS_ACTIONTEXT_FileDirSize31033File: [1], Directory: [9], Size: [6]0-1256677244 IDS_ACTIONTEXT_FileDirSize41033File: [1], Directory: [2], Size: [3]0-1256677244 IDS_ACTIONTEXT_FileDirectorySize1033File: [1], Directory: [9], Size: [6]0-1256677244 IDS_ACTIONTEXT_FileFolder1033File: [1], Folder: [2]0-1256677244 IDS_ACTIONTEXT_FileFolder21033File: [1], Folder: [2]0-1256677244 IDS_ACTIONTEXT_FileSectionKeyValue1033File: [1], Section: [2], Key: [3], Value: [4]0-1256677244 IDS_ACTIONTEXT_FileSectionKeyValue21033File: [1], Section: [2], Key: [3], Value: [4]0-1256677244 IDS_ACTIONTEXT_Folder1033Folder: [1]0-1256677244 IDS_ACTIONTEXT_Folder11033Folder: [1]0-1256677244 IDS_ACTIONTEXT_Font1033Font: [1]0-1256677244 IDS_ACTIONTEXT_Font21033Font: [1]0-1256677244 IDS_ACTIONTEXT_FoundApp1033Found application: [1]0-1256677244 IDS_ACTIONTEXT_FreeSpace1033Free space: [1]0-1256677244 IDS_ACTIONTEXT_GeneratingScript1033Generating script operations for action:0-1256677244 IDS_ACTIONTEXT_InitializeODBCDirs1033Initializing ODBC directories0-1256677244 IDS_ACTIONTEXT_InstallODBC1033Installing ODBC components0-1256677244 IDS_ACTIONTEXT_InstallServices1033Installing new services0-1256677244 IDS_ACTIONTEXT_InstallingSystemCatalog1033Installing system catalog0-1256677244 IDS_ACTIONTEXT_KeyName1033Key: [1], Name: [2]0-1256677244 IDS_ACTIONTEXT_KeyNameValue1033Key: [1], Name: [2], Value: [3]0-1256677244 IDS_ACTIONTEXT_LibId1033LibID: [1]0-1256677244 IDS_ACTIONTEXT_Libid21033LibID: [1]0-1256677244 IDS_ACTIONTEXT_MigratingFeatureStates1033Migrating feature states from related applications0-1256677244 IDS_ACTIONTEXT_MovingFiles1033Moving files0-1256677244 IDS_ACTIONTEXT_NameValueAction1033Name: [1], Value: [2], Action [3]0-1256677244 IDS_ACTIONTEXT_NameValueAction21033Name: [1], Value: [2], Action [3]0-1256677244 IDS_ACTIONTEXT_PatchingFiles1033Patching files0-1256677244 IDS_ACTIONTEXT_ProgID1033ProgID: [1]0-1256677244 IDS_ACTIONTEXT_ProgID21033ProgID: [1]0-1256677244 IDS_ACTIONTEXT_PropertySignature1033Property: [1], Signature: [2]0-1256677244 IDS_ACTIONTEXT_PublishProductFeatures1033Publishing product features0-1256677244 IDS_ACTIONTEXT_PublishProductInfo1033Publishing product information0-1256677244 IDS_ACTIONTEXT_PublishingQualifiedComponents1033Publishing qualified components0-1256677244 IDS_ACTIONTEXT_RegUser1033Registering user0-1256677244 IDS_ACTIONTEXT_RegisterClassServer1033Registering class servers0-1256677244 IDS_ACTIONTEXT_RegisterExtensionServers1033Registering extension servers0-1256677244 IDS_ACTIONTEXT_RegisterFonts1033Registering fonts0-1256677244 IDS_ACTIONTEXT_RegisterMimeInfo1033Registering MIME info0-1256677244 IDS_ACTIONTEXT_RegisterTypeLibs1033Registering type libraries0-1256677244 IDS_ACTIONTEXT_RegisteringComPlus1033Registering COM+ Applications and Components0-1256677244 IDS_ACTIONTEXT_RegisteringModules1033Registering modules0-1256677244 IDS_ACTIONTEXT_RegisteringProduct1033Registering product0-1256677244 IDS_ACTIONTEXT_RegisteringProgIdentifiers1033Registering program identifiers0-1256677244 IDS_ACTIONTEXT_RemoveApps1033Removing applications0-1256677244 IDS_ACTIONTEXT_RemovingBackup1033Removing backup files0-1256677244 IDS_ACTIONTEXT_RemovingDuplicates1033Removing duplicated files0-1256677244 IDS_ACTIONTEXT_RemovingFiles1033Removing files0-1256677244 IDS_ACTIONTEXT_RemovingFolders1033Removing folders0-1256677244 IDS_ACTIONTEXT_RemovingIISRoots1033Removing IIS Virtual Roots...0-1256677244 IDS_ACTIONTEXT_RemovingIni1033Removing INI file entries0-1256677244 IDS_ACTIONTEXT_RemovingMoved1033Removing moved files0-1256677244 IDS_ACTIONTEXT_RemovingODBC1033Removing ODBC components0-1256677244 IDS_ACTIONTEXT_RemovingRegistry1033Removing system registry values0-1256677244 IDS_ACTIONTEXT_RemovingShortcuts1033Removing shortcuts0-1256677244 IDS_ACTIONTEXT_RollingBack1033Rolling back action:0-1256677244 IDS_ACTIONTEXT_SearchForRelated1033Searching for related applications0-1256677244 IDS_ACTIONTEXT_SearchInstalled1033Searching for installed applications0-1256677244 IDS_ACTIONTEXT_SearchingQualifyingProducts1033Searching for qualifying products0-1256677244 IDS_ACTIONTEXT_SearchingQualifyingProducts21033Searching for qualifying products0-1256677244 IDS_ACTIONTEXT_Service1033Service: [1]0-1256677244 IDS_ACTIONTEXT_Service21033Service: [2]0-1256677244 IDS_ACTIONTEXT_Service31033Service: [1]0-1256677244 IDS_ACTIONTEXT_Service41033Service: [1]0-1256677244 IDS_ACTIONTEXT_Shortcut1033Shortcut: [1]0-1256677244 IDS_ACTIONTEXT_Shortcut11033Shortcut: [1]0-1256677244 IDS_ACTIONTEXT_StartingServices1033Starting services0-1256677244 IDS_ACTIONTEXT_StoppingServices1033Stopping services0-1256677244 IDS_ACTIONTEXT_UnpublishProductFeatures1033Unpublishing product features0-1256677244 IDS_ACTIONTEXT_UnpublishQualified1033Unpublishing Qualified Components0-1256677244 IDS_ACTIONTEXT_UnpublishingProductInfo1033Unpublishing product information0-1256677244 IDS_ACTIONTEXT_UnregTypeLibs1033Unregistering type libraries0-1256677244 IDS_ACTIONTEXT_UnregisterClassServers1033Unregister class servers0-1256677244 IDS_ACTIONTEXT_UnregisterExtensionServers1033Unregistering extension servers0-1256677244 IDS_ACTIONTEXT_UnregisterModules1033Unregistering modules0-1256677244 IDS_ACTIONTEXT_UnregisteringComPlus1033Unregistering COM+ Applications and Components0-1256677244 IDS_ACTIONTEXT_UnregisteringFonts1033Unregistering fonts0-1256677244 IDS_ACTIONTEXT_UnregisteringMimeInfo1033Unregistering MIME info0-1256677244 IDS_ACTIONTEXT_UnregisteringProgramIds1033Unregistering program identifiers0-1256677244 IDS_ACTIONTEXT_UpdateComponentRegistration1033Updating component registration0-1256677244 IDS_ACTIONTEXT_UpdateEnvironmentStrings1033Updating environment strings0-1256677244 IDS_ACTIONTEXT_Validating1033Validating install0-1256677244 IDS_ACTIONTEXT_WritingINI1033Writing INI file values0-1256677244 IDS_ACTIONTEXT_WritingRegistry1033Writing system registry values0-1256677244 IDS_BACK1033< &Back0-1256677244 IDS_CANCEL1033Cancel0-1256677244 IDS_CANCEL21033&Cancel0-1256677244 IDS_CHANGE1033&Change...0-1256677244 IDS_COMPLUS_PROGRESSTEXT_COST1033Costing COM+ application: [1]0-1256677244 IDS_COMPLUS_PROGRESSTEXT_INSTALL1033Installing COM+ application: [1]0-1256677244 IDS_COMPLUS_PROGRESSTEXT_UNINSTALL1033Uninstalling COM+ application: [1]0-1256677244 IDS_DatabaseFolder_InstallDatabaseTo1033Install [ProductName] database to:0-1256677244 IDS_ERROR_01033{{Fatal error: }}0-1256677244 IDS_ERROR_11033Error [1].0-1256677244 IDS_ERROR_101033=== Logging started: [Date] [Time] ===0-1256677244 IDS_ERROR_1001033Could not remove shortcut [2]. Verify that the shortcut file exists and that you can access it.0-1256677244 IDS_ERROR_1011033Could not register type library for file [2]. Contact your support personnel.0-1256677244 IDS_ERROR_1021033Could not unregister type library for file [2]. Contact your support personnel.0-1256677244 IDS_ERROR_1031033Could not update the INI file [2][3]. Verify that the file exists and that you can access it.0-1256677244 IDS_ERROR_1041033Could not schedule file [2] to replace file [3] on reboot. Verify that you have write permissions to file [3].0-1256677244 IDS_ERROR_1051033Error removing ODBC driver manager, ODBC error [2]: [3]. Contact your support personnel.0-1256677244 IDS_ERROR_1061033Error installing ODBC driver manager, ODBC error [2]: [3]. Contact your support personnel.0-1256677244 IDS_ERROR_1071033Error removing ODBC driver [4], ODBC error [2]: [3]. Verify that you have sufficient privileges to remove ODBC drivers.0-1256677244 IDS_ERROR_1081033Error installing ODBC driver [4], ODBC error [2]: [3]. Verify that the file [4] exists and that you can access it.0-1256677244 IDS_ERROR_1091033Error configuring ODBC data source [4], ODBC error [2]: [3]. Verify that the file [4] exists and that you can access it.0-1256677244 IDS_ERROR_111033=== Logging stopped: [Date] [Time] ===0-1256677244 IDS_ERROR_1101033Service [2] ([3]) failed to start. Verify that you have sufficient privileges to start system services.0-1256677244 IDS_ERROR_1111033Service [2] ([3]) could not be stopped. Verify that you have sufficient privileges to stop system services.0-1256677244 IDS_ERROR_1121033Service [2] ([3]) could not be deleted. Verify that you have sufficient privileges to remove system services.0-1256677244 IDS_ERROR_1131033Service [2] ([3]) could not be installed. Verify that you have sufficient privileges to install system services.0-1256677244 IDS_ERROR_1141033Could not update environment variable [2]. Verify that you have sufficient privileges to modify environment variables.0-1256677244 IDS_ERROR_1151033You do not have sufficient privileges to complete this installation for all users of the machine. Log on as an administrator and then retry this installation.0-1256677244 IDS_ERROR_1161033Could not set file security for file [3]. Error: [2]. Verify that you have sufficient privileges to modify the security permissions for this file.0-1256677244 IDS_ERROR_1171033Component Services (COM+ 1.0) are not installed on this computer. This installation requires Component Services in order to complete successfully. Component Services are available on Windows 2000.0-1256677244 IDS_ERROR_1181033Error registering COM+ application. Contact your support personnel for more information.0-1256677244 IDS_ERROR_1191033Error unregistering COM+ application. Contact your support personnel for more information.0-1256677244 IDS_ERROR_121033Action start [Time]: [1].0-1256677244 IDS_ERROR_1201033Removing older versions of this application0-1256677244 IDS_ERROR_1211033Preparing to remove older versions of this application0-1256677244 IDS_ERROR_1221033Error applying patch to file [2]. It has probably been updated by other means, and can no longer be modified by this patch. For more information contact your patch vendor. {{System Error: [3]}}0-1256677244 IDS_ERROR_1231033[2] cannot install one of its required products. Contact your technical support group. {{System Error: [3].}}0-1256677244 IDS_ERROR_1241033The older version of [2] cannot be removed. Contact your technical support group. {{System Error [3].}}0-1256677244 IDS_ERROR_1251033The description for service '[2]' ([3]) could not be changed.0-1256677244 IDS_ERROR_1261033The Windows Installer service cannot update the system file [2] because the file is protected by Windows. You may need to update your operating system for this program to work correctly. {{Package version: [3], OS Protected version: [4]}}0-1256677244 IDS_ERROR_1271033The Windows Installer service cannot update the protected Windows file [2]. {{Package version: [3], OS Protected version: [4], SFP Error: [5]}}0-1256677244 IDS_ERROR_1281033The Windows Installer service cannot update one or more protected Windows files. SFP Error: [2]. List of protected files: [3]0-1256677244 IDS_ERROR_1291033User installations are disabled via policy on the machine.0-1256677244 IDS_ERROR_131033Action ended [Time]: [1]. Return value [2].0-1256677244 IDS_ERROR_1301033This setup requires Internet Information Server 4.0 or higher for configuring IIS Virtual Roots. Please make sure that you have IIS 4.0 or higher.0-1256677244 IDS_ERROR_1311033This setup requires Administrator privileges for configuring IIS Virtual Roots.0-1256677244 IDS_ERROR_141033Time remaining: {[1] minutes }{[2] seconds}0-1256677244 IDS_ERROR_151033Out of memory. Shut down other applications before retrying.0-1256677244 IDS_ERROR_161033Installer is no longer responding.0-1256677244 IDS_ERROR_171033Installer terminated prematurely.0-1256677244 IDS_ERROR_181033Please wait while Windows configures [ProductName]0-1256677244 IDS_ERROR_191033Gathering required information...0-1256677244 IDS_ERROR_21033Warning [1].0-1256677244 IDS_ERROR_201033{[ProductName] }Setup completed successfully.0-1256677244 IDS_ERROR_211033{[ProductName] }Setup failed.0-1256677244 IDS_ERROR_221033Error reading from file: [2]. {{ System error [3].}} Verify that the file exists and that you can access it.0-1256677244 IDS_ERROR_231033Cannot create the file [3]. A directory with this name already exists. Cancel the installation and try installing to a different location.0-1256677244 IDS_ERROR_23311033Error loading library [2] or finding entry point [3].0-1256677244 IDS_ERROR_241033Please insert the disk: [2]0-1256677244 IDS_ERROR_251033The installer has insufficient privileges to access this directory: [2]. The installation cannot continue. Log on as an administrator or contact your system administrator.0-1256677244 IDS_ERROR_261033Error writing to file [2]. Verify that you have access to that directory.0-1256677244 IDS_ERROR_271033Error reading from file [2]. Verify that the file exists and that you can access it.0-1256677244 IDS_ERROR_275021033Could not connect to [2] '[3]'. [4]0-1256677244 IDS_ERROR_275031033Error retrieving version string from [2] '[3]'. [4]0-1256677244 IDS_ERROR_275041033SQL version requirements not met: [3]. This installation requires [2] [4] or later.0 IDS_ERROR_275051033Could not open SQL script file [2].0-1256677244 IDS_ERROR_275061033Error executing SQL script [2]. Line [3]. [4]0-1256677244 IDS_ERROR_275071033Connection or browsing for database servers requires that MDAC be installed.0-1256677244 IDS_ERROR_275081033Error installing COM+ application [2]. [3]0-1256677244 IDS_ERROR_275091033Error uninstalling COM+ application [2]. [3]0-1256677244 IDS_ERROR_275101033Error installing COM+ application [2]. Could not load Microsoft(R) .NET class libraries. Registering .NET serviced components requires that Microsoft(R) .NET Framework be installed.0-1256677244 IDS_ERROR_275111033Could not execute SQL script file [2]. Connection not open: [3]0-1256677244 IDS_ERROR_275121033Error beginning transactions for [2] '[3]'. Database [4]. [5]0-1256677244 IDS_ERROR_275131033Error committing transactions for [2] '[3]'. Database [4]. [5]0-1256677244 IDS_ERROR_275141033This installation requires a Microsoft SQL Server. The specified server '[3]' is a Microsoft SQL Server Desktop Engine (MSDE).0-1256677244 IDS_ERROR_275151033Error retrieving schema version from [2] '[3]'. Database: '[4]'. [5]0-1256677244 IDS_ERROR_275161033Error writing schema version to [2] '[3]'. Database: '[4]'. [5]0-1256677244 IDS_ERROR_275171033This installation requires Administrator privileges for installing COM+ applications. Log on as an administrator and then retry this installation.0-1256677244 IDS_ERROR_275181033The COM+ application "[2]" is configured to run as an NT service; this requires COM+ 1.5 or later on the system. Since your system has COM+ 1.0, this application will not be installed.0-1256677244 IDS_ERROR_275191033Error updating XML file [2]. [3]0-1256677244 IDS_ERROR_275201033Error opening XML file [2]. [3]0-1256677244 IDS_ERROR_275211033This setup requires MSXML 3.0 or higher for configuring XML files. Please make sure that you have version 3.0 or higher.0-1256677244 IDS_ERROR_275221033Error creating XML file [2]. [3]0-1256677244 IDS_ERROR_275231033Error loading servers.0-1256677244 IDS_ERROR_275241033Error loading NetApi32.DLL. The ISNetApi.dll needs to have NetApi32.DLL properly loaded and requires an NT based operating system.0-1256677244 IDS_ERROR_275251033Server not found. Verify that the specified server exists. The server name can not be empty.0-1256677244 IDS_ERROR_275261033Unspecified error from ISNetApi.dll.0-1256677244 IDS_ERROR_275271033The buffer is too small.0-1256677244 IDS_ERROR_275281033Access denied. Check administrative rights.0-1256677244 IDS_ERROR_275291033Invalid computer.0-1256677244 IDS_ERROR_275301033Undefined switch case.0-1256677244 IDS_ERROR_275311033Unhandled exception.0-1256677244 IDS_ERROR_275321033Invalid user name for this server or domain.0-1256677244 IDS_ERROR_275331033The case-sensitive passwords do not match.0-1256677244 IDS_ERROR_275341033The list is empty.0-1256677244 IDS_ERROR_275351033Access violation.0-1256677244 IDS_ERROR_275361033Error getting group.0-1256677244 IDS_ERROR_275371033Error adding user to group. Verify that the group exists for this domain or server.0-1256677244 IDS_ERROR_275381033Error creating user.0-1256677244 IDS_ERROR_275391033ERROR_NETAPI_ERROR_NOT_PRIMARY returned from NetAPI.0-1256677244 IDS_ERROR_275401033The specified user already exists.0-1256677244 IDS_ERROR_275411033The specified group already exists.0-1256677244 IDS_ERROR_275421033Invalid password. Verify that the password is in accordance with your network password policy.0-1256677244 IDS_ERROR_275431033Invalid name.0-1256677244 IDS_ERROR_275441033Invalid group.0-1256677244 IDS_ERROR_275451033The user name can not be empty and must be in the format DOMAIN\Username.0-1256677244 IDS_ERROR_275461033Error loading or creating INI file in the user TEMP directory.0-1256677244 IDS_ERROR_275471033ISNetAPI.dll is not loaded or there was an error loading the dll. This dll needs to be loaded for this operation. Verify that the dll is in the SUPPORTDIR directory.0-1256677244 IDS_ERROR_275481033Error deleting INI file containing new user information from the user's TEMP directory.0-1256677244 IDS_ERROR_275491033Error getting the primary domain controller (PDC).0-1256677244 IDS_ERROR_275501033Every field must have a value in order to create a user.0-1256677244 IDS_ERROR_275511033ODBC driver for [2] not found. This is required to connect to [2] database servers.0-1256677244 IDS_ERROR_275521033Error creating database [4]. Server: [2] [3]. [5]0 IDS_ERROR_275531033Error connecting to database [4]. Server: [2] [3]. [5]0 IDS_ERROR_275541033Error attempting to open connection [2]. No valid database metadata associated with this connection.0 IDS_ERROR_281033Another application has exclusive access to the file [2]. Please shut down all other applications, then click Retry.0-1256677244 IDS_ERROR_291033There is not enough disk space to install the file [2]. Free some disk space and click Retry, or click Cancel to exit.0-1256677244 IDS_ERROR_31033Info [1].0-1256677244 IDS_ERROR_301033Source file not found: [2]. Verify that the file exists and that you can access it.0-1256677244 IDS_ERROR_311033Error reading from file: [3]. {{ System error [2].}} Verify that the file exists and that you can access it.0-1256677244 IDS_ERROR_321033Error writing to file: [3]. {{ System error [2].}} Verify that you have access to that directory.0-1256677244 IDS_ERROR_331033Source file not found{{(cabinet)}}: [2]. Verify that the file exists and that you can access it.0-1256677244 IDS_ERROR_341033Cannot create the directory [2]. A file with this name already exists. Please rename or remove the file and click Retry, or click Cancel to exit.0-1256677244 IDS_ERROR_351033The volume [2] is currently unavailable. Please select another.0-1256677244 IDS_ERROR_361033The specified path [2] is unavailable.0-1256677244 IDS_ERROR_371033Unable to write to the specified folder [2].0-1256677244 IDS_ERROR_381033A network error occurred while attempting to read from the file [2]0-1256677244 IDS_ERROR_391033An error occurred while attempting to create the directory [2]0-1256677244 IDS_ERROR_41033Internal Error [1]. [2]{, [3]}{, [4]}0-1256677244 IDS_ERROR_401033A network error occurred while attempting to create the directory [2]0-1256677244 IDS_ERROR_411033A network error occurred while attempting to open the source file cabinet [2].0-1256677244 IDS_ERROR_421033The specified path is too long [2].0-1256677244 IDS_ERROR_431033The Installer has insufficient privileges to modify the file [2].0-1256677244 IDS_ERROR_441033A portion of the path [2] exceeds the length allowed by the system.0-1256677244 IDS_ERROR_451033The path [2] contains words that are not valid in folders.0-1256677244 IDS_ERROR_461033The path [2] contains an invalid character.0-1256677244 IDS_ERROR_471033[2] is not a valid short file name.0-1256677244 IDS_ERROR_481033Error getting file security: [3] GetLastError: [2]0-1256677244 IDS_ERROR_491033Invalid Drive: [2]0-1256677244 IDS_ERROR_51033{{Disk full: }}0-1256677244 IDS_ERROR_501033Could not create key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.0-1256677244 IDS_ERROR_511033Could not open key: [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.0-1256677244 IDS_ERROR_521033Could not delete value [2] from key [3]. {{ System error [4].}} Verify that you have sufficient access to that key, or contact your support personnel.0-1256677244 IDS_ERROR_531033Could not delete key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.0-1256677244 IDS_ERROR_541033Could not read value [2] from key [3]. {{ System error [4].}} Verify that you have sufficient access to that key, or contact your support personnel.0-1256677244 IDS_ERROR_551033Could not write value [2] to key [3]. {{ System error [4].}} Verify that you have sufficient access to that key, or contact your support personnel.0-1256677244 IDS_ERROR_561033Could not get value names for key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.0-1256677244 IDS_ERROR_571033Could not get sub key names for key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.0-1256677244 IDS_ERROR_581033Could not read security information for key [2]. {{ System error [3].}} Verify that you have sufficient access to that key, or contact your support personnel.0-1256677244 IDS_ERROR_591033Could not increase the available registry space. [2] KB of free registry space is required for the installation of this application.0-1256677244 IDS_ERROR_61033Action [Time]: [1]. [2]0-1256677244 IDS_ERROR_601033Another installation is in progress. You must complete that installation before continuing this one.0-1256677244 IDS_ERROR_611033Error accessing secured data. Please make sure the Windows Installer is configured properly and try the installation again.0-1256677244 IDS_ERROR_621033User [2] has previously initiated an installation for product [3]. That user will need to run that installation again before using that product. Your current installation will now continue.0-1256677244 IDS_ERROR_631033User [2] has previously initiated an installation for product [3]. That user will need to run that installation again before using that product.0-1256677244 IDS_ERROR_641033Out of disk space -- Volume: '[2]'; required space: [3] KB; available space: [4] KB. Free some disk space and retry.0-1256677244 IDS_ERROR_651033Are you sure you want to cancel?0-1256677244 IDS_ERROR_661033The file [2][3] is being held in use{ by the following process: Name: [4], ID: [5], Window Title: [6]}. Close that application and retry.0-1256677244 IDS_ERROR_671033The product [2] is already installed, preventing the installation of this product. The two products are incompatible.0-1256677244 IDS_ERROR_681033Out of disk space -- Volume: [2]; required space: [3] KB; available space: [4] KB. If rollback is disabled, enough space is available. Click Cancel to quit, Retry to check available disk space again, or Ignore to continue without rollback.0-1256677244 IDS_ERROR_691033Could not access network location [2].0-1256677244 IDS_ERROR_71033[ProductName]0-1256677244 IDS_ERROR_701033The following applications should be closed before continuing the installation:0-1256677244 IDS_ERROR_711033Could not find any previously installed compliant products on the machine for installing this product.0-1256677244 IDS_ERROR_721033The key [2] is not valid. Verify that you entered the correct key.0-1256677244 IDS_ERROR_731033The installer must restart your system before configuration of [2] can continue. Click Yes to restart now or No if you plan to restart later.0-1256677244 IDS_ERROR_741033You must restart your system for the configuration changes made to [2] to take effect. Click Yes to restart now or No if you plan to restart later.0-1256677244 IDS_ERROR_751033An installation for [2] is currently suspended. You must undo the changes made by that installation to continue. Do you want to undo those changes?0-1256677244 IDS_ERROR_761033A previous installation for this product is in progress. You must undo the changes made by that installation to continue. Do you want to undo those changes?0-1256677244 IDS_ERROR_771033No valid source could be found for product [2]. The Windows Installer cannot continue.0-1256677244 IDS_ERROR_781033Installation operation completed successfully.0-1256677244 IDS_ERROR_791033Installation operation failed.0-1256677244 IDS_ERROR_81033{[2]}{, [3]}{, [4]}0-1256677244 IDS_ERROR_801033Product: [2] -- [3]0-1256677244 IDS_ERROR_811033You may either restore your computer to its previous state or continue the installation later. Would you like to restore?0-1256677244 IDS_ERROR_821033An error occurred while writing installation information to disk. Check to make sure enough disk space is available, and click Retry, or Cancel to end the installation.0-1256677244 IDS_ERROR_831033One or more of the files required to restore your computer to its previous state could not be found. Restoration will not be possible.0-1256677244 IDS_ERROR_841033The path [2] is not valid. Please specify a valid path.0-1256677244 IDS_ERROR_851033Out of memory. Shut down other applications before retrying.0-1256677244 IDS_ERROR_861033There is no disk in drive [2]. Please insert one and click Retry, or click Cancel to go back to the previously selected volume.0-1256677244 IDS_ERROR_871033There is no disk in drive [2]. Please insert one and click Retry, or click Cancel to return to the browse dialog and select a different volume.0-1256677244 IDS_ERROR_881033The folder [2] does not exist. Please enter a path to an existing folder.0-1256677244 IDS_ERROR_891033You have insufficient privileges to read this folder.0-1256677244 IDS_ERROR_91033Message type: [1], Argument: [2]0-1256677244 IDS_ERROR_901033A valid destination folder for the installation could not be determined.0-1256677244 IDS_ERROR_911033Error attempting to read from the source installation database: [2].0-1256677244 IDS_ERROR_921033Scheduling reboot operation: Renaming file [2] to [3]. Must reboot to complete operation.0-1256677244 IDS_ERROR_931033Scheduling reboot operation: Deleting file [2]. Must reboot to complete operation.0-1256677244 IDS_ERROR_941033Module [2] failed to register. HRESULT [3]. Contact your support personnel.0-1256677244 IDS_ERROR_951033Module [2] failed to unregister. HRESULT [3]. Contact your support personnel.0-1256677244 IDS_ERROR_961033Failed to cache package [2]. Error: [3]. Contact your support personnel.0-1256677244 IDS_ERROR_971033Could not register font [2]. Verify that you have sufficient permissions to install fonts, and that the system supports this font.0-1256677244 IDS_ERROR_981033Could not unregister font [2]. Verify that you have sufficient permissions to remove fonts.0-1256677244 IDS_ERROR_991033Could not create shortcut [2]. Verify that the destination folder exists and that you can access it.0-1256677244 IDS_INSTALLDIR1033[INSTALLDIR]0-1256677244 IDS_INSTALLSHIELD1033InstallShield0-1256677244 IDS_INSTALLSHIELD_FORMATTED1033{&MSSWhiteSerif8}InstallShield0-1256677244 IDS_ISSCRIPT_VERSION_MISSING1033The InstallScript engine is missing from this machine. If available, please run ISScript.msi, or contact your support personnel for further assistance.0-1256677244 IDS_ISSCRIPT_VERSION_OLD1033The InstallScript engine on this machine is older than the version required to run this setup. If available, please install the latest version of ISScript.msi, or contact your support personnel for further assistance.0-1256677244 IDS_NEXT1033&Next >0-1256677244 IDS_OK1033OK0-1256677244 IDS_PRINT_BUTTON1033&Print0-1256677244 IDS_PRODUCTNAME_INSTALLSHIELD1033[ProductName] - InstallShield Wizard0-1256677244 IDS_PROGMSG_IIS_CREATEAPPPOOL1033Creating application pool %s0 IDS_PROGMSG_IIS_CREATEAPPPOOLS1033Creating application Pools...0 IDS_PROGMSG_IIS_CREATEVROOT1033Creating IIS virtual directory %s0-1256677244 IDS_PROGMSG_IIS_CREATEVROOTS1033Creating IIS virtual directories...0-1256677244 IDS_PROGMSG_IIS_CREATEWEBSERVICEEXTENSION1033Creating web service extension0 IDS_PROGMSG_IIS_CREATEWEBSERVICEEXTENSIONS1033Creating web service extensions...0 IDS_PROGMSG_IIS_EXTRACT1033Extracting information for IIS virtual directories...0-1256677244 IDS_PROGMSG_IIS_EXTRACTDONE1033Extracted information for IIS virtual directories...0-1256677244 IDS_PROGMSG_IIS_REMOVEAPPPOOL1033Removing application pool0 IDS_PROGMSG_IIS_REMOVEAPPPOOLS1033Removing application pools...0 IDS_PROGMSG_IIS_REMOVESITE1033Removing web site at port %d0-1256677244 IDS_PROGMSG_IIS_REMOVEVROOT1033Removing IIS virtual directory %s0-1256677244 IDS_PROGMSG_IIS_REMOVEVROOTS1033Removing IIS virtual directories...0-1256677244 IDS_PROGMSG_IIS_REMOVEWEBSERVICEEXTENSION1033Removing web service extension0 IDS_PROGMSG_IIS_REMOVEWEBSERVICEEXTENSIONS1033Removing web service extensions...0 IDS_PROGMSG_IIS_ROLLBACKAPPPOOLS1033Rolling back application pools...0 IDS_PROGMSG_IIS_ROLLBACKVROOTS1033Rolling back virtual directory and web site changes...0-1256677244 IDS_PROGMSG_IIS_ROLLBACKWEBSERVICEEXTENSIONS1033Rolling back web service extensions...0 IDS_PROGMSG_XML_COSTING1033Costing XML files...0-1256677244 IDS_PROGMSG_XML_CREATE_FILE1033Creating XML file %s...0-1256677244 IDS_PROGMSG_XML_FILES1033Performing XML file changes...0-1256677244 IDS_PROGMSG_XML_REMOVE_FILE1033Removing XML file %s...0-1256677244 IDS_PROGMSG_XML_ROLLBACK_FILES1033Rolling back XML file changes...0-1256677244 IDS_PROGMSG_XML_UPDATE_FILE1033Updating XML file %s...0-1256677244 IDS_SQLBROWSE_INTRO1033From the list of servers below, select the database server you would like to target.0-1256677244 IDS_SQLLOGIN_BROWSE1033B&rowse...0-1256677244 IDS_SQLLOGIN_CONNECT1033Connect using:0-1256677244 IDS_SQLLOGIN_DESC1033Select database server and authentication method0-1256677244 IDS_SQLLOGIN_ID1033&Login ID:0-1256677244 IDS_SQLLOGIN_INTRO1033Select the database server to install to from the list below or click Browse to see a list of all database servers. You can also specify the way to authenticate your login using your current credentials or a SQL Login ID and Password.0-1256677244 IDS_SQLLOGIN_PSWD1033&Password:0-1256677244 IDS_SQLLOGIN_SERVER1033&Database Server:0-1256677244 IDS_SQLLOGIN_SQL1033S&erver authentication using the Login ID and password below0-1256677244 IDS_SQLLOGIN_TITLE1033{&MSSansBold8}Database Server0-1256677244 IDS_SQLLOGIN_WIN1033&Windows authentication credentials of current user0-1256677244 IDS_SQLSCRIPT_INSTALLING1033Executing SQL Install Script...0-1256677244 IDS_SQLSCRIPT_UNINSTALLING1033Executing SQL Uninstall Script...0-1256677244 IDS_STANDARD_USE_SETUPEXE1033This installation cannot be run by directly launching the MSI package. You must run setup.exe.0-1256677244 IDS_SetupTips_Advertise1033Will be installed on first use. (Available only if the feature supports this option.)0-1256677244 IDS_SetupTips_AllInstalledLocal1033Will be completely installed to the local hard drive.0-1256677244 IDS_SetupTips_CustomSetup1033{&MSSansBold8}Custom Setup Tips0-1256677244 IDS_SetupTips_CustomSetupDescription1033Custom Setup allows you to selectively install program features.0-1256677244 IDS_SetupTips_IconInstallState1033The icon next to the feature name indicates the install state of the feature. Click the icon to drop down the install state menu for each feature.0-1256677244 IDS_SetupTips_InstallState1033This install state means the feature...0-1256677244 IDS_SetupTips_Network1033Will be installed to run from the network. (Available only if the feature supports this option.)0-1256677244 IDS_SetupTips_OK1033OK0-1256677244 IDS_SetupTips_SubFeaturesInstalledLocal1033Will have some subfeatures installed to the local hard drive. (Available only if the feature has subfeatures.)0-1256677244 IDS_SetupTips_WillNotBeInstalled1033Will not be installed.0-1256677244 IDS_UITEXT_Available1033Available0-1256677244 IDS_UITEXT_Bytes1033bytes0-1256677244 IDS_UITEXT_CompilingFeaturesCost1033Compiling cost for this feature...0-1256677244 IDS_UITEXT_Differences1033Differences0-1256677244 IDS_UITEXT_DiskSize1033Disk Size0-1256677244 IDS_UITEXT_FeatureCompletelyRemoved1033This feature will be completely removed.0-1256677244 IDS_UITEXT_FeatureContinueNetwork1033This feature will continue to be run from the network0-1256677244 IDS_UITEXT_FeatureFreeSpace1033This feature frees up [1] on your hard drive.0-1256677244 IDS_UITEXT_FeatureInstalledCD1033This feature, and all subfeatures, will be installed to run from the CD.0-1256677244 IDS_UITEXT_FeatureInstalledCD21033This feature will be installed to run from CD.0-1256677244 IDS_UITEXT_FeatureInstalledLocal1033This feature, and all subfeatures, will be installed on local hard drive.0-1256677244 IDS_UITEXT_FeatureInstalledLocal21033This feature will be installed on local hard drive.0-1256677244 IDS_UITEXT_FeatureInstalledNetwork1033This feature, and all subfeatures, will be installed to run from the network.0-1256677244 IDS_UITEXT_FeatureInstalledNetwork21033This feature will be installed to run from network.0-1256677244 IDS_UITEXT_FeatureInstalledRequired1033Will be installed when required.0-1256677244 IDS_UITEXT_FeatureInstalledWhenRequired1033This feature will be set to be installed when required.0-1256677244 IDS_UITEXT_FeatureInstalledWhenRequired21033This feature will be installed when required.0-1256677244 IDS_UITEXT_FeatureLocal1033This feature will be installed on the local hard drive.0-1256677244 IDS_UITEXT_FeatureLocal21033This feature will be installed on your local hard drive.0-1256677244 IDS_UITEXT_FeatureNetwork1033This feature will be installed to run from the network.0-1256677244 IDS_UITEXT_FeatureNetwork21033This feature will be available to run from the network.0-1256677244 IDS_UITEXT_FeatureNotAvailable1033This feature will not be available.0-1256677244 IDS_UITEXT_FeatureOnCD1033This feature will be installed to run from CD.0-1256677244 IDS_UITEXT_FeatureOnCD21033This feature will be available to run from CD.0-1256677244 IDS_UITEXT_FeatureRemainLocal1033This feature will remain on your local hard drive.0-1256677244 IDS_UITEXT_FeatureRemoveNetwork1033This feature will be removed from your local hard drive, but will be still available to run from the network.0-1256677244 IDS_UITEXT_FeatureRemovedCD1033This feature will be removed from your local hard drive but will still be available to run from CD.0-1256677244 IDS_UITEXT_FeatureRemovedUnlessRequired1033This feature will be removed from your local hard drive but will be set to be installed when required.0-1256677244 IDS_UITEXT_FeatureRequiredSpace1033This feature requires [1] on your hard drive.0-1256677244 IDS_UITEXT_FeatureRunFromCD1033This feature will continue to be run from the CD0-1256677244 IDS_UITEXT_FeatureSpaceFree1033This feature frees up [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures free up [4] on your hard drive.0-1256677244 IDS_UITEXT_FeatureSpaceFree21033This feature frees up [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures require [4] on your hard drive.0-1256677244 IDS_UITEXT_FeatureSpaceFree31033This feature requires [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures free up [4] on your hard drive.0-1256677244 IDS_UITEXT_FeatureSpaceFree41033This feature requires [1] on your hard drive. It has [2] of [3] subfeatures selected. The subfeatures require [4] on your hard drive.0-1256677244 IDS_UITEXT_FeatureUnavailable1033This feature will become unavailable.0-1256677244 IDS_UITEXT_FeatureUninstallNoNetwork1033This feature will be uninstalled completely, and you won't be able to run it from the network.0-1256677244 IDS_UITEXT_FeatureWasCD1033This feature was run from the CD but will be set to be installed when required.0-1256677244 IDS_UITEXT_FeatureWasCDLocal1033This feature was run from the CD but will be installed on the local hard drive.0-1256677244 IDS_UITEXT_FeatureWasOnNetworkInstalled1033This feature was run from the network but will be installed when required.0-1256677244 IDS_UITEXT_FeatureWasOnNetworkLocal1033This feature was run from the network but will be installed on the local hard drive.0-1256677244 IDS_UITEXT_FeatureWillBeUninstalled1033This feature will be uninstalled completely, and you won't be able to run it from CD.0-1256677244 IDS_UITEXT_Folder1033Fldr|New Folder0-1256677244 IDS_UITEXT_GB1033GB0-1256677244 IDS_UITEXT_KB1033KB0-1256677244 IDS_UITEXT_MB1033MB0-1256677244 IDS_UITEXT_Required1033Required0-1256677244 IDS_UITEXT_TimeRemaining1033Time remaining: {[1] min }[2] sec0-1256677244 IDS_UITEXT_Volume1033Volume0-1256677244 IDS__AgreeToLicense_01033I &do not accept the terms in the license agreement0-1256677244 IDS__AgreeToLicense_11033I &accept the terms in the license agreement0-1256677244 IDS__DatabaseFolder_ChangeFolder1033Click Next to install to this folder, or click Change to install to a different folder.0-1256677244 IDS__DatabaseFolder_DatabaseDir1033[DATABASEDIR]0-1256677244 IDS__DatabaseFolder_DatabaseFolder1033{&MSSansBold8}Database Folder0-1256677244 IDS__DestinationFolder_Change1033&Change...0-1256677244 IDS__DestinationFolder_ChangeFolder1033Click Next to install to this folder, or click Change to install to a different folder.0-1256677244 IDS__DestinationFolder_DestinationFolder1033{&MSSansBold8}Destination Folder0-1256677244 IDS__DestinationFolder_InstallTo1033Install [ProductName] to:0-1256677244 IDS__DisplayName_Custom1033Custom0-1256677244 IDS__DisplayName_Minimal1033Minimal0-1256677244 IDS__DisplayName_Typical1033Typical0-1256677244 IDS__IsAdminInstallBrowse_1110330-1256677244 IDS__IsAdminInstallBrowse_410330-1256677244 IDS__IsAdminInstallBrowse_810330-1256677244 IDS__IsAdminInstallBrowse_BrowseDestination1033Browse to the destination folder.0-1256677244 IDS__IsAdminInstallBrowse_ChangeDestination1033{&MSSansBold8}Change Current Destination Folder0-1256677244 IDS__IsAdminInstallBrowse_CreateFolder1033Create new folder|0-1256677244 IDS__IsAdminInstallBrowse_FolderName1033&Folder name:0-1256677244 IDS__IsAdminInstallBrowse_LookIn1033&Look in:0-1256677244 IDS__IsAdminInstallBrowse_UpOneLevel1033Up one level|0-1256677244 IDS__IsAdminInstallPointWelcome_ServerImage1033The InstallShield(R) Wizard will create a server image of [ProductName] at a specified network location. To continue, click Next.0-1256677244 IDS__IsAdminInstallPointWelcome_Wizard1033{&TahomaBold10}Welcome to the InstallShield Wizard for [ProductName]0-1256677244 IDS__IsAdminInstallPoint_Change1033&Change...0-1256677244 IDS__IsAdminInstallPoint_EnterNetworkLocation1033Enter the network location or click Change to browse to a location. Click Install to create a server image of [ProductName] at the specified network location or click Cancel to exit the wizard.0-1256677244 IDS__IsAdminInstallPoint_Install1033&Install0-1256677244 IDS__IsAdminInstallPoint_NetworkLocation1033&Network location:0-1256677244 IDS__IsAdminInstallPoint_NetworkLocationFormatted1033{&MSSansBold8}Network Location0-1256677244 IDS__IsAdminInstallPoint_SpecifyNetworkLocation1033Specify a network location for the server image of the product.0-1256677244 IDS__IsBrowseButton1033&Browse...0-1256677244 IDS__IsBrowseFolderDlg_1110330-1256677244 IDS__IsBrowseFolderDlg_410330-1256677244 IDS__IsBrowseFolderDlg_810330-1256677244 IDS__IsBrowseFolderDlg_BrowseDestFolder1033Browse to the destination folder.0-1256677244 IDS__IsBrowseFolderDlg_ChangeCurrentFolder1033{&MSSansBold8}Change Current Destination Folder0-1256677244 IDS__IsBrowseFolderDlg_CreateFolder1033Create New Folder|0-1256677244 IDS__IsBrowseFolderDlg_FolderName1033&Folder name:0-1256677244 IDS__IsBrowseFolderDlg_LookIn1033&Look in:0-1256677244 IDS__IsBrowseFolderDlg_OK1033OK0-1256677244 IDS__IsBrowseFolderDlg_UpOneLevel1033Up One Level|0-1256677244 IDS__IsBrowseForAccount1033Browse for a User Account0-1256677244 IDS__IsBrowseGroup1033Select a Group0-1256677244 IDS__IsBrowseUsernameTitle1033Select a User Name0-1256677244 IDS__IsCancelDlg_ConfirmCancel1033Are you sure you want to cancel [ProductName] installation?0-1256677244 IDS__IsCancelDlg_No1033&No0-1256677244 IDS__IsCancelDlg_Yes1033&Yes0-1256677244 IDS__IsConfirmPassword1033Con&firm password:0-1256677244 IDS__IsCreateNewUserTitle1033New User Information0-1256677244 IDS__IsCreateUserBrowse1033N&ew User Information...0-1256677244 IDS__IsCustomSelectionDlg_Change1033&Change...0-1256677244 IDS__IsCustomSelectionDlg_ClickFeatureIcon1033Click on an icon in the list below to change how a feature is installed.0-1256677244 IDS__IsCustomSelectionDlg_CustomSetup1033{&MSSansBold8}Custom Setup0-1256677244 IDS__IsCustomSelectionDlg_FeatureDescription1033Feature Description0-1256677244 IDS__IsCustomSelectionDlg_FeaturePath1033<selected feature path>0-1256677244 IDS__IsCustomSelectionDlg_FeatureSize1033Feature size0-1256677244 IDS__IsCustomSelectionDlg_Help1033&Help0-1256677244 IDS__IsCustomSelectionDlg_InstallTo1033Install to:0-1256677244 IDS__IsCustomSelectionDlg_MultilineDescription1033Multiline description of the currently selected item0-1256677244 IDS__IsCustomSelectionDlg_SelectFeatures1033Select the program features you want installed.0-1256677244 IDS__IsCustomSelectionDlg_Space1033&Space0-1256677244 IDS__IsDiskSpaceDlg_DiskSpace1033Disk space required for the installation exceeds available disk space.0-1256677244 IDS__IsDiskSpaceDlg_HighlightedVolumes1033The highlighted volumes do not have enough disk space available for the currently selected features. You can remove files from the highlighted volumes, choose to install fewer features onto local drives, or select different destination drives.0-1256677244 IDS__IsDiskSpaceDlg_Numbers1033{120}{70}{70}{70}{70}0-1256677244 IDS__IsDiskSpaceDlg_OK1033OK0-1256677244 IDS__IsDiskSpaceDlg_OutOfDiskSpace1033{&MSSansBold8}Out of Disk Space0-1256677244 IDS__IsDomainOrServer1033&Domain or server:0-1256677244 IDS__IsErrorDlg_Abort1033&Abort0-1256677244 IDS__IsErrorDlg_ErrorText1033<error text goes here><error text goes here><error text goes here><error text goes here><error text goes here><error text goes here><error text goes here><error text goes here><error text goes here><error text goes here><error text goes here>0-1256677244 IDS__IsErrorDlg_Ignore1033&Ignore0-1256677244 IDS__IsErrorDlg_InstallerInfo1033[ProductName] Installer Information0-1256677244 IDS__IsErrorDlg_NO1033&No0-1256677244 IDS__IsErrorDlg_OK1033&OK0-1256677244 IDS__IsErrorDlg_Retry1033&Retry0-1256677244 IDS__IsErrorDlg_Yes1033&Yes0-1256677244 IDS__IsExitDialog_Finish1033&Finish0-1256677244 IDS__IsExitDialog_InstallSuccess1033The InstallShield Wizard has successfully installed [ProductName]. Click Finish to exit the wizard.0-1256677244 IDS__IsExitDialog_LaunchProgram1033Launch the program0-1256677244 IDS__IsExitDialog_ShowReadMe1033Show the readme file0-1256677244 IDS__IsExitDialog_UninstallSuccess1033The InstallShield Wizard has successfully uninstalled [ProductName]. Click Finish to exit the wizard.0-1256677244 IDS__IsExitDialog_Update_InternetConnection1033Your Internet connection can be used to make sure that you have the latest updates.0-1256677244 IDS__IsExitDialog_Update_PossibleUpdates1033Some program files might have been updated since you purchased your copy of [ProductName].0-1256677244 IDS__IsExitDialog_Update_SetupFinished1033Setup has finished installing [ProductName].0-1256677244 IDS__IsExitDialog_Update_YesCheckForUpdates1033&Yes, check for program updates (Recommended) after the setup completes.0-1256677244 IDS__IsExitDialog_WizardCompleted1033{&TahomaBold10}InstallShield Wizard Completed0-1256677244 IDS__IsFatalError_ClickFinish1033Click Finish to exit the wizard.0-1256677244 IDS__IsFatalError_Finish1033&Finish0-1256677244 IDS__IsFatalError_KeepOrRestore1033You can either keep any existing installed elements on your system to continue this installation at a later time or you can restore your system to its original state prior to the installation.0-1256677244 IDS__IsFatalError_NotModified1033Your system has not been modified. To complete installation at another time, please run setup again.0-1256677244 IDS__IsFatalError_RestoreOrContinueLater1033Click Restore or Continue Later to exit the wizard.0-1256677244 IDS__IsFatalError_WizardCompleted1033{&TahomaBold10}InstallShield Wizard Completed0-1256677244 IDS__IsFatalError_WizardInterrupted1033The wizard was interrupted before [ProductName] could be completely installed.0-1256677244 IDS__IsFeatureDetailsDlg_DiskSpaceRequirements1033{&MSSansBold8}Disk Space Requirements0-1256677244 IDS__IsFeatureDetailsDlg_Numbers1033{120}{70}{70}{70}{70}0-1256677244 IDS__IsFeatureDetailsDlg_OK1033OK0-1256677244 IDS__IsFeatureDetailsDlg_SpaceRequired1033The disk space required for the installation of the selected features.0-1256677244 IDS__IsFeatureDetailsDlg_VolumesTooSmall1033The highlighted volumes do not have enough disk space available for the currently selected features. You can remove files from the highlighted volumes, choose to install fewer features onto local drives, or select different destination drives.0-1256677244 IDS__IsFilesInUse_ApplicationsUsingFiles1033The following applications are using files that need to be updated by this setup. Close these applications and click Retry to continue.0-1256677244 IDS__IsFilesInUse_Exit1033&Exit0-1256677244 IDS__IsFilesInUse_FilesInUse1033{&MSSansBold8}Files in Use0-1256677244 IDS__IsFilesInUse_FilesInUseMessage1033Some files that need to be updated are currently in use.0-1256677244 IDS__IsFilesInUse_Ignore1033&Ignore0-1256677244 IDS__IsFilesInUse_Retry1033&Retry0-1256677244 IDS__IsGroup1033&Group:0-1256677244 IDS__IsGroupLabel1033Gr&oup:0-1256677244 IDS__IsInitDlg_110330-1256677244 IDS__IsInitDlg_210330-1256677244 IDS__IsInitDlg_PreparingWizard1033[ProductName] Setup is preparing the InstallShield Wizard which will guide you through the program setup process. Please wait.0-1256677244 IDS__IsInitDlg_WelcomeWizard1033{&TahomaBold10}Welcome to the InstallShield Wizard for [ProductName]0-1256677244 IDS__IsLicenseDlg_LicenseAgreement1033{&MSSansBold8}License Agreement0-1256677244 IDS__IsLicenseDlg_ReadLicenseAgreement1033Please read the following license agreement carefully.0-1256677244 IDS__IsLogonInfoDescription1033Specify the user name and password of the user account that will logon to use this application. The user account must be in the form DOMAIN\Username.0-1256677244 IDS__IsLogonInfoTitle1033{&MSSansBold8}Logon Information0-1256677244 IDS__IsLogonInfoTitleDescription1033Specify a user name and password0-1256677244 IDS__IsLogonNewUserDescription1033Select the button below to specify information about a new user that will be created during the installation.0-1256677244 IDS__IsMaintenanceDlg_1110330-1256677244 IDS__IsMaintenanceDlg_ChangeFeatures1033Change which program features are installed. This option displays the Custom Selection dialog in which you can change the way features are installed.0-1256677244 IDS__IsMaintenanceDlg_MaitenanceOptions1033Modify, repair, or remove the program.0-1256677244 IDS__IsMaintenanceDlg_Modify1033{&MSSansBold8}&Modify0-1256677244 IDS__IsMaintenanceDlg_ProgramMaintenance1033{&MSSansBold8}Program Maintenance0-1256677244 IDS__IsMaintenanceDlg_Remove1033{&MSSansBold8}&Remove0-1256677244 IDS__IsMaintenanceDlg_RemoveProductName1033Remove [ProductName] from your computer.0-1256677244 IDS__IsMaintenanceDlg_Repair1033{&MSSansBold8}Re&pair0-1256677244 IDS__IsMaintenanceDlg_RepairMessage1033Repair installation errors in the program. This option fixes missing or corrupt files, shortcuts, and registry entries.0-1256677244 IDS__IsMaintenanceWelcome_MaintenanceOptionsDescription1033The InstallShield(R) Wizard will allow you to modify, repair, or remove [ProductName]. To continue, click Next.0-1256677244 IDS__IsMaintenanceWelcome_WizardWelcome1033{&TahomaBold10}Welcome to the InstallShield Wizard for [ProductName]0-1256677244 IDS__IsPatchDlg_PatchClickUpdate1033The InstallShield(R) Wizard will install the Patch for [ProductName] on your computer. To continue, click Update.0-1256677244 IDS__IsPatchDlg_PatchWizard1033[ProductName] Patch - InstallShield Wizard0-1256677244 IDS__IsPatchDlg_Update1033&Update >0-1256677244 IDS__IsPatchDlg_WelcomePatchWizard1033{&TahomaBold10}Welcome to the Patch for [ProductName]0-1256677244 IDS__IsProgressDlg_210330-1256677244 IDS__IsProgressDlg_Hidden1033(Hidden for now)0-1256677244 IDS__IsProgressDlg_HiddenTimeRemaining1033)Hidden for now)Estimated time remaining:0-1256677244 IDS__IsProgressDlg_InstallingProductName1033{&MSSansBold8}Installing [ProductName]0-1256677244 IDS__IsProgressDlg_ProgressDone1033Progress done0-1256677244 IDS__IsProgressDlg_SecHidden1033(Hidden for now)Sec.0-1256677244 IDS__IsProgressDlg_Status1033Status:0-1256677244 IDS__IsProgressDlg_Uninstalling1033{&MSSansBold8}Uninstalling [ProductName]0-1256677244 IDS__IsProgressDlg_UninstallingFeatures1033The program features you selected are being uninstalled.0-1256677244 IDS__IsProgressDlg_UninstallingFeatures21033The program features you selected are being installed.0-1256677244 IDS__IsProgressDlg_WaitUninstall1033Please wait while the InstallShield Wizard uninstalls [ProductName]. This may take several minutes.0-1256677244 IDS__IsProgressDlg_WaitUninstall21033Please wait while the InstallShield Wizard installs [ProductName]. This may take several minutes.0-1256677244 IDS__IsReadmeDlg_Cancel1033&Cancel0-1256677244 IDS__IsReadmeDlg_PleaseReadInfo1033Please read the following readme information carefully.0-1256677244 IDS__IsReadmeDlg_ReadMeInfo1033{&MSSansBold8}Readme Information0-1256677244 IDS__IsRegisterUserDlg_1610330-1256677244 IDS__IsRegisterUserDlg_Anyone1033&Anyone who uses this computer (all users)0-1256677244 IDS__IsRegisterUserDlg_CustomerInformation1033{&MSSansBold8}Customer Information0-1256677244 IDS__IsRegisterUserDlg_InstallFor1033Install this application for:0-1256677244 IDS__IsRegisterUserDlg_OnlyMe1033Only for &me ([USERNAME])0-1256677244 IDS__IsRegisterUserDlg_Organization1033&Organization:0-1256677244 IDS__IsRegisterUserDlg_PleaseEnterInfo1033Please enter your information.0-1256677244 IDS__IsRegisterUserDlg_SerialNumber1033&Serial Number:0-1256677244 IDS__IsRegisterUserDlg_Tahoma501033{\Tahoma8}{50}0-1256677244 IDS__IsRegisterUserDlg_Tahoma801033{\Tahoma8}{80}0-1256677244 IDS__IsRegisterUserDlg_UserName1033&User Name:0-1256677244 IDS__IsResumeDlg_ResumeSuspended1033The InstallShield(R) Wizard will complete the suspended installation of [ProductName] on your computer. To continue, click Next.0-1256677244 IDS__IsResumeDlg_Resuming1033{&TahomaBold10}Resuming the InstallShield Wizard for [ProductName]0-1256677244 IDS__IsResumeDlg_WizardResume1033The InstallShield(R) Wizard will complete the installation of [ProductName] on your computer. To continue, click Next.0-1256677244 IDS__IsSelectDomainOrServer1033Select a Domain or Server0-1256677244 IDS__IsSelectDomainUserInstructions1033Use the browse buttons to select a domain\server and a user name.0-1256677244 IDS__IsSetupTypeMinDlg_1310330-1256677244 IDS__IsSetupTypeMinDlg_AllFeatures1033All program features will be installed. (Requires the most disk space.)0-1256677244 IDS__IsSetupTypeMinDlg_ChooseFeatures1033Choose which program features you want installed and where they will be installed. Recommended for advanced users.0-1256677244 IDS__IsSetupTypeMinDlg_ChooseSetupType1033Choose the setup type that best suits your needs.0-1256677244 IDS__IsSetupTypeMinDlg_Complete1033{&MSSansBold8}&Complete0-1256677244 IDS__IsSetupTypeMinDlg_Custom1033{&MSSansBold8}Cu&stom0-1256677244 IDS__IsSetupTypeMinDlg_Minimal1033{&MSSansBold8}&Minimal0-1256677244 IDS__IsSetupTypeMinDlg_MinimumFeatures1033Minimum required features will be installed.0-1256677244 IDS__IsSetupTypeMinDlg_SelectSetupType1033Please select a setup type.0-1256677244 IDS__IsSetupTypeMinDlg_SetupType1033{&MSSansBold8}Setup Type0-1256677244 IDS__IsSetupTypeMinDlg_Typical1033{&MSSansBold8}&Typical0-1256677244 IDS__IsUserExit_ClickFinish1033Click Finish to exit the wizard.0-1256677244 IDS__IsUserExit_Finish1033&Finish0-1256677244 IDS__IsUserExit_KeepOrRestore1033You can either keep any existing installed elements on your system to continue this installation at a later time or you can restore your system to its original state prior to the installation.0-1256677244 IDS__IsUserExit_NotModified1033Your system has not been modified. To install this program at a later time, please run the installation again.0-1256677244 IDS__IsUserExit_RestoreOrContinue1033Click Restore or Continue Later to exit the wizard.0-1256677244 IDS__IsUserExit_WizardCompleted1033{&TahomaBold10}InstallShield Wizard Completed0-1256677244 IDS__IsUserExit_WizardInterrupted1033The wizard was interrupted before [ProductName] could be completely installed.0-1256677244 IDS__IsUserNameLabel1033&User name:0-1256677244 IDS__IsVerifyReadyDlg_BackOrCancel1033If you want to review or change any of your installation settings, click Back. Click Cancel to exit the wizard.0-1256677244 IDS__IsVerifyReadyDlg_ClickInstall1033Click Install to begin the installation.0-1256677244 IDS__IsVerifyReadyDlg_Company1033Company: [COMPANYNAME]0-1256677244 IDS__IsVerifyReadyDlg_CurrentSettings1033Current Settings:0-1256677244 IDS__IsVerifyReadyDlg_DestFolder1033Destination Folder:0-1256677244 IDS__IsVerifyReadyDlg_Install1033&Install0-1256677244 IDS__IsVerifyReadyDlg_Installdir1033[INSTALLDIR]0-1256677244 IDS__IsVerifyReadyDlg_ModifyReady1033{&MSSansBold8}Ready to Modify the Program0-1256677244 IDS__IsVerifyReadyDlg_ReadyInstall1033{&MSSansBold8}Ready to Install the Program0-1256677244 IDS__IsVerifyReadyDlg_ReadyRepair1033{&MSSansBold8}Ready to Repair the Program0-1256677244 IDS__IsVerifyReadyDlg_SelectedSetupType1033[SelectedSetupType]0-1256677244 IDS__IsVerifyReadyDlg_Serial1033Serial: [ISX_SERIALNUM]0-1256677244 IDS__IsVerifyReadyDlg_SetupType1033Setup Type:0-1256677244 IDS__IsVerifyReadyDlg_UserInfo1033User Information:0-1256677244 IDS__IsVerifyReadyDlg_UserName1033Name: [USERNAME]0-1256677244 IDS__IsVerifyReadyDlg_WizardReady1033The wizard is ready to begin installation.0-1256677244 IDS__IsVerifyRemoveAllDlg_ChoseRemoveProgram1033You have chosen to remove the program from your system.0-1256677244 IDS__IsVerifyRemoveAllDlg_ClickBack1033If you want to review or change any settings, click Back.0-1256677244 IDS__IsVerifyRemoveAllDlg_ClickRemove1033Click Remove to remove [ProductName] from your computer. After removal, this program will no longer be available for use.0-1256677244 IDS__IsVerifyRemoveAllDlg_Remove1033&Remove0-1256677244 IDS__IsVerifyRemoveAllDlg_RemoveProgram1033{&MSSansBold8}Remove the Program0-1256677244 IDS__IsWelcomeDlg_InstallProductName1033The InstallShield(R) Wizard will install [ProductName] on your computer. To continue, click Next.0-1256677244 IDS__IsWelcomeDlg_WarningCopyright1033WARNING: This program is protected by copyright law and international treaties.0-1256677244 IDS__IsWelcomeDlg_WelcomeProductName1033{&TahomaBold10}Welcome to the InstallShield Wizard for [ProductName]0-1256677244 IDS__TargetReq_DESC_COLOR1033The color settings of your system are not adequate for running [ProductName].0-1256677244 IDS__TargetReq_DESC_OS1033The operating system is not adequate for running [ProductName].0-1256677244 IDS__TargetReq_DESC_PROCESSOR1033The processor is not adequate for running [ProductName].0-1256677244 IDS__TargetReq_DESC_RAM1033The amount of RAM is not adequate for running [ProductName].0-1256677244 IDS__TargetReq_DESC_RESOLUTION1033The screen resolution is not adequate for running [ProductName].0-1256677244 ID_STRING11033http://tomcat.apache.org02115538665 ID_STRING21033DisplayName102115549418 ID_STRING31033jakarta02115510538 ID_STRING41033CoreFiles02115544011 ID_STRING51033Tomcat Isapi Redirector0161207880 ID_STRING61033See http://tomcat.apache.org/connectors-doc/0161197672 IIDS_UITEXT_FeatureUninstalled1033This feature will remain uninstalled.0-1256677244
UpgradedImage_NameMsiPathOrderFlagsIgnoreMissingFiles
UpgradeItemObjectSetupPathISReleaseFlagsISAttributes
NameMsiPathFamily
VRootKeyVRootNameVRootDirVRootPropsVRootAppNameVRootDefDocConditionSessionTimeoutScriptTimeoutAnonyUserNameAnonyPasswrdComponent_
ISIISCommonVRootObsoleteObsolete0VirtualDirComponent
VRootKeyVRootAppMapKeyExtensionExecPathVerbAppMapProps
ISIISCommon_PortIPSiteNumberWebSiteProps
ISIISCommonWebsite18010
ISXmlElementISXmlFile_ISXmlElement_ParentXPathContentISAttributes
ISXmlElementAttribISXmlElement_NameValueISAttributes
ISXmlFileFileNameComponent_DirectoryISAttributesSelectionNamespaces
Signature_ParentElementAttributeISAttributes
NameDataISBuildSourcePathISIconIndex
ARPPRODUCTICON.exe<ISProjectFolder>\tomcat.ico0
IniFileFileNameDirPropertySectionKeyValueActionComponent_
Signature_FileNameSectionKeyFieldType
ActionConditionSequenceISCommentsISAttributes
AllocateRegistrySpaceNOT Installed1550AllocateRegistrySpace AppSearch400AppSearch BindImage4300BindImage CCPSearchCCP_TEST500CCPSearch CostFinalize1000CostFinalize CostInitialize800CostInitialize CreateFolders3700CreateFolders CreateShortcuts4500CreateShortcuts DeleteServicesVersionNT2000DeleteServices DuplicateFiles4210DuplicateFiles FileCost900FileCost FindRelatedProductsNOT ISSETUPDRIVEN420FindRelatedProducts ISSelfRegisterCosting2201 ISSelfRegisterFiles5601 ISSelfRegisterFinalize6601 ISUnSelfRegisterFiles2202 InstallFiles4000InstallFiles InstallFilter4001 InstallFinalize6600InstallFinalize InstallInitialize1501InstallInitialize InstallODBC5400InstallODBC InstallServicesVersionNT5800InstallServices InstallValidate1400InstallValidate IsolateComponents950IsolateComponents LaunchConditionsNot Installed410LaunchConditions MigrateFeatureStates1200MigrateFeatureStates MoveFiles3800MoveFiles MsiPublishAssemblies6250MsiPublishAssemblies MsiUnpublishAssemblies1750MsiUnpublishAssemblies PatchFiles4090PatchFiles ProcessComponents1600ProcessComponents PublishComponents6200PublishComponents PublishFeatures6300PublishFeatures PublishProduct6400PublishProduct RMCCPSearchNot CCP_SUCCESS And CCP_TEST600RMCCPSearch RegisterClassInfo4600RegisterClassInfo RegisterComPlus5700RegisterComPlus RegisterExtensionInfo4700RegisterExtensionInfo RegisterFonts5300RegisterFonts RegisterMIMEInfo4900RegisterMIMEInfo RegisterProduct6100RegisterProduct RegisterProgIdInfo4800RegisterProgIdInfo RegisterTypeLibraries5500RegisterTypeLibraries RegisterUser6000RegisterUser RemoveDuplicateFiles3400RemoveDuplicateFiles RemoveEnvironmentStrings3300RemoveEnvironmentStrings RemoveExistingProducts1410RemoveExistingProducts RemoveFiles3500RemoveFiles RemoveFolders3600RemoveFolders RemoveIniValues3100RemoveIniValues RemoveODBC2400RemoveODBC RemoveRegistryValues2600RemoveRegistryValues RemoveShortcuts3200RemoveShortcuts ScheduleRebootISSCHEDULEREBOOT6410ScheduleReboot SelfRegModules5600SelfRegModules SelfUnregModules2200SelfUnregModules SetARPINSTALLLOCATIONNot Installed1010SetARPINSTALLLOCATION SetODBCFolders1100SetODBCFolders StartServicesVersionNT5900StartServices StopServicesVersionNT1900StopServices UnpublishComponents1700UnpublishComponents UnpublishFeatures1800UnpublishFeatures UnregisterClassInfo2700UnregisterClassInfo UnregisterComPlus2100UnregisterComPlus UnregisterExtensionInfo2800UnregisterExtensionInfo UnregisterFonts2500UnregisterFonts UnregisterMIMEInfo3000UnregisterMIMEInfo UnregisterProgIdInfo2900UnregisterProgIdInfo UnregisterTypeLibraries2300UnregisterTypeLibraries ValidateProductID700ValidateProductID WriteEnvironmentStrings5200WriteEnvironmentStrings WriteIniValues5100WriteIniValues WriteRegistryValues5000WriteRegistryValues caCreateVRoots4002 caExtractIISSuppFiles1500 caIISCleanup6602 caRemoveVRoots3503 caRlbackVRoots3502
PropertyValue
ActiveLanguage1033 Comments CurrentMedia TQBzAGkAAQBSAGUAbABlAGEAcwBlAA== ISCompilerOption_CompileBeforeBuild1 ISCompilerOption_Debug0 ISCompilerOption_IncludePath ISCompilerOption_MaxErrors50 ISCompilerOption_MaxWarnings50 ISCompilerOption_OutputPath<ISProjectDataFolder>\Script Files ISCompilerOption_PreProcessor ISCompilerOption_WarningLevel3 ISCompilerOption_WarningsAsErrors1 ISDialogLangID ISUSLock{3872C0E8-6909-4854-B023-A63C791DEF8B} ISUSSignature{33FEE5F9-7895-4F44-87E1-D98785707659} IsProjectFileText1 MsiExecCmdLineOptions MsiLogFile OnUpgrade1 OwnerMladen Turk PatchFamilyMyPatchFamily1 PatchSequence1.0.0 SaveAsSchema SccEnabled0 SccPath SchemaVersion763 TypeMSI
ActionConditionSequenceISCommentsISAttributes
AppSearch400AppSearch CCPSearchCCP_TEST500CCPSearch CostFinalize1000CostFinalize CostInitialize800CostInitialize ExecuteAction1300ExecuteAction FileCost900FileCost FindRelatedProducts430FindRelatedProducts InstallWelcomeNot Installed And (Not PATCH Or IS_MAJOR_UPGRADE)1210InstallWelcome IsolateComponents950IsolateComponents LaunchConditionsNot Installed410LaunchConditions MaintenanceWelcomeInstalled And Not RESUME And Not Preselected And Not PATCH1230MaintenanceWelcome MigrateFeatureStates1200MigrateFeatureStates PatchWelcomePATCH And Not IS_MAJOR_UPGRADE1205Patch Panel RMCCPSearchNot CCP_SUCCESS And CCP_TEST600RMCCPSearch ResolveSourceNot Installed And Not PATCH990ResolveSource SetAllUsersProfileNTVersionNT = 400970 SetupCompleteError-3SetupCompleteError SetupCompleteSuccess-1SetupCompleteSuccess SetupInitialization420SetupInitialization SetupInterrupted-2SetupInterrupted SetupProgress1240SetupProgress SetupResumeInstalled And (RESUME Or Preselected) And Not PATCH1220SetupResume ValidateProductID700ValidateProductID setAllUsersProfile2KVersionNT >= 500980 setUserProfileNTVersionNT960
Component_SharedComponent_Application
ConditionDescription
(Not Version9X)##IDPROP_EXPRESS_LAUNCH_CONDITION_OS##
PropertyOrderValueText
IS_SQLSERVER_LIST1TestValue
PropertyOrderValueTextBinary_
LockObjectTableDomainUserPermission
ContentTypeExtension_CLSID
DiskIdLastSequenceDiskPromptCabinetVolumeLabelSource
FileKeyComponent_SourceNameDestNameSourceFolderDestFolderOptions
Component_Feature_File_ManifestFile_ApplicationAttributes
Component_NameValue
DigitalCertificateCertData
TableSignObjectDigitalCertificate_Hash
ComponentFlagsSequenceReferenceComponents
File_OptionsHashPart1HashPart2HashPart3HashPart4
PatchCertificateDigitalCertificate_
PatchConfiguration_CompanyPropertyValue
File_Assembly_
Assembly_NameValue
PatchConfiguration_PatchFamilyTargetSequenceSupersede
Driver_AttributeValue
DataSourceComponent_DescriptionDriverDescriptionRegistration
DriverComponent_DescriptionFile_File_Setup
DataSource_AttributeValue
TranslatorComponent_DescriptionFile_File_Setup
File_SequencePatchSizeAttributesHeaderISBuildSourcePath
PatchIdMedia_
ProgIdProgId_ParentClass_DescriptionIcon_IconIndexISAttributes
PropertyValueISComments
ARPPRODUCTICONARPPRODUCTICON.exe ARPURLINFOABOUT##ID_STRING1## AgreeToLicenseNo ApplicationUsersAllUsers DWUSINTERVAL30 DWUSLINKCEAC2798B9CCC7BFDEAC879F5E6C978F29BC978F69DCE0AFCEFC673F895C57EF898B905F79AC DefaultUIFontTahoma8 DialogCaptionInstallShield for Windows Installer DiskPrompt[1] DisplayNameCustom##IDS__DisplayName_Custom## DisplayNameMinimal##IDS__DisplayName_Minimal## DisplayNameTypical##IDS__DisplayName_Typical## Display_IsBitmapDlg1 ErrorDialogSetupError INSTALLLEVEL100 ISCHECKFORPRODUCTUPDATES1 ISENABLEDWUSFINISHDIALOG ISVROOT_PORT_NO0 IS_COMPLUS_PROGRESSTEXT_COST##IDS_COMPLUS_PROGRESSTEXT_COST## IS_COMPLUS_PROGRESSTEXT_INSTALL##IDS_COMPLUS_PROGRESSTEXT_INSTALL## IS_COMPLUS_PROGRESSTEXT_UNINSTALL##IDS_COMPLUS_PROGRESSTEXT_UNINSTALL## IS_PROGMSG_XML_COSTING##IDS_PROGMSG_XML_COSTING## IS_PROGMSG_XML_CREATE_FILE##IDS_PROGMSG_XML_CREATE_FILE## IS_PROGMSG_XML_FILES##IDS_PROGMSG_XML_FILES## IS_PROGMSG_XML_REMOVE_FILE##IDS_PROGMSG_XML_REMOVE_FILE## IS_PROGMSG_XML_ROLLBACK_FILES##IDS_PROGMSG_XML_ROLLBACK_FILES## IS_PROGMSG_XML_UPDATE_FILE##IDS_PROGMSG_XML_UPDATE_FILE## IS_SQLSERVER_AUTHENTICATION0 IS_SQLSERVER_DATABASE IS_SQLSERVER_PASSWORD IS_SQLSERVER_SERVER IS_SQLSERVER_USERNAMEsa InstallChoiceAR Manufacturer##COMPANY_NAME## PIDTemplate12345<###-%%%%%%%>@@@@@ PROGMSG_IIS_CREATEAPPPOOL##IDS_PROGMSG_IIS_CREATEAPPPOOL## PROGMSG_IIS_CREATEAPPPOOLS##IDS_PROGMSG_IIS_CREATEAPPPOOLS## PROGMSG_IIS_CREATEVROOT##IDS_PROGMSG_IIS_CREATEVROOT## PROGMSG_IIS_CREATEVROOTS##IDS_PROGMSG_IIS_CREATEVROOTS## PROGMSG_IIS_CREATEWEBSERVICEEXTENSION##IDS_PROGMSG_IIS_CREATEWEBSERVICEEXTENSION## PROGMSG_IIS_CREATEWEBSERVICEEXTENSIONS##IDS_PROGMSG_IIS_CREATEWEBSERVICEEXTENSIONS## PROGMSG_IIS_EXTRACT##IDS_PROGMSG_IIS_EXTRACT## PROGMSG_IIS_EXTRACTDONE##IDS_PROGMSG_IIS_EXTRACTDONE## PROGMSG_IIS_REMOVEAPPPOOL##IDS_PROGMSG_IIS_REMOVEAPPPOOL## PROGMSG_IIS_REMOVEAPPPOOLS##IDS_PROGMSG_IIS_REMOVEAPPPOOLS## PROGMSG_IIS_REMOVESITE##IDS_PROGMSG_IIS_REMOVESITE## PROGMSG_IIS_REMOVEVROOT##IDS_PROGMSG_IIS_REMOVEVROOT## PROGMSG_IIS_REMOVEVROOTS##IDS_PROGMSG_IIS_REMOVEVROOTS## PROGMSG_IIS_REMOVEWEBSERVICEEXTENSION##IDS_PROGMSG_IIS_REMOVEWEBSERVICEEXTENSION## PROGMSG_IIS_REMOVEWEBSERVICEEXTENSIONS##IDS_PROGMSG_IIS_REMOVEWEBSERVICEEXTENSIONS## PROGMSG_IIS_ROLLBACKAPPPOOLS##IDS_PROGMSG_IIS_ROLLBACKAPPPOOLS## PROGMSG_IIS_ROLLBACKVROOTS##IDS_PROGMSG_IIS_ROLLBACKVROOTS## PROGMSG_IIS_ROLLBACKWEBSERVICEEXTENSIONS##IDS_PROGMSG_IIS_ROLLBACKWEBSERVICEEXTENSIONS## ProductCode{8B799ADD-7E5C-41B9-936B-942F3CAE42A0} ProductIDnone ProductLanguage1033 ProductNameTomcat Isapi Redirector ProductVersion1.2.41 ProgressType0install ProgressType1Installing ProgressType2installed ProgressType3installs RebootYesNoYes ReinstallModeTextomus SHOWLAUNCHPROGRAM0 SetupTypeTypical UpgradeCode{0BE8FA4C-503F-4209-A3DA-79B605E542E0} _IsMaintenanceChange _IsSetupTypeMinTypical
ComponentIdQualifierComponent_AppDataFeature_
PropertyOrderValueXYWidthHeightTextHelpISControlId
AgreeToLicense1No01529115##IDS__AgreeToLicense_0## AgreeToLicense2Yes0029115##IDS__AgreeToLicense_1## ApplicationUsers1AllUsers1729014##IDS__IsRegisterUserDlg_Anyone## ApplicationUsers2OnlyCurrentUser12329014##IDS__IsRegisterUserDlg_OnlyMe## IS_SQLSERVER_AUTHENTICATION100032714##IDS_SQLLOGIN_WIN##0 IS_SQLSERVER_AUTHENTICATION2101432719##IDS_SQLLOGIN_SQL##0 _IsMaintenance1Change0029014##IDS__IsMaintenanceDlg_Modify## _IsMaintenance2Reinstall06029014##IDS__IsMaintenanceDlg_Repair## _IsMaintenance3Remove012029014##IDS__IsMaintenanceDlg_Remove## _IsSetupTypeMin1Typical0026414##IDS__IsSetupTypeMinDlg_Complete## _IsSetupTypeMin2Custom06026414##IDS__IsSetupTypeMinDlg_Custom##
Signature_RootKeyNameType
_IISROOTFOLDER2Software\Microsoft\InetStpPathWWWRoot0 _IIS_VERSION2SYSTEM\CurrentControlSet\Services\W3SVC\ParametersMajorVersion2
RegistryRootKeyNameValueComponent_ISAttributes
Registry12SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0rewrite_rule_file[INSTALLDIR]conf\rewrite.propertiesISRegistryComponent10 Registry102SOFTWARE\Apache Software FoundationISRegistryComponent10 Registry112SOFTWARE\Apache Software Foundation\Jakarta Isapi RedirectorISRegistryComponent10 Registry122SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0ISRegistryComponent10 Registry132SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0extension_uri/jakarta/isapi_redirect.dllISRegistryComponent10 Registry142SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0log_file[INSTALLDIR]log\isapi_redirect.logISRegistryComponent10 Registry152SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0log_levelinfoISRegistryComponent10 Registry162SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0worker_file[INSTALLDIR]conf\workers.propertiesISRegistryComponent10 Registry172SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0worker_mount_file[INSTALLDIR]conf\uriworkermap.propertiesISRegistryComponent10
FileKeyComponent_FileNameDirPropertyInstallMode
RemoveIniFileFileNameDirPropertySectionKeyValueActionComponent_
RemoveRegistryRootKeyNameComponent_
ReserveKeyComponent_ReserveFolderReserveLocalReserveSource
SFPCatalogCatalogDependency
File_Cost
ServiceControlNameEventArgumentsWaitComponent_
ServiceInstallNameDisplayNameServiceTypeStartTypeErrorControlLoadOrderGroupDependenciesStartNamePasswordArgumentsComponent_Description
ShortcutDirectory_NameComponent_TargetArgumentsDescriptionHotkeyIcon_IconIndexShowCmdWkDirISCommentsISShortcutNameISAttributes
SignatureFileNameMinVersionMaxVersionMinSizeMaxSizeMinDateMaxDateLanguages
TextStyleFaceNameSizeColorStyleBits
Arial8Arial8 Arial9Arial9 ArialBlue10Arial1016711680 ArialBlueStrike10Arial10167116808 CourierNew8Courier New8 CourierNew9Courier New9 MSGothic9MS Gothic9 MSSGreySerif8MS Sans Serif88421504 MSSWhiteSerif8Tahoma816777215 MSSansBold8Tahoma81 MSSansSerif8MS Sans Serif8 MSSansSerif9MS Sans Serif9 Tahoma10Tahoma10 Tahoma8Tahoma8 Tahoma9Tahoma9 TahomaBold10Tahoma101 TahomaBold8Tahoma81 Times8Times New Roman8 Times9Times New Roman9 TimesItalic12Times New Roman122 TimesItalicBlue10Times New Roman10167116802 TimesRed16Times New Roman16255
LibIDLanguageComponent_VersionDescriptionDirectory_Feature_Cost
KeyText
AbsentPath GB##IDS_UITEXT_GB## KB##IDS_UITEXT_KB## MB##IDS_UITEXT_MB## MenuAbsent##IDS_UITEXT_FeatureNotAvailable## MenuAdvertise##IDS_UITEXT_FeatureInstalledWhenRequired2## MenuAllCD##IDS_UITEXT_FeatureInstalledCD## MenuAllLocal##IDS_UITEXT_FeatureInstalledLocal## MenuAllNetwork##IDS_UITEXT_FeatureInstalledNetwork## MenuCD##IDS_UITEXT_FeatureInstalledCD2## MenuLocal##IDS_UITEXT_FeatureInstalledLocal2## MenuNetwork##IDS_UITEXT_FeatureInstalledNetwork2## NewFolder##IDS_UITEXT_Folder## SelAbsentAbsent##IDS_UITEXT_GB## SelAbsentAdvertise##IDS_UITEXT_FeatureInstalledWhenRequired## SelAbsentCD##IDS_UITEXT_FeatureOnCD## SelAbsentLocal##IDS_UITEXT_FeatureLocal## SelAbsentNetwork##IDS_UITEXT_FeatureNetwork## SelAdvertiseAbsent##IDS_UITEXT_FeatureUnavailable## SelAdvertiseAdvertise##IDS_UITEXT_FeatureInstalledRequired## SelAdvertiseCD##IDS_UITEXT_FeatureOnCD2## SelAdvertiseLocal##IDS_UITEXT_FeatureLocal2## SelAdvertiseNetwork##IDS_UITEXT_FeatureNetwork2## SelCDAbsent##IDS_UITEXT_FeatureWillBeUninstalled## SelCDAdvertise##IDS_UITEXT_FeatureWasCD## SelCDCD##IDS_UITEXT_FeatureRunFromCD## SelCDLocal##IDS_UITEXT_FeatureWasCDLocal## SelChildCostNeg##IDS_UITEXT_FeatureFreeSpace## SelChildCostPos##IDS_UITEXT_FeatureRequiredSpace## SelCostPending##IDS_UITEXT_CompilingFeaturesCost## SelLocalAbsent##IDS_UITEXT_FeatureCompletelyRemoved## SelLocalAdvertise##IDS_UITEXT_FeatureRemovedUnlessRequired## SelLocalCD##IDS_UITEXT_FeatureRemovedCD## SelLocalLocal##IDS_UITEXT_FeatureRemainLocal## SelLocalNetwork##IDS_UITEXT_FeatureRemoveNetwork## SelNetworkAbsent##IDS_UITEXT_FeatureUninstallNoNetwork## SelNetworkAdvertise##IDS_UITEXT_FeatureWasOnNetworkInstalled## SelNetworkLocal##IDS_UITEXT_FeatureWasOnNetworkLocal## SelNetworkNetwork##IDS_UITEXT_FeatureContinueNetwork## SelParentCostNegNeg##IDS_UITEXT_FeatureSpaceFree## SelParentCostNegPos##IDS_UITEXT_FeatureSpaceFree2## SelParentCostPosNeg##IDS_UITEXT_FeatureSpaceFree3## SelParentCostPosPos##IDS_UITEXT_FeatureSpaceFree4## TimeRemaining##IDS_UITEXT_TimeRemaining## VolumeCostAvailable##IDS_UITEXT_Available## VolumeCostDifference##IDS_UITEXT_Differences## VolumeCostRequired##IDS_UITEXT_Required## VolumeCostSize##IDS_UITEXT_DiskSize## VolumeCostVolume##IDS_UITEXT_Volume## bytes##IDS_UITEXT_Bytes##
UpgradeCodeVersionMinVersionMaxLanguageAttributesRemoveActionPropertyISDisplayName
Extension_VerbSequenceCommandArgument
TableColumnNullableMinValueMaxValueKeyTableKeyColumnCategorySetDescription
ActionTextActionNIdentifierName of action to be described. ActionTextDescriptionYTextLocalized description displayed in progress dialog and log when action is executing. ActionTextTemplateYTemplateOptional localized format template used to format action data records for display during action execution. AdminExecuteSequenceActionNIdentifierName of action to invoke, either in the engine or the handler DLL. AdminExecuteSequenceConditionYTextOptional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData. AdminExecuteSequenceISAttributesYThis is used to store MM Custom Action Types AdminExecuteSequenceISCommentsYTextAuthor’s comments on this Sequence. AdminExecuteSequenceSequenceY-432767Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action. AdminUISequenceActionNIdentifierName of action to invoke, either in the engine or the handler DLL. AdminUISequenceConditionYTextOptional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData. AdminUISequenceISAttributesYThis is used to store MM Custom Action Types AdminUISequenceISCommentsYTextAuthor’s comments on this Sequence. AdminUISequenceSequenceY-432767Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action. AdvtExecuteSequenceActionNIdentifierName of action to invoke, either in the engine or the handler DLL. AdvtExecuteSequenceConditionYTextOptional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData. AdvtExecuteSequenceISAttributesYThis is used to store MM Custom Action Types AdvtExecuteSequenceISCommentsYTextAuthor’s comments on this Sequence. AdvtExecuteSequenceSequenceY-432767Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action. AdvtUISequenceActionNIdentifierName of action to invoke, either in the engine or the handler DLL. AdvtUISequenceConditionYTextOptional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData. AdvtUISequenceISAttributesYThis is used to store MM Custom Action Types AdvtUISequenceISCommentsYTextAuthor’s comments on this Sequence. AdvtUISequenceSequenceY-432767Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action. AppIdActivateAtStorageY01 AppIdAppIdNGuid AppIdDllSurrogateYText AppIdLocalServiceYText AppIdRemoteServerNameYFormatted AppIdRunAsInteractiveUserY01 AppIdServiceParametersYText AppSearchPropertyNIdentifierThe property associated with a Signature AppSearchSignature_NISXmlLocator;Signature1IdentifierThe Signature_ represents a unique file signature and is also the foreign key in the Signature, RegLocator, IniLocator, CompLocator and the DrLocator tables. BBControlAttributesY02147483647A 32-bit word that specifies the attribute flags to be applied to this control. BBControlBBControlNIdentifierName of the control. This name must be unique within a billboard, but can repeat on different billboard. BBControlBillboard_NBillboard1IdentifierExternal key to the Billboard table, name of the billboard. BBControlHeightN032767Height of the bounding rectangle of the control. BBControlTextYTextA string used to set the initial text contained within a control (if appropriate). BBControlTypeNIdentifierThe type of the control. BBControlWidthN032767Width of the bounding rectangle of the control. BBControlXN032767Horizontal coordinate of the upper left corner of the bounding rectangle of the control. BBControlYN032767Vertical coordinate of the upper left corner of the bounding rectangle of the control. BillboardActionYIdentifierThe name of an action. The billboard is displayed during the progress messages received from this action. BillboardBillboardNIdentifierName of the billboard. BillboardFeature_NFeature1IdentifierAn external key to the Feature Table. The billboard is shown only if this feature is being installed. BillboardOrderingY032767A positive integer. If there is more than one billboard corresponding to an action they will be shown in the order defined by this column. BinaryDataYBinaryBinary stream. The binary icon data in PE (.DLL or .EXE) or icon (.ICO) format. BinaryISBuildSourcePathYTextFull path to the ICO or EXE file. BinaryNameNIdentifierUnique key identifying the binary data. BindImageFile_NFile1IdentifierThe index into the File table. This must be an executable file. BindImagePathYPathsA list of ; delimited paths that represent the paths to be searched for the import DLLS. The list is usually a list of properties each enclosed within square brackets [] . CCPSearchSignature_NSignature1IdentifierThe Signature_ represents a unique file signature and is also the foreign key in the Signature, RegLocator, IniLocator, CompLocator and the DrLocator tables. CheckBoxPropertyNIdentifierA named property to be tied to the item. CheckBoxValueYFormattedThe value string associated with the item. ClassAppId_YAppId1GuidOptional AppID containing DCOM information for associated application (string GUID). ClassArgumentYFormattedoptional argument for LocalServers. ClassAttributesY32767Class registration attributes. ClassCLSIDNGuidThe CLSID of an OLE factory. ClassComponent_NComponent1IdentifierRequired foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent. ClassContextNIdentifierThe numeric server context for this server. CLSCTX_xxxx ClassDefInprocHandlerYText1;2;3Optional default inproc handler. Only optionally provided if Context=CLSCTX_LOCAL_SERVER. Typically "ole32.dll" or "mapi32.dll" ClassDescriptionYTextLocalized description for the Class. ClassFeature_NFeature1IdentifierRequired foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational. ClassFileTypeMaskYTextOptional string containing information for the HKCRthis CLSID) key. If multiple patterns exist, they must be delimited by a semicolon, and numeric subkeys will be generated: 0,1,2... ClassIconIndexY-3276732767Optional icon index. ClassIcon_YIcon1IdentifierOptional foreign key into the Icon Table, specifying the icon file associated with this CLSID. Will be written under the DefaultIcon key. ClassProgId_DefaultYProgId1TextOptional ProgId associated with this CLSID. ComboBoxOrderN132767A positive integer used to determine the ordering of the items within one list. The integers do not have to be consecutive. ComboBoxPropertyNIdentifierA named property to be tied to this item. All the items tied to the same property become part of the same combobox. ComboBoxTextYFormattedThe visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value. ComboBoxValueNFormattedThe value string associated with this item. Selecting the line will set the associated property to this value. CompLocatorComponentIdNGuidA string GUID unique to this component, version, and language. CompLocatorSignature_NSignature1IdentifierThe table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table. CompLocatorTypeY01A boolean value that determines if the registry value is a filename or a directory location. ComplusComponent_NComponent1IdentifierForeign key referencing Component that controls the ComPlus component. ComplusExpTypeY032767ComPlus component attributes. ComponentAttributesNRemote execution option, one of irsEnum ComponentComponentNIdentifierPrimary key used to identify a particular component record. ComponentComponentIdYGuidA string GUID unique to this component, version, and language. ComponentConditionYConditionA conditional statement that will disable this component if the specified condition evaluates to the 'True' state. If a component is disabled, it will not be installed, regardless of the 'Action' state associated with the component. ComponentDirectory_NDirectory1IdentifierRequired key of a Directory table record. This is actually a property name whose value contains the actual path, set either by the AppSearch action or with the default setting obtained from the Directory table. ComponentISAttributesYThis is used to store Installshield custom properties of a component. ComponentISCommentsYTextUser Comments. ComponentISDotNetInstallerArgsCommitYTextArguments passed to the key file of the component if if implements the .NET Installer class ComponentISDotNetInstallerArgsInstallYTextArguments passed to the key file of the component if if implements the .NET Installer class ComponentISDotNetInstallerArgsRollbackYTextArguments passed to the key file of the component if if implements the .NET Installer class ComponentISDotNetInstallerArgsUninstallYTextArguments passed to the key file of the component if if implements the .NET Installer class ComponentISRegFileToMergeAtBuildYTextPath and File name of a .REG file to merge into the component at build time. ComponentISScanAtBuildFileYTextFile used by the Dot Net scanner to populate dependant assemblies' File_Application field. ComponentKeyPathYFile;ODBCDataSource;Registry1IdentifierEither the primary key into the File table, Registry table, or ODBCDataSource table. This extract path is stored when the component is installed, and is used to detect the presence of the component and to return the path to it. ConditionConditionYConditionExpression evaluated to determine if Level in the Feature table is to change. ConditionFeature_NFeature1IdentifierReference to a Feature entry in Feature table. ConditionLevelN032767New selection Level to set in Feature table if Condition evaluates to TRUE. ControlAttributesY02147483647A 32-bit word that specifies the attribute flags to be applied to this control. ControlBinary_YBinary1IdentifierExternal key to the Binary table. ControlControlNIdentifierName of the control. This name must be unique within a dialog, but can repeat on different dialogs. ControlControl_NextYControl2IdentifierThe name of an other control on the same dialog. This link defines the tab order of the controls. The links have to form one or more cycles! ControlDialog_NDialog1IdentifierExternal key to the Dialog table, name of the dialog. ControlHeightN032767Height of the bounding rectangle of the control. ControlHelpYTextThe help strings used with the button. The text is optional. ControlISBuildSourcePathYTextFull path to .rtf file for scrollable text control ControlISControlIdYA number used to represent the control ID of the Control, Used in Dialog export ControlISWindowStyleY02147483647A 32-bit word that specifies non-MSI window styles to be applied to this control. ControlPropertyYIdentifierThe name of a defined property to be linked to this control. ControlTextYFormattedA string used to set the initial text contained within a control (if appropriate). ControlTypeNIdentifierThe type of the control. ControlWidthN032767Width of the bounding rectangle of the control. ControlXN032767Horizontal coordinate of the upper left corner of the bounding rectangle of the control. ControlYN032767Vertical coordinate of the upper left corner of the bounding rectangle of the control. ControlConditionActionNDefault;Disable;Enable;Hide;ShowThe desired action to be taken on the specified control. ControlConditionConditionNConditionA standard conditional statement that specifies under which conditions the action should be triggered. ControlConditionControl_NControl2IdentifierA foreign key to the Control table, name of the control. ControlConditionDialog_NDialog1IdentifierA foreign key to the Dialog table, name of the dialog. ControlEventArgumentNFormattedA value to be used as a modifier when triggering a particular event. ControlEventConditionYConditionA standard conditional statement that specifies under which conditions an event should be triggered. ControlEventControl_NControl2IdentifierA foreign key to the Control table, name of the control ControlEventDialog_NDialog1IdentifierA foreign key to the Dialog table, name of the dialog. ControlEventEventNFormattedAn identifier that specifies the type of the event that should take place when the user interacts with control specified by the first two entries. ControlEventOrderingY02147483647An integer used to order several events tied to the same control. Can be left blank. CreateFolderComponent_NComponent1IdentifierForeign key into the Component table. CreateFolderDirectory_NDirectory1IdentifierPrimary key, could be foreign key into the Directory table. CustomActionActionNIdentifierPrimary key, name of action, normally appears in sequence table unless private use. CustomActionISCommentsYTextAuthor’s comments for this custom action. CustomActionSourceYCustomSourceThe table reference of the source of the code. CustomActionTargetYISDLLWrapper;ISInstallScriptAction1FormattedExcecution parameter, depends on the type of custom action CustomActionTypeN132767The numeric custom action type, consisting of source location, code type, entry, option flags. DialogAttributesY02147483647A 32-bit word that specifies the attribute flags to be applied to this dialog. DialogControl_CancelYControl2IdentifierDefines the cancel control. Hitting escape or clicking on the close icon on the dialog is equivalent to pushing this button. DialogControl_DefaultYControl2IdentifierDefines the default control. Hitting return is equivalent to pushing this button. DialogControl_FirstNControl2IdentifierDefines the control that has the focus when the dialog is created. DialogDialogNIdentifierName of the dialog. DialogHCenteringN0100Horizontal position of the dialog on a 0-100 scale. 0 means left end, 100 means right end of the screen, 50 center. DialogHeightN032767Height of the bounding rectangle of the dialog. DialogISCommentsYTextAuthor’s comments for this dialog. DialogISResourceIdYA Number the Specifies the Dialog ID to be used in Dialog Export DialogISWindowStyleYA 32-bit word that specifies non-MSI window styles to be applied to this control. This is only used in Script Based Setups. DialogTextStyle_YIdentifierForeign Key into TextStyle table, only used in Script Based Projects. DialogTitleYFormattedA text string specifying the title to be displayed in the title bar of the dialog's window. DialogVCenteringN0100Vertical position of the dialog on a 0-100 scale. 0 means top end, 100 means bottom end of the screen, 50 center. DialogWidthN032767Width of the bounding rectangle of the dialog. DirectoryDefaultDirNTextThe default sub-path under parent's path. DirectoryDirectoryNIdentifierUnique identifier for directory entry, primary key. If a property by this name is defined, it contains the full path to the directory. DirectoryDirectory_ParentYDirectory1IdentifierReference to the entry in this table specifying the default parent directory. A record parented to itself or with a Null parent represents a root of the install tree. DirectoryISAttributesY0;1;2;3;4;5;6;7This is used to store Installshield custom properties of a directory. Currently the only one is Shortcut. DirectoryISDescriptionYTextDescription of folder DirectoryISFolderNameYTextThis is used in Pro projects because the pro identifier used in the tree wasn't necessarily unique. DrLocatorDepthY032767The depth below the path to which the Signature_ is recursively searched. If absent, the depth is assumed to be 0. DrLocatorParentYIdentifierThe parent file signature. It is also a foreign key in the Signature table. If null and the Path column does not expand to a full path, then all the fixed drives of the user system are searched using the Path. DrLocatorPathYAnyPathThe path on the user system. This is a either a subpath below the value of the Parent or a full path. The path may contain properties enclosed within [ ] that will be expanded. DrLocatorSignature_NSignature1IdentifierThe Signature_ represents a unique file signature and is also the foreign key in the Signature table. DuplicateFileComponent_NComponent1IdentifierForeign key referencing Component that controls the duplicate file. DuplicateFileDestFolderYIdentifierName of a property whose value is assumed to resolve to the full pathname to a destination folder. DuplicateFileDestNameYTextFilename to be given to the duplicate file. DuplicateFileFileKeyNIdentifierPrimary key used to identify a particular file entry DuplicateFileFile_NFile1IdentifierForeign key referencing the source file to be duplicated. EnvironmentComponent_NComponent1IdentifierForeign key into the Component table referencing component that controls the installing of the environmental value. EnvironmentEnvironmentNIdentifierUnique identifier for the environmental variable setting EnvironmentNameNTextThe name of the environmental value. EnvironmentValueYFormattedThe value to set in the environmental settings. ErrorErrorN032767Integer error number, obtained from header file IError(...) macros. ErrorMessageYTemplateError formatting template, obtained from user ed. or localizers. EventMappingAttributeNIdentifierThe name of the control attribute, that is set when this event is received. EventMappingControl_NControl2IdentifierA foreign key to the Control table, name of the control. EventMappingDialog_NDialog1IdentifierA foreign key to the Dialog table, name of the Dialog. EventMappingEventNIdentifierAn identifier that specifies the type of the event that the control subscribes to. ExtensionComponent_NComponent1IdentifierRequired foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent. ExtensionExtensionNTextThe extension associated with the table row. ExtensionFeature_NFeature1IdentifierRequired foreign key into the Feature Table, specifying the feature to validate or install in order for the CLSID factory to be operational. ExtensionMIME_YMIME1TextOptional Context identifier, typically "type/format" associated with the extension ExtensionProgId_YProgId1TextOptional ProgId associated with this extension. FeatureAttributesN0;1;2;4;5;6;8;9;10;16;17;18;20;21;22;24;25;26;32;33;34;36;37;38;48;49;50;52;53;54Feature attributes FeatureDescriptionYTextLonger descriptive text describing a visible feature item. FeatureDirectory_YDirectory1UpperCaseThe name of the Directory that can be configured by the UI. A non-null value will enable the browse button. FeatureDisplayY032767Numeric sort order, used to force a specific display ordering. FeatureFeatureNIdentifierPrimary key used to identify a particular feature record. FeatureFeature_ParentYFeature1IdentifierOptional key of a parent record in the same table. If the parent is not selected, then the record will not be installed. Null indicates a root item. FeatureISCommentsYComments FeatureISFeatureCabNameYName of CAB used when compressing CABs by Feature. Used to override build generated name for CAB file. FeatureISProFeatureNameYTextThe name of the feature used by pro projects. This doesn't have to be unique. FeatureISReleaseFlagsYRelease Flags that specify whether this feature will be built in a particular release. FeatureLevelN032767The install level at which record will be initially selected. An install level of 0 will disable an item and prevent its display. FeatureTitleYTextShort text identifying a visible feature item. FeatureComponentsComponent_NComponent1IdentifierForeign key into Component table. FeatureComponentsFeature_NFeature1IdentifierForeign key into Feature table. FileAttributesY032767Integer containing bit flags representing file attributes (with the decimal value of each bit position in parentheses) FileComponent_NComponent1IdentifierForeign key referencing Component that controls the file. FileFileNIdentifierPrimary key, non-localized token, must match identifier in cabinet. For uncompressed files, this field is ignored. FileFileNameNTextFile name used for installation. This may contain a "short name|long name" pair. It may be just a long name, hence it cannot be of the Filename data type. FileFileSizeN02147483647Size of file in bytes (long integer). FileISAttributesY02147483647This field contains the following attributes: UseSystemSettings(0x1) FileISBuildSourcePathYTextFull path, the category is of Text instead of Path because of potential use of path variables. FileISComponentSubFolder_YIdentifierForeign key referencing component subfolder containing this file. Only for Pro. FileLanguageYLanguageList of decimal language Ids, comma-separated if more than one. FileSequenceN132767Sequence with respect to the media images; order must track cabinet order. FileVersionYFile1VersionVersion string for versioned files; Blank for unversioned files. FileSFPCatalogFile_NFile1IdentifierFile associated with the catalog FileSFPCatalogSFPCatalog_NSFPCatalog1TextCatalog associated with the file FontFile_NFile1IdentifierPrimary key, foreign key into File table referencing font file. FontFontTitleYTextFont name. ISAssistantTagDataY ISAssistantTagTagN ISCEAppAppKeyN ISCEAppAppNameN ISCEAppAttributesY ISCEAppCompanyNameN ISCEAppComponent_YComponent1 ISCEAppDefDirN ISCEAppDeleteMediaN ISCEAppDescriptionY ISCEAppDesktopTargetDirN ISCEAppDeviceFileY ISCEAppIconIndexY ISCEAppIconPathY ISCEAppInstallNetCFY ISCEAppInstallSQLClientY ISCEAppInstallSQLDevY ISCEAppInstallSQLServerY ISCEAppNoUninstallY ISCEAppPVKFileY ISCEAppPostXMLY ISCEAppPreXMLY ISCEAppRawDeviceFileY ISCEAppSPCFileY ISCEDirAppKeyN ISCEDirDirKeyN ISCEDirDirParentN ISCEDirDirValueN ISCEFileAdvancedOptionsY ISCEFileAppKeyN ISCEFileCopyOptionN ISCEFileDestinationN ISCEFileFileKeyN ISCEFileFileOptionN ISCEFileNameN ISCEFilePlatformN ISCEFileProcessorN ISCEFileSourceN ISCEFileExtAppKeyN ISCEFileExtDescriptionY ISCEFileExtExtKeyN ISCEFileExtExtensionN ISCEFileExtFileKeyN ISCEFileExtIconIndexN ISCEInstallCEAppNameN ISCEInstallCECabsN ISCEInstallCEDesktopDirN ISCEInstallCEIcoFileN ISCEInstallCEIniFileKeyN ISCEInstallCEInstallKeyN ISCEInstallComponent_Y ISCEInstallDeleteMediaN ISCEOtherAppCABsAppKeyN ISCEOtherAppCABsBuildSourcePathN ISCEOtherAppCABsFileKeyN ISCERegistryAppKeyN ISCERegistryKeyN ISCERegistryNameY ISCERegistryOverwriteN ISCERegistryPlatformN ISCERegistryProcessorN ISCERegistryRegKeyN ISCERegistryRootN ISCERegistryValueY ISCESetupFileAppKeyN ISCESetupFileNameN ISCESetupFilePlatformN ISCESetupFileProcessorN ISCESetupFileSetupFileKeyN ISCESetupFileSourceN ISCEShtCutAppKeyN ISCEShtCutDestinationN ISCEShtCutDisplayNameN ISCEShtCutPlatformN ISCEShtCutShtCutKeyN ISCEShtCutTargetN ISComCatalogAttributeISComCatalogObject_NISComCatalogObject1IdentifierForeign key into the ISComCatalogObject table. ISComCatalogAttributeItemNameNTextThe named attribute for a catalog object. ISComCatalogAttributeItemValueYTextA value associated with the attribute defined in the ItemName column. ISComCatalogCollectionCollectionNameNTextA catalog collection name. ISComCatalogCollectionISComCatalogCollectionNIdentifierA unique key for the ISComCatalogCollection table. ISComCatalogCollectionISComCatalogObject_NISComCatalogObject1IdentifierForeign key into the ISComCatalogObject table. ISComCatalogCollectionObjectsISComCatalogCollection_NISComCatalogCollection1IdentifierA unique key for the ISComCatalogCollection table. ISComCatalogCollectionObjectsISComCatalogObject_NISComCatalogObject1IdentifierForeign key into the ISComCatalogObject table. ISComCatalogObjectDisplayNameNThe display name of a catalog object. ISComCatalogObjectISComCatalogObjectNIdentifierA unique key for the ISComCatalogObject table. ISComPlusApplicationComponent_NComponent1IdentifierForeign key into the Component table that a COM+ application belongs to. ISComPlusApplicationComputerNameYTextComputer name that a COM+ application belongs to. ISComPlusApplicationDepFilesYTextList of the dependent files. ISComPlusApplicationISAttributesYInstallShield custom attributes associated with a COM+ application. ISComPlusApplicationISComCatalogObject_NISComCatalogObject1IdentifierForeign key into the ISComCatalogObject table. ISComPlusProxyComponent_YComponent1IdentifierForeign key into the Component table that a COM+ application proxy belongs to. ISComPlusProxyDepFilesYTextList of the dependent files. ISComPlusProxyISAttributesYInstallShield custom attributes associated with a COM+ application proxy. ISComPlusProxyISComPlusApplication_NISComPlusApplication1IdentifierForeign key into the ISComPlusApplication table that a COM+ application proxy belongs to. ISComPlusProxyISComPlusProxyNIdentifierA unique key for the ISComPlusProxy table. ISComponentExtendedComponent_NComponent1IdentifierPrimary key used to identify a particular component record. ISComponentExtendedFTPLocationYTextFTP Location ISComponentExtendedFilterPropertyNIdentifierProperty to set if you want to filter a component ISComponentExtendedHTTPLocationYTextHTTP Location ISComponentExtendedLanguageYTextLanguage ISComponentExtendedMiscellaneousYTextMiscellaneous ISComponentExtendedOSYbitwise addition of OSs ISComponentExtendedPlatformsYbitwise addition of Platforms. ISDIMDependencyISDIMReference_NIdentifierThis is the primary key to the ISDIMDependency table ISDIMDependencyRequiredBuildVersionYTextthe build version identifying the required DIM ISDIMDependencyRequiredMajorVersionYTextthe major version identifying the required DIM ISDIMDependencyRequiredMinorVersionYTextthe minor version identifying the required DIM ISDIMDependencyRequiredRevisionVersionYTextthe revision version identifying the required DIM ISDIMDependencyRequiredUUIDNTextthe UUID identifying the required DIM ISDIMReferenceISBuildSourcePathYTextFull path, the category is of Text instead of Path because of potential use of path variables. ISDIMReferenceISDIMReferenceNISDIMDependency1IdentifierThis is the primary key to the ISDIMReference table ISDIMReferenceDependenciesISDIMDependency_NISDIMDependency1IdentifierForeign key into ISDIMDependency table. ISDIMReferenceDependenciesISDIMReference_ParentNISDIMReference1IdentifierForeign key into ISDIMReference table. ISDIMVariableISDIMReference_NISDIMReference1IdentifierForeign key into ISDIMReference table. ISDIMVariableISDIMVariableNIdentifierThis is the primary key to the ISDIMVariable table ISDIMVariableNameNTextName of a variable defined in the .dim file ISDIMVariableNewValueYTextNew value that you want to override with ISDIMVariableTypeYType of the variable. 0: Build Variable, 1: Runtime Variable ISDLLWrapperEntryPointNTextThis is a foreign key to the target column in the CustomAction table ISDLLWrapperSourceNFormattedThis is column points to the source file for the DLLWrapper Custom Action ISDLLWrapperTargetNTextThe function signature ISDLLWrapperTypeYType ISDRMFileFile_YFile1IdentifierForeign key into File table. A null value will cause a build warning. ISDRMFileISDRMFileNIdentifierUnique identifier for this item. ISDRMFileISDRMLicense_YISDRMLicense1IdentifierForeign key referencing License that packages this file. ISDRMFileShellNTextText indicating the activation shell used at runtime. ISDRMFileAttributeISDRMFile_NISDRMFile1IdentifierPrimary foreign key into ISDRMFile table. ISDRMFileAttributePropertyNTextThe name of the attribute ISDRMFileAttributeValueYTextThe value of the attribute ISDRMLicenseAttributesYNumberBitwise field used to specify binary attributes of this license. ISDRMLicenseDescriptionYTextAn internal description of this license. ISDRMLicenseISDRMLicenseNIdentifierUnique key identifying the license record. ISDRMLicenseLicenseNumberYTextThe license number. ISDRMLicenseProjectVersionYTextThe version of the project that this license is tied to. ISDRMLicenseRequestCodeYTextThe request code. ISDRMLicenseResponseCodeYTextThe response code. ISDependencyExcludeY ISDependencyISDependencyY ISDisk1FileDiskY-1;0;1Used to differentiate between disk1(1), last disk(-1), and other(0). ISDisk1FileISBuildSourcePathNTextFull path of file to be copied to Disk1 folder ISDisk1FileISDisk1FileNIdentifierPrimary key for ISDisk1File table ISDynamicFileComponent_NComponent1IdentifierForeign key referencing Component that controls the file. ISDynamicFileExcludeFilesYTextWildcards for excluded files. ISDynamicFileISAttributesY0;1;2;3This is used to store Installshield custom properties of a dynamic filet. Currently the only one is SelfRegister. ISDynamicFileIncludeFilesYTextWildcards for included files. ISDynamicFileIncludeFlagsYInclude flags. ISDynamicFileSourceFolderNTextFull path, the category is of Text instead of Path because of potential use of path variables. ISFeatureDIMReferencesFeature_NFeature1IdentifierForeign key into Feature table. ISFeatureDIMReferencesISDIMReference_NISDIMReference1IdentifierForeign key into ISDIMReference table. ISFeatureMergeModuleExcludesFeature_NIdentifierForeign key into Feature table. ISFeatureMergeModuleExcludesLanguageNForeign key into ISMergeModule table. ISFeatureMergeModuleExcludesModuleIDNIdentifierForeign key into ISMergeModule table. ISFeatureMergeModulesFeature_NFeature1IdentifierForeign key into Feature table. ISFeatureMergeModulesISMergeModule_NISMergeModule1TextForeign key into ISMergeModule table. ISFeatureMergeModulesLanguage_NISMergeModule2Foreign key into ISMergeModule table. ISFileManifestsFile_NIdentifierForeign key into File table. ISFileManifestsManifest_NIdentifierForeign key into File table. ISIISAppPoolAppPoolN ISIISAppPoolAttributesY ISIISAppPoolCPUMonY ISIISAppPoolComponent_NComponent1TextForeign key into Component table ISIISAppPoolIdleTimeoutY ISIISAppPoolMaxProcY ISIISAppPoolNameNTextLocalizable Display Name ISIISAppPoolQueueLimitY ISIISAppPoolRecycleMinutesY ISIISAppPoolRecycleRequestsY ISIISAppPoolRecycleTimesY ISIISAppPoolUserY ISIISAppPoolUserPasswordY ISIISCommonAnonyPasswrdYTextPassword for anonymous access ISIISCommonAnonyUserNameYTextUser name for anonymous access ISIISCommonAppNameYTextAppName of this VRoot ISIISCommonAppPool_YTextLocalizable Application Pool Name ISIISCommonAttributesNNumberAttributes for this IIS node ISIISCommonCustomErrorsYTextDelimited list of custom errors ISIISCommonDefDocYTextLocalizable Defeault Doc ISIISCommonDisplayNameYTextLocalizable Virtual Root Name ISIISCommonISIISCommonNIdentifierPrimary key used to identify a particular record. ISIISCommonISIISCommon_ParentYISIISCommon1IdentifierThis record's parent record. ISIISCommonRootDirNTextRoot directory for this IIS Node ISIISCommonSSLCertYBinary1IdentifierForeign key into the binary table. ISIISCommonScriptTimeoutYNumberASP Script Timeout ISIISCommonSessionTimeoutYNumberSession Timeout ISIISMetaDataISIISCommon_NISIISCommon1IdentifierForeign key into ISIISCommon table ISIISMetaDataMetaDataAttributesNThis is the dwMDAttributes item in the METADATA_RECORD structure ISIISMetaDataMetaDataPropYThis is the dwMDIdentifier item in the METADATA_RECORD structure ISIISMetaDataMetaDataTypeYThis is the dwMDDataType item in the METADATA_RECORD structure ISIISMetaDataMetaDataUserTypeNThis is the dwMDUserType item in the METADATA_RECORD structure ISIISMetaDataMetaDataValueNTextThis is the pbMDData item in the METADATA_RECORD structure ISIISMetaDataOrderNUse this column to order the meta data properties. ISIISWebServiceExtensionAttributesN ISIISWebServiceExtensionComponent_NComponent1TextForeign key into Component table ISIISWebServiceExtensionDescriptionNTextLocalizable Description ISIISWebServiceExtensionFileN ISIISWebServiceExtensionGroupN ISIISWebServiceExtensionWebServiceExtensionN ISInstallScriptActionEntryPointNTextThis is a foreign key to the target column in the CustomAction table ISInstallScriptActionSourceNFormattedThis is column points to the source file for the DLLWrapper Custom Action ISInstallScriptActionTargetYTextThe function signature ISInstallScriptActionTypeYType ISLanguageISLanguageNLanguageThis is the language ID. ISLanguageIncludedY0;1Specify whether this language should be included. ISLinkerLibraryISLinkerLibraryNIdentifierUnique identifier for the link library. ISLinkerLibraryLibraryNTextFull path of the object library (.obl file). ISLinkerLibraryOrderNOrder of the Library ISLocalControlAttributesYA 32-bit word that specifies the attribute flags to be applied to this control. ISLocalControlBinary_YBinary1IdentifierExternal key to the Binary table. ISLocalControlControl_NControl2IdentifierName of the control. This name must be unique within a dialog, but can repeat on different dialogs. ISLocalControlDialog_NDialog1IdentifierExternal key to the Dialog table, name of the dialog. ISLocalControlHeightYHeight of the bounding rectangle of the control. ISLocalControlISBuildSourcePathYTextFull path to .rtf file for scrollable text control ISLocalControlISLanguage_NISLanguage1LanguageThis is a foreign key to the ISLanguage table. ISLocalControlWidthYWidth of the bounding rectangle of the control. ISLocalControlXYHorizontal coordinate of the upper left corner of the bounding rectangle of the control. ISLocalControlYYVertical coordinate of the upper left corner of the bounding rectangle of the control. ISLocalDialogAttributesYA 32-bit word that specifies the attribute flags to be applied to this dialog. ISLocalDialogDialog_YDialog1IdentifierName of the dialog. ISLocalDialogHeightN032767Height of the bounding rectangle of the dialog. ISLocalDialogISLanguage_YISLanguage1LanguageThis is a foreign key to the ISLanguage table. ISLocalDialogTextStyle_YIdentifierForeign Key into TextStyle table, only used in Script Based Projects. ISLocalDialogWidthN032767Width of the bounding rectangle of the dialog. ISLocalRadioButtonHeightN032767The height of the button. ISLocalRadioButtonISLanguage_NISLanguage1LanguageThis is a foreign key to the ISLanguage table. ISLocalRadioButtonOrderN132767RadioButton2A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive. ISLocalRadioButtonPropertyNRadioButton1IdentifierA named property to be tied to this radio button. All the buttons tied to the same property become part of the same group. ISLocalRadioButtonWidthN032767The width of the button. ISLocalRadioButtonXN032767The horizontal coordinate of the upper left corner of the bounding rectangle of the radio button. ISLocalRadioButtonYN032767The vertical coordinate of the upper left corner of the bounding rectangle of the radio button. ISLogicalDiskCabinetYCabinetIf some or all of the files stored on the media are compressed in a cabinet, the name of that cabinet. ISLogicalDiskDiskIdN132767Primary key, integer to determine sort order for table. ISLogicalDiskDiskPromptYTextDisk name: the visible text actually printed on the disk. This will be used to prompt the user when this disk needs to be inserted. ISLogicalDiskISProductConfiguration_NISProductConfiguration1TextForeign key into the ISProductConfiguration table. ISLogicalDiskISRelease_NISRelease1TextForeign key into the ISRelease table. ISLogicalDiskLastSequenceN032767File sequence number for the last file for this media. ISLogicalDiskSourceYPropertyThe property defining the location of the cabinet file. ISLogicalDiskVolumeLabelYTextThe label attributed to the volume. ISLogicalDiskFeaturesFeature_YFeature1IdentifierRequired foreign key into the Feature Table, ISLogicalDiskFeaturesISAttributesYThis is used to store Installshield custom properties, like Compressed, etc. ISLogicalDiskFeaturesISLogicalDisk_N132767ISLogicalDisk1IdentifierForeign key into the ISLogicalDisk table. ISLogicalDiskFeaturesISProductConfiguration_NISProductConfiguration1TextForeign key into the ISProductConfiguration table. ISLogicalDiskFeaturesISRelease_NISRelease1TextForeign key into the ISRelease table. ISLogicalDiskFeaturesSequenceN032767File sequence number for the file for this media. ISMergeModuleDestinationYTextDestination. ISMergeModuleISAttributesYThis is used to store Installshield custom properties of a merge module. ISMergeModuleISMergeModuleNTextThe GUID identifying the merge module. ISMergeModuleLanguageNDefault decimal language of module. ISMergeModuleNameNTextName of the merge module. ISMergeModuleCfgValuesAttributesYAttributes (from configurable merge module) ISMergeModuleCfgValuesContextDataYTextContextData (from configurable merge module) ISMergeModuleCfgValuesDefaultValueYTextDefaultValue (from configurable merge module) ISMergeModuleCfgValuesDescriptionYTextDescription (from configurable merge module) ISMergeModuleCfgValuesDisplayNameYTextDisplayName (from configurable merge module) ISMergeModuleCfgValuesFormatNFormat (from configurable merge module) ISMergeModuleCfgValuesHelpKeywordYTextHelpKeyword (from configurable merge module) ISMergeModuleCfgValuesHelpLocationYTextHelpLocation (from configurable merge module) ISMergeModuleCfgValuesISMergeModule_NISMergeModule1TextThe module signature, a foreign key into the ISMergeModule table ISMergeModuleCfgValuesLanguage_NISMergeModule2Default decimal language of module. ISMergeModuleCfgValuesModuleConfiguration_NIdentifierIdentifier, foreign key into ModuleConfiguration table (ModuleConfiguration.Name) ISMergeModuleCfgValuesTypeYTextType (from configurable merge module) ISMergeModuleCfgValuesValueYTextValue for this item. ISObjectLanguageNText ISObjectObjectNameNText ISObjectPropertyIncludeInBuildYBoolean, 0 for false non 0 for true ISObjectPropertyObjectNameYISObject1Text ISObjectPropertyPropertyYText ISObjectPropertyValueYText ISPalmAppComponentNComponent1 ISPalmAppPalmAppN ISPalmAppFileDestinationN ISPalmAppFileFileKeyNFile1 ISPalmAppFilePalmAppNISPalmApp1 ISPatchConfigImagePatchConfiguration_YISPatchConfiguration1TextForeign key to the ISPatchConfigurationTable ISPatchConfigImageUpgradedImage_NISUpgradedImage1TextForeign key to the ISUpgradedImageTable ISPatchConfigurationAttributesYPatchConfiguration attributes ISPatchConfigurationCanPCDifferNThis is determine whether Product Codes may differ ISPatchConfigurationCanPVDifferNThis is determine whether the Major Product Version may differ ISPatchConfigurationEnablePatchCacheNThis is determine whether to Enable Patch cacheing ISPatchConfigurationFlagsNPatching API Flags ISPatchConfigurationIncludeWholeFilesNThis is determine whether to build a binary level patch ISPatchConfigurationLeaveDecompressedNThis is determine whether to leave intermediate files devcompressed when finished ISPatchConfigurationMinMsiVersionNMinimum Required MSI Version ISPatchConfigurationNameNTextName of the Patch Configuration ISPatchConfigurationOptimizeForSizeNThis is determine whether to Optimize for large files ISPatchConfigurationOutputPathNTextBuild Location ISPatchConfigurationPatchCacheDirYTextDirectory to recieve the Patch Cache information ISPatchConfigurationPatchGuidNTextUnique Patch Identifier ISPatchConfigurationPatchGuidsToReplaceYTextList Of Patch Guids to unregister ISPatchConfigurationTargetProductCodesNTextList Of target Product Codes ISPatchConfigurationPropertyISPatchConfiguration_YISPatchConfiguration1TextName of the Patch Configuration ISPatchConfigurationPropertyPropertyYTextName of the Patch Configuration Property value ISPatchConfigurationPropertyValueYTextValue of the Patch Configuration Property ISPatchExternalFileFileKeyNTextFilekey ISPatchExternalFileFilePathNTextFilepath ISPatchExternalFileISUpgradedImage_NISUpgradedImage1TextForeign key to the isupgraded image table ISPatchExternalFileNameNTextUniqu name to identify this record. ISPatchWholeFileComponentYTextComponent containing file key ISPatchWholeFileFileKeyNTextKey of file to be included as whole ISPatchWholeFileUpgradedImageNISUpgradedImage1TextForeign key to ISUpgradedImage Table ISPathVariableISPathVariableNThe name of the path variable. ISPathVariableTestValueYTextThe test value of the path variable. ISPathVariableTypeN1;2;4;8The type of the path variable. ISPathVariableValueYTextThe value of the path variable. ISProductConfigurationGeneratePackageCodeYNumber0;1Indicates whether or not to generate a package code. ISProductConfigurationISProductConfigurationNTextThe name of the product configuration. ISProductConfigurationProductConfigurationFlagsYTextProduct configuration (release) flags. ISProductConfigurationInstanceISProductConfiguration_NISProductConfiguration1TextForeign key into the ISProductConfiguration table. ISProductConfigurationInstanceInstanceIdN032767Identifies the instance number of this instance. This value is stored in the Property InstanceId. ISProductConfigurationInstancePropertyNTextProduct Congiuration property name ISProductConfigurationInstanceValueNTextString value for property. ISProductConfigurationPropertyISProductConfiguration_NISProductConfiguration1TextForeign key into the ISProductConfiguration table. ISProductConfigurationPropertyPropertyNProperty1TextProduct Congiuration property name ISProductConfigurationPropertyValueYTextString value for property. Never null or empty. ISReleaseAttributesNBitfield holding boolean values for various release attributes. ISReleaseBuildLocationNTextBuild location. ISReleaseCDBrowserYTextDemoshield browser location. ISReleaseDefaultLanguageNLanguageDefault language for setup. ISReleaseDigitalPVKYTextDigital signing private key (.pvk) file. ISReleaseDigitalSPCYTextDigital signing Software Publisher Certificate (.spc) file. ISReleaseDigitalURLYTextDigital signing URL. ISReleaseDiskClusterSizeNDisk cluster size. ISReleaseDiskSizeNTextDisk size. ISReleaseDiskSizeUnitN0;1;2Disk size units (KB or MB). ISReleaseDiskSpanningN0;1;2Disk spanning (automatic, enforce size, etc.). ISReleaseDotNetBuildConfigurationYTextBuild Configuration for .NET solutions. ISReleaseISProductConfiguration_NISProductConfiguration1TextForeign key into the ISProductConfiguration table. ISReleaseISReleaseNTextThe name of the release. ISReleaseISSetupPrerequisiteLocationY0;1;2Location the Setup Prerequisites will be placed in ISReleaseMediaLocationNTextMedia location on disk. ISReleaseMsiCommandLineYTextCommand line passed to the msi package from setup.exe ISReleaseMsiSourceTypeN-14MSI media source type. ISReleasePackageNameNTextPackage name. ISReleasePasswordYTextPassword. ISReleasePlatformsNTextPlatforms supported (Intel, Alpha, etc.). ISReleaseReleaseFlagsYTextRelease flags. ISReleaseReleaseTypeN1;2;4Release type (single, uncompressed, etc.). ISReleaseSupportedLanguagesDataYTextLanguages supported (for component filtering). ISReleaseSupportedLanguagesUINTextUI languages supported. ISReleaseSupportedOSsNIndicate which operating systmes are supported. ISReleaseSynchMsiYTextMSI file to synchronize file keys and other data with (patch-like functionality). ISReleaseTypeN06Release type (CDROM, Network, etc.). ISReleaseURLLocationYTextMedia location via URL. ISReleaseVersionCopyrightYTextVersion stamp information. ISReleaseASPublishInfoISProductConfiguration_NISProductConfiguration1TextForeign key into the ISProductConfiguration table. ISReleaseASPublishInfoISRelease_NISRelease1TextForeign key into the ISRelease table. ISReleaseASPublishInfoPropertyYTextAS Repository property name ISReleaseASPublishInfoValueYTextAS Repository property value ISReleaseExtendedAttributesYBitfield holding boolean values for various release attributes. ISReleaseExtendedCertPasswordYTextDigital certificate password ISReleaseExtendedDigitalCertificateDBaseNSYTextPath to cerificate database for Netscape digital signature ISReleaseExtendedDigitalCertificateIdNSYTextPath to cerificate ID for Netscape digital signature ISReleaseExtendedDigitalCertificatePasswordNSYTextPassword for Netscape digital signature ISReleaseExtendedDotNetBaseLanguageYTextBase Languge of .NET Redist ISReleaseExtendedDotNetFxCmdLineYTextCommand Line to pass to DotNetFx.exe ISReleaseExtendedDotNetLangPackCmdLineYTextCommand Line to pass to LangPack.exe ISReleaseExtendedDotNetLangaugePacksYText.NET Redist language packs to include ISReleaseExtendedDotNetRedistLocationY03Location of .NET framework Redist (Web, SetupExe, Source, None) ISReleaseExtendedDotNetRedistURLYTextURL to .NET framework Redist ISReleaseExtendedDotNetVersionY02Version of .NET framework Redist (1.0, 1.1) ISReleaseExtendedEngineLocationY02Location of msi engine (Web, SetupExe...) ISReleaseExtendedISEngineLocationY02Location of ISScript engine (Web, SetupExe...) ISReleaseExtendedISEngineURLYTextURL to InstallShield scripting engine ISReleaseExtendedISProductConfiguration_NTextForeign key into the ISProductConfiguration table. ISReleaseExtendedISRelease_NTextThe name of the release. ISReleaseExtendedJSharpCmdLineYTextCommand Line to pass to vjredist.exe ISReleaseExtendedJSharpRedistLocationY03Location of J# framework Redist (Web, SetupExe, Source, None) ISReleaseExtendedMsiEngineVersionYBitfield holding selected MSI engine versions included in this release ISReleaseExtendedOneClickCabNameYTextFile name of generated cabfile ISReleaseExtendedOneClickHtmlNameYTextFile name of generated html page ISReleaseExtendedOneClickTargetBrowserY02Target browser (IE, Netscape, both...) ISReleaseExtendedWebCabSizeY02147483647Size of the cabfile ISReleaseExtendedWebLocalCachePathYTextDirectory to cache downloaded package ISReleaseExtendedWebTypeY02Type of web install (One Executable, Downloader...) ISReleaseExtendedWebURLYTextURL to .msi package ISReleaseExtendedWin9xMsiUrlYTextURL to Ansi MSI engine ISReleaseExtendedWinMsi30UrlYTextURL to MSI 3.0 engine ISReleaseExtendedWinNTMsiUrlYTextURL to Unicode MSI engine ISReleasePublishInfoDescriptionYTextRepository item description ISReleasePublishInfoDisplayNameYTextRepository item display name ISReleasePublishInfoISAttributesYBitfield holding various attributes ISReleasePublishInfoISProductConfiguration_NISProductConfiguration1TextForeign key into the ISProductConfiguration table. ISReleasePublishInfoISRelease_NISRelease1TextThe name of the release. ISReleasePublishInfoPublisherYTextRepository item publisher ISReleasePublishInfoRepositoryYTextRepository which to publish the built merge module ISSQLConnectionAttributesN ISSQLConnectionAuthenticationN ISSQLConnectionBatchSeparatorY ISSQLConnectionCmdTimeoutY ISSQLConnectionCommentsY ISSQLConnectionDatabaseN ISSQLConnectionISSQLConnectionN ISSQLConnectionOrderN ISSQLConnectionPasswordN ISSQLConnectionServerN ISSQLConnectionUserNameN ISSQLConnectionDBServerISSQLConnectionDBServerN ISSQLConnectionDBServerISSQLConnection_NISSQLConnection1 ISSQLConnectionDBServerISSQLDBMetaData_NISSQLDBMetaData1 ISSQLConnectionDBServerOrderN ISSQLConnectionScriptISSQLConnection_NISSQLConnection1 ISSQLConnectionScriptISSQLScriptFile_NISSQLScriptFile1 ISSQLConnectionScriptOrderN ISSQLDBMetaDataAdoCxnDatabaseY ISSQLDBMetaDataAdoCxnDriverY ISSQLDBMetaDataAdoCxnNetLibraryY ISSQLDBMetaDataAdoCxnPasswordY ISSQLDBMetaDataAdoCxnServerY ISSQLDBMetaDataAdoCxnUserIDY ISSQLDBMetaDataAdoCxnWindowsSecurityY ISSQLDBMetaDataAdoDriverNameY ISSQLDBMetaDataCreateDbCmdY ISSQLDBMetaDataDisplayNameY ISSQLDBMetaDataDsnODBCNameY ISSQLDBMetaDataISAttributesY ISSQLDBMetaDataISSQLDBMetaDataN ISSQLDBMetaDataLocalInstanceNamesY ISSQLDBMetaDataSwitchDbCmdY ISSQLDBMetaDataTestDatabaseCmdY ISSQLDBMetaDataTestTableCmdY ISSQLDBMetaDataTestTableCmd2Y ISSQLDBMetaDataVersionBeginTokenY ISSQLDBMetaDataVersionEndTokenY ISSQLDBMetaDataVersionInfoCmdY ISSQLDBMetaDataWinAuthentUserIdY ISSQLRequirementAttributesN ISSQLRequirementISSQLConnectionDBServer_YISSQLConnectionDBServer1 ISSQLRequirementISSQLConnection_NISSQLConnection1 ISSQLRequirementISSQLRequirementN ISSQLRequirementMajorVersionY ISSQLRequirementServicePackLevelY ISSQLScriptErrorAttributesN ISSQLScriptErrorErrHandlingN ISSQLScriptErrorErrNumberN ISSQLScriptErrorISSQLScriptFile_YISSQLScriptFile1IdentifierForeign key referencing ISSQLScriptFile ISSQLScriptErrorMessageYTextCustom end-user message. Reserved for future use. ISSQLScriptFileAttributesN ISSQLScriptFileCommentsYTextComments ISSQLScriptFileComponent_NComponent1IdentifierForeign key referencing Component that controls the SQL script. ISSQLScriptFileErrorHandlingN ISSQLScriptFileISBuildSourcePathYTextFull path, the category is of Text instead of Path because of potential use of path variables. ISSQLScriptFileISSQLScriptFileNIdentifierThis is the primary key to the ISSQLScriptFile table ISSQLScriptFileInstallTextYTextFeedback end-user text at install ISSQLScriptFileSchedulingN ISSQLScriptFileUninstallTextYTextFeedback end-user text at Uninstall ISSQLScriptFileVersionYTextSchema Version (####.#####.####) ISSQLScriptImportAttributesN ISSQLScriptImportAuthenticationN ISSQLScriptImportDatabaseY ISSQLScriptImportExcludeTablesY ISSQLScriptImportISSQLScriptFile_NISSQLScriptFile1 ISSQLScriptImportIncludeTablesY ISSQLScriptImportPasswordY ISSQLScriptImportServerY ISSQLScriptImportUserNameY ISSQLScriptReplaceAttributesN ISSQLScriptReplaceISSQLScriptFile_NISSQLScriptFile1 ISSQLScriptReplaceISSQLScriptReplaceN ISSQLScriptReplaceReplaceY ISSQLScriptReplaceSearchY ISScriptFileISScriptFileNTextThis is the full path of the script file. The path portion may be expressed in path variable form. ISSelfRegCmdLineY ISSelfRegCostY ISSelfRegFileKeyNFile1IdentifierForeign key to the file table ISSelfRegOrderY ISSetupFileFileNameYTextThis is the file name to use when streaming the file to the support files location ISSetupFileISSetupFileNIdentifierThis is the primary key to the ISSetupFile table ISSetupFileLanguageYTextFour digit language identifier. 0 for Language Neutral ISSetupFilePathYTextLink to the source file on the build machine ISSetupFileSplashYShortBoolean value indication whether his setup file entry belongs in the Splasc Screen section ISSetupFileStreamYBinaryBinary stream. The bits to stream to the support location ISSetupPrerequisitesISBuildSourcePathY ISSetupPrerequisitesISSetupPrerequisitesN ISSetupPrerequisitesOrderY ISSetupTypeCommentsYTextUser Comments. ISSetupTypeDescriptionYTextLonger descriptive text describing a visible feature item. ISSetupTypeDisplayN032767Numeric sort order, used to force a specific display ordering. ISSetupTypeDisplay_NameYFormattedA string used to set the initial text contained within a control (if appropriate). ISSetupTypeISSetupTypeNIdentifierPrimary key used to identify a particular feature record. ISSetupTypeFeaturesFeature_NFeature1IdentifierForeign key into Feature table. ISSetupTypeFeaturesISSetupType_NISSetupType1IdentifierForeign key into ISSetupType table. ISStoragesISBuildSourcePathYPath to the file to stream into sub-storage ISStoragesNameNName of the sub-storage key ISStringCommentYTextComment ISStringEncodedYEncoding for multi-byte strings. ISStringISLanguage_NLanguageThis is a foreign key to the ISLanguage table. ISStringISStringNTextString id. ISStringTimeStampYTime/DateTime Stamp. MSI's Time/Date column type is just an int, with bits packed in a certain order. ISStringValueYTextreal string value. ISTargetImageFlagsYrelative order of the target image ISTargetImageIgnoreMissingFilesNIf true, ignore missing source files when creating patch ISTargetImageMsiPathNTextPath to the target image ISTargetImageNameNIdentifierName of the TargetImage ISTargetImageOrderNrelative order of the target image ISTargetImageUpgradedImage_NISUpgradedImage1Textforeign key to the upgraded Image table ISUpgradeMsiItemISAttributesN0;1 ISUpgradeMsiItemISReleaseFlagsY ISUpgradeMsiItemObjectSetupPathNTextThe path to the setup you want to upgrade. ISUpgradeMsiItemUpgradeItemNTextThe name of the Upgrade Item. ISUpgradedImageFamilyNTextName of the image family ISUpgradedImageMsiPathNTextPath to the upgraded image ISUpgradedImageNameNIdentifierName of the UpgradedImage ISVRootAnonyPasswrdYTextObsolete column. Moved to IISCommon ISVRootAnonyUserNameYTextObsolete column. Moved to IISCommon ISVRootComponent_NComponent1TextForeign key into Component table ISVRootConditionYTextObsolete column. Moved to Component ISVRootScriptTimeoutYObsolete column. Moved to IISCommon ISVRootSessionTimeoutYObsolete column. Moved to IISCommon ISVRootVRootAppNameYTextAppName of this VRoot ISVRootVRootDefDocYTextObsolete column. Moved to IISCommon ISVRootVRootDirNTextObsolete column. Moved to IISCommon ISVRootVRootKeyNTextForeign key into ISIISCommon table ISVRootVRootNameNTextObsolete column. Moved to IISCommon ISVRootVRootPropsNProperties of this VRoot ISVRootAppMapsAppMapPropsN ISVRootAppMapsExecPathNTextLocalizable Exec Path ISVRootAppMapsExtensionNTextLocalizable Extension ISVRootAppMapsVRootAppMapKeyN ISVRootAppMapsVRootKeyNISIISCommon1 ISVRootAppMapsVerbNTextLocalizable Verb ISWebSiteIPY ISWebSiteISIISCommon_NISIISCommon1TextForeign key into ISIISCommon table ISWebSitePortN ISWebSiteSiteNumberN ISWebSiteWebSitePropsY ISXmlElementContentYTextElement contents ISXmlElementISAttributesYNumberInternal XML element attributes ISXmlElementISXmlElementNIdentifierPrimary key, non-localized, internal token for Xml element ISXmlElementISXmlElement_ParentYISXmlElement1IdentifierForeign key into ISXMLElement table. ISXmlElementISXmlFile_NISXmlFile1IdentifierForeign key into XmlFile table. ISXmlElementXPathYTextXPath fragment including any operators ISXmlElementAttribISAttributesYNumberInternal XML elementattib attributes ISXmlElementAttribISXmlElementAttribNIdentifierPrimary key, non-localized, internal token for Xml element attribute ISXmlElementAttribISXmlElement_NISXmlElement1IdentifierForeign key into ISXMLElement table. ISXmlElementAttribNameYTextLocalized attribute name ISXmlElementAttribValueYTextLocalized attribute value ISXmlFileComponent_NComponent1IdentifierForeign key into Component table. ISXmlFileDirectoryNIdentifierForeign key into Directory table. ISXmlFileFileNameNTextLocalized XML file name ISXmlFileISAttributesYNumberInternal XML file attributes ISXmlFileISXmlFileNIdentifierPrimary key, non-localized,internal token for Xml file ISXmlFileSelectionNamespacesYTextSelection namespaces ISXmlLocatorAttributeYThe name of an attribute within the XML element. ISXmlLocatorElementYXPath query that will locate an element in an XML file. ISXmlLocatorISAttributesY0;1;2 ISXmlLocatorParentYIdentifierThe parent file signature. It is also a foreign key in the Signature table. ISXmlLocatorSignature_NIdentifierThe Signature_ represents a unique file signature and is also the foreign key in the Signature, RegLocator, IniLocator, ISXmlLocator, CompLocator and the DrLocator tables. IconDataYBinaryBinary stream. The binary icon data in PE (.DLL or .EXE) or icon (.ICO) format. IconISBuildSourcePathYTextFull path to the ICO or EXE file. IconISIconIndexY-3276732767Optional icon index to be extracted. IconNameNIdentifierPrimary key. Name of the icon file. IniFileActionN0;1;3The type of modification to be made, one of iifEnum IniFileComponent_NComponent1IdentifierForeign key into the Component table referencing component that controls the installing of the .INI value. IniFileDirPropertyYIdentifierForeign key into the Directory table denoting the directory where the .INI file is. IniFileFileNameNTextThe .INI file name in which to write the information IniFileIniFileNIdentifierPrimary key, non-localized token. IniFileKeyNFormattedThe .INI file key below Section. IniFileSectionNFormattedThe .INI file Section. IniFileValueNFormattedThe value to be written. IniLocatorFieldY032767The field in the .INI line. If Field is null or 0 the entire line is read. IniLocatorFileNameNTextThe .INI file name. IniLocatorKeyNTextKey value (followed by an equals sign in INI file). IniLocatorSectionNTextSection name within in file (within square brackets in INI file). IniLocatorSignature_NSignature1IdentifierThe table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table. IniLocatorTypeY02An integer value that determines if the .INI value read is a filename or a directory location or to be used as is w/o interpretation. InstallExecuteSequenceActionNIdentifierName of action to invoke, either in the engine or the handler DLL. InstallExecuteSequenceConditionYTextOptional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData. InstallExecuteSequenceISAttributesYThis is used to store MM Custom Action Types InstallExecuteSequenceISCommentsYTextAuthor’s comments on this Sequence. InstallExecuteSequenceSequenceY-432767Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action. InstallShieldPropertyNIdentifierName of property, uppercase if settable by launcher or loader. InstallShieldValueYTextString value for property. InstallUISequenceActionNIdentifierName of action to invoke, either in the engine or the handler DLL. InstallUISequenceConditionYTextOptional expression which skips the action if evaluates to expFalse.If the expression syntax is invalid, the engine will terminate, returning iesBadActionData. InstallUISequenceISAttributesYThis is used to store MM Custom Action Types InstallUISequenceISCommentsYTextAuthor’s comments on this Sequence. InstallUISequenceSequenceY-432767Number that determines the sort order in which the actions are to be executed. Leave blank to suppress action. IsolatedComponentComponent_ApplicationNComponent1IdentifierKey to Component table item for application IsolatedComponentComponent_SharedNComponent1IdentifierKey to Component table item to be isolated LaunchConditionConditionNConditionExpression which must evaluate to TRUE in order for install to commence. LaunchConditionDescriptionNTextLocalizable text to display when condition fails and install must abort. ListBoxOrderN132767A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive. ListBoxPropertyNIdentifierA named property to be tied to this item. All the items tied to the same property become part of the same listbox. ListBoxTextYTextThe visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value. ListBoxValueNFormattedThe value string associated with this item. Selecting the line will set the associated property to this value. ListViewBinary_YBinary1IdentifierThe name of the icon to be displayed with the icon. The binary information is looked up from the Binary Table. ListViewOrderN132767A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive. ListViewPropertyNIdentifierA named property to be tied to this item. All the items tied to the same property become part of the same listview. ListViewTextYTextThe visible text to be assigned to the item. Optional. If this entry or the entire column is missing, the text is the same as the value. ListViewValueNTextThe value string associated with this item. Selecting the line will set the associated property to this value. LockPermissionsDomainYTextDomain name for user whose permissions are being set. (usually a property) LockPermissionsLockObjectNIdentifierForeign key into Registry or File table LockPermissionsPermissionY-21474836472147483647Permission Access mask. Full Control = 268435456 (GENERIC_ALL = 0x10000000) LockPermissionsTableNIdentifierDirectory;File;RegistryReference to another table name LockPermissionsUserNTextUser for permissions to be set. (usually a property) MIMECLSIDYClass1GuidOptional associated CLSID. MIMEContentTypeNTextPrimary key. Context identifier, typically "type/format". MIMEExtension_NExtension1TextOptional associated extension (without dot) MediaCabinetYCabinetIf some or all of the files stored on the media are compressed in a cabinet, the name of that cabinet. MediaDiskIdN132767Primary key, integer to determine sort order for table. MediaDiskPromptYTextDisk name: the visible text actually printed on the disk. This will be used to prompt the user when this disk needs to be inserted. MediaLastSequenceN032767File sequence number for the last file for this media. MediaSourceYPropertyThe property defining the location of the cabinet file. MediaVolumeLabelYTextThe label attributed to the volume. MoveFileComponent_NComponent1IdentifierIf this component is not "selected" for installation or removal, no action will be taken on the associated MoveFile entry MoveFileDestFolderNIdentifierName of a property whose value is assumed to resolve to the full path to the destination directory MoveFileDestNameYTextName to be given to the original file after it is moved or copied. If blank, the destination file will be given the same name as the source file MoveFileFileKeyNIdentifierPrimary key that uniquely identifies a particular MoveFile record MoveFileOptionsN01Integer value specifying the MoveFile operating mode, one of imfoEnum MoveFileSourceFolderYIdentifierName of a property whose value is assumed to resolve to the full path to the source directory MoveFileSourceNameYTextName of the source file(s) to be moved or copied. Can contain the '*' or '?' wildcards. MsiAssemblyAttributesYAssembly attributes MsiAssemblyComponent_NComponent1IdentifierForeign key into Component table. MsiAssemblyFeature_NFeature1IdentifierForeign key into Feature table. MsiAssemblyFile_ApplicationYFile1IdentifierForeign key into File table, denoting the application context for private assemblies. Null for global assemblies. MsiAssemblyFile_ManifestYFile1IdentifierForeign key into the File table denoting the manifest file for the assembly. MsiAssemblyNameComponent_NComponent1IdentifierForeign key into Component table. MsiAssemblyNameNameNTextThe name part of the name-value pairs for the assembly name. MsiAssemblyNameValueNTextThe value part of the name-value pairs for the assembly name. MsiDigitalCertificateCertDataNBinaryA certificate context blob for a signer certificate MsiDigitalCertificateDigitalCertificateNIdentifierA unique identifier for the row MsiDigitalSignatureDigitalCertificate_NMsiDigitalCertificate1IdentifierForeign key to MsiDigitalCertificate table identifying the signer certificate MsiDigitalSignatureHashYBinaryThe encoded hash blob from the digital signature MsiDigitalSignatureSignObjectNTextForeign key to Media table MsiDigitalSignatureTableNIdentifierReference to another table name (only Media table is supported) MsiDriverPackagesComponentNComponent1IdentifierPrimary key used to identify a particular component record. MsiDriverPackagesFlagsNDriver package flags MsiDriverPackagesReferenceComponentsY MsiDriverPackagesSequenceYInstallation sequence number MsiFileHashFile_NFile1IdentifierPrimary key, foreign key into File table referencing file with this hash MsiFileHashHashPart1NSize of file in bytes (long integer). MsiFileHashHashPart2NSize of file in bytes (long integer). MsiFileHashHashPart3NSize of file in bytes (long integer). MsiFileHashHashPart4NSize of file in bytes (long integer). MsiFileHashOptionsN032767Various options and attributes for this hash. MsiPatchCertificateDigitalCertificate_NMsiDigitalCertificate1IdentifierA foreign key to the digital certificate table MsiPatchCertificatePatchCertificateYIdentifierA unique identifier for the row MsiPatchMetadataCompanyYTextOptional company name MsiPatchMetadataPatchConfiguration_NISPatchConfiguration1TextForeign key to the ISPatchConfiguration table MsiPatchMetadataPropertyNTextName of the metadata MsiPatchMetadataValueYTextValue of the metadata MsiPatchOldAssemblyFileAssembly_YMsiPatchOldAssemblyName1 MsiPatchOldAssemblyFileFile_NFile1 MsiPatchOldAssemblyNameAssembly_N MsiPatchOldAssemblyNameNameN MsiPatchOldAssemblyNameValueY MsiPatchSequencePatchConfiguration_NISPatchConfiguration1TextForeign key to the patch configuration table MsiPatchSequencePatchFamilyNTextName of the family to which this patch belongs MsiPatchSequenceSequenceNVersionThe version of this patch in this family MsiPatchSequenceSupersedeNIntegerSupersede MsiPatchSequenceTargetYTextTarget product codes for this patch family ODBCAttributeAttributeNTextName of ODBC driver attribute ODBCAttributeDriver_NODBCDriver1IdentifierReference to ODBC driver in ODBCDriver table ODBCAttributeValueYTextValue for ODBC driver attribute ODBCDataSourceComponent_NComponent1IdentifierReference to associated component ODBCDataSourceDataSourceNIdentifierPrimary key, non-localized.internal token for data source ODBCDataSourceDescriptionNTextText used as registered name for data source ODBCDataSourceDriverDescriptionNTextReference to driver description, may be existing driver ODBCDataSourceRegistrationN01Registration option: 0=machine, 1=user, others t.b.d. ODBCDriverComponent_NComponent1IdentifierReference to associated component ODBCDriverDescriptionNTextText used as registered name for driver, non-localized ODBCDriverDriverNIdentifierPrimary key, non-localized.internal token for driver ODBCDriverFile_NFile1IdentifierReference to key driver file ODBCDriverFile_SetupYFile1IdentifierOptional reference to key driver setup DLL ODBCSourceAttributeAttributeNTextName of ODBC data source attribute ODBCSourceAttributeDataSource_NODBCDataSource1IdentifierReference to ODBC data source in ODBCDataSource table ODBCSourceAttributeValueYTextValue for ODBC data source attribute ODBCTranslatorComponent_NComponent1IdentifierReference to associated component ODBCTranslatorDescriptionNTextText used as registered name for translator ODBCTranslatorFile_NFile1IdentifierReference to key translator file ODBCTranslatorFile_SetupYFile1IdentifierOptional reference to key translator setup DLL ODBCTranslatorTranslatorNIdentifierPrimary key, non-localized.internal token for translator PatchAttributesN032767Integer containing bit flags representing patch attributes PatchFile_NFile1IdentifierPrimary key, non-localized token, foreign key to File table, must match identifier in cabinet. PatchHeaderYBinaryBinary stream. The patch header, used for patch validation. PatchISBuildSourcePathYTextFull path to patch header. PatchPatchSizeN02147483647Size of patch in bytes (long integer). PatchSequenceN032767Primary key, sequence with respect to the media images; order must track cabinet order. PatchPackageMedia_N032767Foreign key to DiskId column of Media table. Indicates the disk containing the patch package. PatchPackagePatchIdNGuidA unique string GUID representing this patch. ProgIdClass_YClass1GuidThe CLSID of an OLE factory corresponding to the ProgId. ProgIdDescriptionYTextLocalized description for the Program identifier. ProgIdISAttributesYThis is used to store Installshield custom properties of a component, like ExtractIcon, etc. ProgIdIconIndexY-3276732767Optional icon index. ProgIdIcon_YIcon1IdentifierOptional foreign key into the Icon Table, specifying the icon file associated with this ProgId. Will be written under the DefaultIcon key. ProgIdProgIdNTextThe Program Identifier. Primary key. ProgIdProgId_ParentYProgId1TextThe Parent Program Identifier. If specified, the ProgId column becomes a version independent prog id. PropertyISCommentsYTextUser Comments. PropertyPropertyNIdentifierName of property, uppercase if settable by launcher or loader. PropertyValueYTextString value for property. PublishComponentAppDataYTextThis is localisable Application specific data that can be associated with a Qualified Component. PublishComponentComponentIdNGuidA string GUID that represents the component id that will be requested by the alien product. PublishComponentComponent_NComponent1IdentifierForeign key into the Component table. PublishComponentFeature_NFeature1IdentifierForeign key into the Feature table. PublishComponentQualifierNTextThis is defined only when the ComponentId column is an Qualified Component Id. This is the Qualifier for ProvideComponentIndirect. RadioButtonHeightN032767The height of the button. RadioButtonHelpYTextThe help strings used with the button. The text is optional. RadioButtonISControlIdYA number used to represent the control ID of the Control, Used in Dialog export RadioButtonOrderN132767A positive integer used to determine the ordering of the items within one list..The integers do not have to be consecutive. RadioButtonPropertyNIdentifierA named property to be tied to this radio button. All the buttons tied to the same property become part of the same group. RadioButtonTextYTextThe visible title to be assigned to the radio button. RadioButtonValueNFormattedThe value string associated with this button. Selecting the button will set the associated property to this value. RadioButtonWidthN032767The width of the button. RadioButtonXN032767The horizontal coordinate of the upper left corner of the bounding rectangle of the radio button. RadioButtonYN032767The vertical coordinate of the upper left corner of the bounding rectangle of the radio button. RegLocatorKeyNRegPathThe key for the registry value. RegLocatorNameYFormattedThe registry value name. RegLocatorRootN03The predefined root key for the registry value, one of rrkEnum. RegLocatorSignature_NSignature1IdentifierThe table key. The Signature_ represents a unique file signature and is also the foreign key in the Signature table. If the type is 0, the registry values refers a directory, and _Signature is not a foreign key. RegLocatorTypeY018An integer value that determines if the registry value is a filename or a directory location or to be used as is w/o interpretation. RegistryComponent_NComponent1IdentifierForeign key into the Component table referencing component that controls the installing of the registry value. RegistryISAttributesYThis is used to store Installshield custom properties of a registry item. Currently the only one is Automatic. RegistryKeyNRegPathThe key for the registry value. RegistryNameYFormattedThe registry value name. RegistryRegistryNIdentifierPrimary key, non-localized token. RegistryRootN-13The predefined root key for the registry value, one of rrkEnum. RegistryValueYTextThe registry value. RemoveFileComponent_NComponent1IdentifierForeign key referencing Component that controls the file to be removed. RemoveFileDirPropertyNIdentifierName of a property whose value is assumed to resolve to the full pathname to the folder of the file to be removed. RemoveFileFileKeyNIdentifierPrimary key used to identify a particular file entry RemoveFileFileNameYTextName of the file to be removed. RemoveFileInstallModeN1;2;3Installation option, one of iimEnum. RemoveIniFileActionN2;4The type of modification to be made, one of iifEnum. RemoveIniFileComponent_NComponent1IdentifierForeign key into the Component table referencing component that controls the deletion of the .INI value. RemoveIniFileDirPropertyYIdentifierForeign key into the Directory table denoting the directory where the .INI file is. RemoveIniFileFileNameNTextThe .INI file name in which to delete the information RemoveIniFileKeyNFormattedThe .INI file key below Section. RemoveIniFileRemoveIniFileNIdentifierPrimary key, non-localized token. RemoveIniFileSectionNFormattedThe .INI file Section. RemoveIniFileValueYFormattedThe value to be deleted. The value is required when Action is iifIniRemoveTag RemoveRegistryComponent_NComponent1IdentifierForeign key into the Component table referencing component that controls the deletion of the registry value. RemoveRegistryKeyNRegPathThe key for the registry value. RemoveRegistryNameYFormattedThe registry value name. RemoveRegistryRemoveRegistryNIdentifierPrimary key, non-localized token. RemoveRegistryRootN-13The predefined root key for the registry value, one of rrkEnum ReserveCostComponent_NComponent1IdentifierReserve a specified amount of space if this component is to be installed. ReserveCostReserveFolderYIdentifierName of a property whose value is assumed to resolve to the full path to the destination directory ReserveCostReserveKeyNIdentifierPrimary key that uniquely identifies a particular ReserveCost record ReserveCostReserveLocalN02147483647Disk space to reserve if linked component is installed locally. ReserveCostReserveSourceN02147483647Disk space to reserve if linked component is installed to run from the source location. SFPCatalogCatalogYBinarySFP Catalog SFPCatalogDependencyYFormattedParent catalog - only used by SFP SFPCatalogSFPCatalogNFilenameFile name for the catalog. SelfRegCostY032767The cost of registering the module. SelfRegFile_NFile1IdentifierForeign key into the File table denoting the module that needs to be registered. ServiceControlArgumentsYFormattedArguments for the service. Separate by [~]. ServiceControlComponent_NComponent1IdentifierRequired foreign key into the Component Table that controls the startup of the service ServiceControlEventN0187Bit field: Install: 0x1 = Start, 0x2 = Stop, 0x8 = Delete, Uninstall: 0x10 = Start, 0x20 = Stop, 0x80 = Delete ServiceControlNameNFormattedName of a service. /, \, comma and space are invalid ServiceControlServiceControlNIdentifierPrimary key, non-localized token. ServiceControlWaitY01Boolean for whether to wait for the service to fully start ServiceInstallArgumentsYFormattedArguments to include in every start of the service, passed to WinMain ServiceInstallComponent_NComponent1IdentifierRequired foreign key into the Component Table that controls the startup of the service ServiceInstallDependenciesYFormattedOther services this depends on to start. Separate by [~], and end with [~][~] ServiceInstallDescriptionYTextDescription of service. ServiceInstallDisplayNameYFormattedExternal Name of the Service ServiceInstallErrorControlN-21474836472147483647Severity of error if service fails to start ServiceInstallLoadOrderGroupYFormattedLoadOrderGroup ServiceInstallNameNFormattedInternal Name of the Service ServiceInstallPasswordYFormattedpassword to run service with. (with StartName) ServiceInstallServiceInstallNIdentifierPrimary key, non-localized token. ServiceInstallServiceTypeN-21474836472147483647Type of the service ServiceInstallStartNameYFormattedUser or object name to run service as ServiceInstallStartTypeN04Type of the service ShortcutArgumentsYFormattedThe command-line arguments for the shortcut. ShortcutComponent_NComponent1IdentifierForeign key into the Component table denoting the component whose selection gates the the shortcut creation/deletion. ShortcutDescriptionYTextThe description for the shortcut. ShortcutDirectory_NDirectory1IdentifierForeign key into the Directory table denoting the directory where the shortcut file is created. ShortcutHotkeyY032767The hotkey for the shortcut. It has the virtual-key code for the key in the low-order byte, and the modifier flags in the high-order byte. ShortcutISAttributesYThis is used to store Installshield custom properties of a shortcut. Mainly used in pro project types. ShortcutISCommentsYTextAuthor’s comments on this Shortcut. ShortcutISShortcutNameYTextA non-unique name for the shortcut. Mainly used by pro pro project types. ShortcutIconIndexY-3276732767The icon index for the shortcut. ShortcutIcon_YIcon1IdentifierForeign key into the File table denoting the external icon file for the shortcut. ShortcutNameNTextThe name of the shortcut to be created. ShortcutShortcutNIdentifierPrimary key, non-localized token. ShortcutShowCmdY1;3;7The show command for the application window.The following values may be used. ShortcutTargetNShortcutThe shortcut target. This is usually a property that is expanded to a file or a folder that the shortcut points to. ShortcutWkDirYIdentifierName of property defining location of working directory. SignatureFileNameNTextThe name of the file. This may contain a "short name|long name" pair. SignatureLanguagesYLanguageThe languages supported by the file. SignatureMaxDateY02147483647The maximum creation date of the file. SignatureMaxSizeY02147483647The maximum size of the file. SignatureMaxVersionYTextThe maximum version of the file. SignatureMinDateY02147483647The minimum creation date of the file. SignatureMinSizeY02147483647The minimum size of the file. SignatureMinVersionYTextThe minimum version of the file. SignatureSignatureNIdentifierThe table key. The Signature represents a unique file signature. TextStyleColorY016777215A long integer indicating the color of the string in the RGB format (Red, Green, Blue each 0-255, RGB = R + 256*G + 256^2*B). TextStyleFaceNameNTextA string indicating the name of the font used. Required. The string must be at most 31 characters long. TextStyleSizeN032767The size of the font used. This size is given in our units (1/12 of the system font height). Assuming that the system font is set to 12 point size, this is equivalent to the point size. TextStyleStyleBitsY015A combination of style bits. TextStyleTextStyleNIdentifierName of the style. The primary key of this table. This name is embedded in the texts to indicate a style change. TypeLibComponent_NComponent1IdentifierRequired foreign key into the Component Table, specifying the component for which to return a path when called through LocateComponent. TypeLibCostY02147483647The cost associated with the registration of the typelib. This column is currently optional. TypeLibDescriptionYText TypeLibDirectory_YDirectory1IdentifierOptional. The foreign key into the Directory table denoting the path to the help file for the type library. TypeLibFeature_NFeature1IdentifierRequired foreign key into the Feature Table, specifying the feature to validate or install in order for the type library to be operational. TypeLibLanguageN032767The language of the library. TypeLibLibIDNGuidThe GUID that represents the library. TypeLibVersionY02147483647The version of the library. The major version is in the upper 8 bits of the short integer. The minor version is in the lower 8 bits. UITextKeyNIdentifierA unique key that identifies the particular string. UITextTextYTextThe localized version of the string. UpgradeActionPropertyNUpperCaseThe property to set when a product in this set is found. UpgradeAttributesN02147483647The attributes of this product set. UpgradeISDisplayNameYISUpgradeMsiItem1 UpgradeLanguageYLanguageA comma-separated list of languages for either products in this set or products not in this set. UpgradeRemoveYFormattedThe list of features to remove when uninstalling a product from this set. The default is "ALL". UpgradeUpgradeCodeNGuidThe UpgradeCode GUID belonging to the products in this set. UpgradeVersionMaxYTextThe maximum ProductVersion of the products in this set. The set may or may not include products with this particular version. UpgradeVersionMinYTextThe minimum ProductVersion of the products in this set. The set may or may not include products with this particular version. VerbArgumentYFormattedOptional value for the command arguments. VerbCommandYFormattedThe command text. VerbExtension_NExtension1TextThe extension associated with the table row. VerbSequenceY032767Order within the verbs for a particular extension. Also used simply to specify the default verb. VerbVerbNTextThe verb for the command. _ValidationCategoryY"Text";"Formatted";"Template";"Condition";"Guid";"Path";"Version";"Language";"Identifier";"Binary";"UpperCase";"LowerCase";"Filename";"Paths";"AnyPath";"WildCardFilename";"RegPath";"KeyFormatted";"CustomSource";"Property";"Cabinet";"Shortcut";"URL";"DefaultDir"String category _ValidationColumnNIdentifierName of column _ValidationDescriptionYTextDescription of column _ValidationKeyColumnY132Column to which foreign key connects _ValidationKeyTableYIdentifierFor foreign key, Name of table to which data must link _ValidationMaxValueY-21474836472147483647Maximum value allowed _ValidationMinValueY-21474836472147483647Minimum value allowed _ValidationNullableNY;N;@Whether the column is nullable _ValidationSetYTextSet of values that are permitted _ValidationTableNIdentifierName of table
tomcat-connectors-1.2.41-src/native/iis/installer/iisfilter.vbs0000644000000000000020000000721112446106016023071 0ustar rootbin' ' Licensed to the Apache Software Foundation (ASF) under one or more ' contributor license agreements. See the NOTICE file distributed with ' this work for additional information regarding copyright ownership. ' The ASF licenses this file to You under the Apache License, Version 2.0 ' (the "License"); you may not use this file except in compliance with ' the License. You may obtain a copy of the License at ' ' http://www.apache.org/licenses/LICENSE-2.0 ' ' Unless required by applicable law or agreed to in writing, software ' distributed under the License is distributed on an "AS IS" BASIS, ' WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ' See the License for the specific language governing permissions and ' limitations under the License. ' ' ========================================================================= ' Description: Install script for Tomcat ISAPI redirector ' Author: Mladen Turk ' Version: $Revision: 1647408 $ ' ========================================================================= ' ' Get a handle to the filters for the server - we process all errors ' On Error Resume Next filterName = "jakarta" filterLib = "bin\isapi_redirect.dll" Function IISInstallFilter(filterDir, filterObject) Dim filters Set filters = GetObject(filterObject) If err Then err.clear info "Got Filters " + filters.FilterLoadOrder ' ' Create the filter - if it fails then delete it and try again ' name = filterName info "Creating Filter - " + filterName Dim filter Set filter = filters.Create( "IISFilter", filterName ) If err Then err.clear info "Filter exists - deleting" filters.delete "IISFilter", filterName If err Then info "Error Deleting Filter" IISInstallFilter = 0 Exit Function End If Set filter = filters.Create( "IISFilter", filterName ) If Err Then info "Error Creating Filter" IISInstallFilter = 0 Exit Function End If End If ' ' Set the filter info and save it ' filter.FilterPath = filterDir + filterLib ' filter.FilterEnabled = true filter.FilterDescription = "Tomcat Isapi Redirector" filter.NotifyOrderHigh = true filter.SetInfo info "Created Filter " + filterDir + filterLib ' ' Set the load order - only if it's not in the list already ' On Error goto 0 loadOrders = filters.FilterLoadOrder list = Split( loadOrders, "," ) found = false For each item in list If Trim( item ) = filterName Then found = true Next If found = false Then info "Filter is not in load order - adding now." If Len(loadOrders) <> 0 Then loadOrders = loadOrders + "," filters.FilterLoadOrder = loadOrders + filterName filters.SetInfo info "Added Filter " + filterName Else info "Filter already exists in load order - no update required." End If IISInstallFilter = 1 End Function ' ' Helper function for snafus ' Function fail(message) ' MsgBox " " + message WScript.Quit(1) End function ' ' Helper function for info ' Function info(message) ' MsgBox " " + message End Function info "Installing IIS Filter " + Session.Property("INSTALLDIR") Dim rv rv = 0 rv = IISInstallFilter(Session.Property("INSTALLDIR"), "IIS://LocalHost/W3SVC/1/Filters") If rv = 0 Then rv = IISInstallFilter(Session.Property("INSTALLDIR"), "/LM/W3SVC/Filters") End If If rv = 0 Then rv = IISInstallFilter(Session.Property("INSTALLDIR"), "/LM/W3SVC/1/Filters") End If tomcat-connectors-1.2.41-src/native/iis/installer/log/0000755000000000000020000000000012555256552021157 5ustar rootbintomcat-connectors-1.2.41-src/native/iis/installer/log/README0000644000000000000020000000004212446106016022017 0ustar rootbinTomcat Isapi Redirector log files tomcat-connectors-1.2.41-src/native/iis/installer/License.rtf0000644000000000000020000002522710475557345022510 0ustar rootbin{\rtf1\ansi\ansicpg1252\deff0{\fonttbl{\f0\fswiss\fprq2\fcharset0 Arial;}} \viewkind4\uc1\pard\qc\lang1033\b\f0\fs18 Apache License\par Version 2.0, January 2004\par http://www.apache.org/licenses/\par \b0\par \pard TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\par \par \pard\fi-180\li180 1. Definitions.\par \par \pard\li180 "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.\par \par "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.\par \par "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.\par \par "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.\par \par "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.\par \par "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.\par \par "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).\par \par "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.\par \par "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."\par \par "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.\par \pard\par \pard\fi-180\li180 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.\par \par 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.\par \par 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:\par \pard\par \pard\fi-270\li450 (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and\par \par (b) You must cause any modified files to carry prominent notices stating that You changed the files; and\par \par (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and\par \par (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.\par \pard\par \pard\li180 You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.\par \pard\par \pard\fi-180\li180 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.\par \par 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.\par \par 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.\par \par 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.\par \par 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.\par \pard\par END OF TERMS AND CONDITIONS\par \par APPENDIX: How to apply the Apache License to your work.\par \par To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.\par \par \pard\li180 Copyright [yyyy] [name of copyright owner]\par \par Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at\par \par \pard\li360 http://www.apache.org/licenses/LICENSE-2.0\par \pard\li180\par Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\par \pard\par \b\par } tomcat-connectors-1.2.41-src/native/iis/installer/conf/0000755000000000000020000000000012555256552021323 5ustar rootbintomcat-connectors-1.2.41-src/native/iis/installer/conf/rewrite.properties0000644000000000000020000000213412446106016025106 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # rewrite.properties - IIS # # Form of the file # requested=replacement # # Note: "requested" must be present in the # uriworkermap.properies file and mapped to # the desired worker. # # Next will send requests for /servlets-examples/ as # /examples/servlets/ to the container. # # /servlets-examples/=/examples/servlets/ tomcat-connectors-1.2.41-src/native/iis/installer/conf/workers.properties0000644000000000000020000001351312446266173025137 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Note that the distributed version of this file requires modification # before it is usable. # # Reference documentation: http://tomcat.apache.org/connectors-doc/reference/workers.html # # As a general note, the characters $( and ) are used to reference # property values in other properties. # # Whenever you see a set of lines such as: # x=value # y=$(x)othervalue # # the final value for y will be "valueothervalue" # Define two status worker: # - jk-status for read-only use # - jk-manager for read/write use worker.list=jk-status worker.jk-status.type=status worker.jk-status.read_only=true worker.list=jk-manager worker.jk-manager.type=status # We define a load balancer worker # with name "balancer" worker.list=balancer worker.balancer.type=lb # error_escalation_time: seconds, default = recover_time/2 (=30) # Determines, how fast a detected error should switch from # local error state to global error state # Since: 1.2.28 worker.balancer.error_escalation_time=0 # - max_reply_timeouts: number, default=0 # If there are to many reply timeouts, a worker # is put into the error state, i.e. it will become # unavailable for all sessions residing on the respective # Tomcat. The number of tolerated reply timeouts is # configured with max_reply_timeouts. The number of # timeouts occuring is divided by 2 once a minute and the # resulting counter is compared against max_reply_timeouts. # If you set max_reply_timeouts to N and the errors are # occuring equally distributed over time, you will # tolerate N/2 errors per minute. If they occur in a burst # you will tolerate N errors. # Since: 1.2.24 worker.balancer.max_reply_timeouts=10 # Now we add members to the load balancer # First member is "node1", most # attributes are inherited from the # template "worker.template". worker.balancer.balance_workers=node1 worker.node1.reference=worker.template worker.node1.host=localhost worker.node1.port=8109 # Activation allows to configure # whether this node should actually be used # A: active (use node fully) # D: disabled (only use, if sticky session needs this node) # S: stopped (do not use) # Since: 1.2.19 worker.node1.activation=A # Second member is "node2", most # attributes are inherited from the # template "worker.template". worker.balancer.balance_workers=node2 worker.node2.reference=worker.template worker.node2.host=localhost worker.node2.port=8209 # Activation allows to configure # whether this node should actually be used # A: active (use node fully) # D: disabled (only use, if sticky session needs this node) # S: stopped (do not use) # Since: 1.2.19 worker.node2.activation=A # Finally we put the parameters # which should apply to all our ajp13 # workers into the referenced template # - Type is ajp13 worker.template.type=ajp13 # - socket_connect_timeout: milliseconds, default=0 # Since: 1.2.27 worker.template.socket_connect_timeout=5000 # - socket_keepalive: boolean, default=false # Should we send TCP keepalive packets # when connection is idle (socket option)? worker.template.socket_keepalive=true # - ping_mode: Character, default=none # When should we use cping/cpong connection probing? # C = directly after establishing a new connection # P = directly before sending each request # I = in regular intervals for idle connections # using the watchdog thread # A = all of the above # Since: 1.2.27 worker.template.ping_mode=A # - ping_timeout: milliseconds, default=10000 # Wait timeout for cpong after cping # Can be overwritten for modes C and P # Using connect_timeout and prepost_timeout. # Since: 1.2.27 worker.template.ping_timeout=10000 # - connection_pool_minsize: number, default=connection_pool_size # Lower pool size when shrinking pool due # to idle connections # We want all connections to be closed when # idle for a long time in order to prevent # firewall problems. # Since: 1.2.16 worker.template.connection_pool_minsize=0 # - connection_pool_timeout: seconds, default=0 # Idle time, before a connection is eligible # for being closed (pool shrinking). # This should be the same value as keepAliveTimeout # (if it is set explicitly) or connectionTimeout # in the Tomcat AJP connector, but there it is # milliseconds, here seconds. worker.template.connection_pool_timeout=600 # - reply_timeout: milliseconds, default=0 # Any pause longer than this timeout during waiting # for a part of the reply will abort handling the request # in mod_jk. The request will proceed running in # Tomcat, but the web server resources will be freed # and an error is send to the client. # For individual requests, the timeout can be overwritten # by the Apache environment variable JK_REPLY_TIMEOUT. # JK_REPLY_TIMEOUT since: 1.2.27 worker.template.reply_timeout=300000 # - recovery_options: number, default=0 # Bit mask to configure, if a request, which was send # to a backend successfully, should be retried on another backend # in case there's a problem with the response. # Value "3" disables retries, whenever a part of the request was # successfully send to the backend. worker.template.recovery_options=3 tomcat-connectors-1.2.41-src/native/iis/installer/conf/uriworkermap.properties0000644000000000000020000000266512446106016026165 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # uriworkermap.properties # # Use for IIS or with the Apache web server as an alternative # to JkMount and JkUnmount # # This file provides sample mappings for the example # worker "balancer" defined in workermap.properties. # The general syntax for this file is: # [URL]=[Worker name] /admin/*=balancer /manager/*=balancer /examples/*=balancer # Optionally filter out all .jpg files inside that context # For no mapping the url has to start with exclamation mark (!) !/examples/*.jpg=balancer # # Mount jk status and manager # For production servers you will need to # secure the access to the /jk-manager and # /jk-status urls # /jk-manager=jk-manager /jk-status=jk-status tomcat-connectors-1.2.41-src/native/iis/installer/conf/isapi_redirect.properties0000644000000000000020000000701012446106016026411 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Note that the distributed version of this file requires modification # before it is usable. # # Reference documentation: http://tomcat.apache.org/connectors-doc/reference/iis.html # # Configuration file for the Tomcat ISAPI Redirector # The path to the ISAPI Redirector Extension, relative to the website # This must be in a virtual directory with execute privileges extension_uri=/jakarta/isapi_redirect.dll # Full path to the log file for the ISAPI Redirector # Use of strftime(3) format in the name is supported. log_file=c:\tomcat\logs\isapi_redirect.%Y-%m-%d.log # Rotate the log file every day log_rotationtime=86400 # Log level (trace, debug, info, warn or error) log_level=info # Full path to the workers.properties file worker_file=c:\tomcat\conf\workers.properties # Full path to the uriworkermap.properties file worker_mount_file=c:\tomcat\conf\uriworkermap.properties # Full path to the rewrite.properties file rewrite_rule_file= # Specify the time in seconds upon which the worker_mount_file will be reloaded. worker_mount_reload= # If this is set to true, URL session suffixes of the form ";jsessionid=..." # get stripped of URLs if the are served locally by the web server. # Default value is false. strip_session=false # If this is set to true, URLs containing percent signs '%' or backslashes '\' # after decoding will be rejected. Most web apps do not use such URLs. # By enabling "reject_unsafe" you can block several well known URL encoding # attacks. # Default value is false. reject_unsafe=false # A value representing the watchdog thread interval in seconds. The workers are # maintained periodically by a background thread running periodically every # watchdog_interval seconds. Worker maintenance checks for idle connections, # corrects load status and is able to detect backend health status. # # The maintenance only happens, if since the last maintenance at least # worker.maintain seconds have passed. So setting the watchdog_interval much # smaller than worker.maintain is not useful. # # The default value is 0 seconds, meaning the watchdog thread will not be # created, and the maintenance is done in combination with normal requests # instead. watchdog_interval=0 # A string value representing the error page url redirection when a backend # returns a non-200 response. This directive can be used to customise the error # messages returned from the backend server. # The url must point to a valid server url and can contain format string number # (%d) that can be used to separate the pages by error number. The redirect url # in that case is formatted by replacing %d from error_page with the returned # error status code. error_page= # If this is set to true, chunked response encoding is supported. # The default value is false. enable_chunked_encoding=false tomcat-connectors-1.2.41-src/native/iis/Makefile.amd640000644000000000000020000001613211726114766020755 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Microsoft Developer Studio Generated NMAKE File, Based on isapi.dsp # Use Platform SDK: # SetEnv.cmd /X64 /RETAIL # nmake -f Makefile.amd64 # TARGET=isapi_redirect$(SO_VERSION) CPP=cl.exe MTL=midl.exe RSC=rc.exe OUTDIR=.\Release_amd64 INTDIR=.\Release_amd64 # Begin Custom Macros OutDir=.\Release_amd64 # End Custom Macros ALL : "pcre_amd64" "$(OUTDIR)\$(TARGET).dll" !IF "$(RECURSE)" == "1" CLEAN :"pcre_amd64CLEAN" !ELSE CLEAN : !ENDIF -@erase "$(INTDIR)\jk.res" -@erase "$(INTDIR)\isapi_redirector_src.idb" -@erase "$(INTDIR)\isapi_redirector_src.pdb" -@erase "$(INTDIR)\jk_ajp12_worker.obj" -@erase "$(INTDIR)\jk_ajp13.obj" -@erase "$(INTDIR)\jk_ajp13_worker.obj" -@erase "$(INTDIR)\jk_ajp14.obj" -@erase "$(INTDIR)\jk_ajp14_worker.obj" -@erase "$(INTDIR)\jk_ajp_common.obj" -@erase "$(INTDIR)\jk_connect.obj" -@erase "$(INTDIR)\jk_context.obj" -@erase "$(INTDIR)\jk_isapi_plugin.obj" -@erase "$(INTDIR)\jk_lb_worker.obj" -@erase "$(INTDIR)\jk_map.obj" -@erase "$(INTDIR)\jk_md5.obj" -@erase "$(INTDIR)\jk_msg_buff.obj" -@erase "$(INTDIR)\jk_nwmain.obj" -@erase "$(INTDIR)\jk_pool.obj" -@erase "$(INTDIR)\jk_shm.obj" -@erase "$(INTDIR)\jk_sockbuf.obj" -@erase "$(INTDIR)\jk_status.obj" -@erase "$(INTDIR)\jk_uri_worker_map.obj" -@erase "$(INTDIR)\jk_url.obj" -@erase "$(INTDIR)\jk_util.obj" -@erase "$(INTDIR)\jk_worker.obj" -@erase "$(OUTDIR)\$(TARGET).dll" -@erase "$(OUTDIR)\isapi_redirect.exp" -@erase "$(OUTDIR)\isapi_redirect.lib" -@erase "$(OUTDIR)\$(TARGET).pdb" "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\isapi.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib strsafe.lib $(EXTRA_LIBS) /nologo /dll /incremental:no /pdb:"$(OUTDIR)\$(TARGET).pdb" /debug /machine:AMD64 /def:".\isapi.def" /out:"$(OUTDIR)\$(TARGET).dll" /implib:"$(OUTDIR)\isapi_redirect.lib" DEF_FILE= \ ".\isapi.def" LINK32_OBJS= \ "$(INTDIR)\jk_ajp12_worker.obj" \ "$(INTDIR)\jk_ajp13.obj" \ "$(INTDIR)\jk_ajp13_worker.obj" \ "$(INTDIR)\jk_ajp14.obj" \ "$(INTDIR)\jk_ajp14_worker.obj" \ "$(INTDIR)\jk_ajp_common.obj" \ "$(INTDIR)\jk_connect.obj" \ "$(INTDIR)\jk_context.obj" \ "$(INTDIR)\jk_isapi_plugin.obj" \ "$(INTDIR)\jk_lb_worker.obj" \ "$(INTDIR)\jk_map.obj" \ "$(INTDIR)\jk_md5.obj" \ "$(INTDIR)\jk_msg_buff.obj" \ "$(INTDIR)\jk_nwmain.obj" \ "$(INTDIR)\jk_pool.obj" \ "$(INTDIR)\jk_shm.obj" \ "$(INTDIR)\jk_sockbuf.obj" \ "$(INTDIR)\jk_status.obj" \ "$(INTDIR)\jk_uri_worker_map.obj" \ "$(INTDIR)\jk_url.obj" \ "$(INTDIR)\jk_util.obj" \ "$(INTDIR)\jk_worker.obj" \ "$(INTDIR)\jk.res" \ ".\pcre\Release_amd64\pcre.lib" "$(OUTDIR)\$(TARGET).dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << IF EXIST $(OUTDIR)\$(TARGET).manifest \ mt -nologo -manifest $(OUTDIR)\$(TARGET).manifest -outputresource:$(OUTDIR)\$(TARGET).dll;2 CPP_PROJ=-nologo -MD -W3 -O2 -Ob2 -Oy- -Zi -EHsc /I "..\common" /I "pcre" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_AMD64_=1" -DWIN64 /D "_WIN64" /D "JK_ISAPI" /D "ISAPI_EXPORTS" /D "HAS_PCRE" /D "PCRE_STATIC" $(CFLAGS) /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\isapi_redirector_src" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 RSC_PROJ=/l 0x409 /fo"$(INTDIR)\jk.res" /i "..\common" /d "JK_ISAPI" /d "NDEBUG" SOURCE=..\common\jk.rc "$(INTDIR)\jk.res" : $(SOURCE) "$(INTDIR)" $(RSC) $(RSC_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp12_worker.c "$(INTDIR)\jk_ajp12_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp13.c "$(INTDIR)\jk_ajp13.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp13_worker.c "$(INTDIR)\jk_ajp13_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp14.c "$(INTDIR)\jk_ajp14.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp14_worker.c "$(INTDIR)\jk_ajp14_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp_common.c "$(INTDIR)\jk_ajp_common.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_connect.c "$(INTDIR)\jk_connect.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_context.c "$(INTDIR)\jk_context.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=.\jk_isapi_plugin.c "$(INTDIR)\jk_isapi_plugin.obj" : $(SOURCE) "$(INTDIR)" SOURCE=..\common\jk_lb_worker.c "$(INTDIR)\jk_lb_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_map.c "$(INTDIR)\jk_map.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_md5.c "$(INTDIR)\jk_md5.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_msg_buff.c "$(INTDIR)\jk_msg_buff.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_nwmain.c "$(INTDIR)\jk_nwmain.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_pool.c "$(INTDIR)\jk_pool.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_shm.c "$(INTDIR)\jk_shm.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_sockbuf.c "$(INTDIR)\jk_sockbuf.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_status.c "$(INTDIR)\jk_status.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_uri_worker_map.c "$(INTDIR)\jk_uri_worker_map.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_url.c "$(INTDIR)\jk_url.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_util.c "$(INTDIR)\jk_util.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_worker.c "$(INTDIR)\jk_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) "pcre_amd64" : cd ".\pcre" $(MAKE) /$(MAKEFLAGS) /F ".\pcre.amd64" cd ".." "pcre_amd64CLEAN" : cd ".\pcre" $(MAKE) /$(MAKEFLAGS) /F ".\pcre.amd64" CLEAN cd ".." tomcat-connectors-1.2.41-src/native/iis/README0000644000000000000020000000277412555244075017270 0ustar rootbinABOUT ----- The Tomcat redirector was developed using Visual C++ Ver.6.0, so having this environment is a prerequisite if you want to perform a custom build. REQUIREMENT ----------- * MS VC 6.0 (+ update, latest service pack is sp5) isapi_redirector.dll can be built using the command line tools, or from within the Visual Studio IDE Workbench. The command line build requires the environment to reflect the PATH, INCLUDE, LIB and other variables that can be configured with the vcvars32 batch file: "c:\Program Files\DevStudio\VC\Bin\vcvars32.bat" * MS PLATFORM SDK Visual C++ 6.0 builds require an updated Microsoft Windows Platform SDK (http://www.microsoft.com/msdownload/platformsdk/sdkupdate/) to enable some isapi_redirector.dll features. For command line builds, the Platform SDK environment is prepared by the setenv batch file: "c:\Program Files\Microsoft Platform SDK\setenv.bat" Note that the Windows Platform SDK is only needed if you want authenticate using IIS to compile a isapi_redirector.dll. BUILDING -------- The steps that you need to take are: 1. Change directory to the isapi redirector plugins source directory. 2. Execute the following command: nmake -f Makefile.x86 [SO_VERSION=-1.2.41] An alternative will be to open the isapi workspace file (isapi.dsw) in msdev and build it using the build menu. * USE_CGI_HEADERS If provided at compile time the isapi_redirect will use alternate header names. TODO: Needs a proper documentation. tomcat-connectors-1.2.41-src/native/aclocal.m40000644000000000000020000125546512555256560017476 0ustar rootbin# generated automatically by aclocal 1.14.1 -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],, [m4_warning([this file was generated for autoconf 2.69. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008, 2009, 2010, 2011 Free Software # Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 57 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl _LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}]) dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl _LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_WITH_SYSROOT])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PREPARE_SED_QUOTE_VARS # -------------------------- # Define a few sed substitution that help us do robust quoting. m4_defun([_LT_PREPARE_SED_QUOTE_VARS], [# Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ]) # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "$" | $SED "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$[]1 _LTECHO_EOF' } # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done _LT_OUTPUT_LIBTOOL_INIT ]) # _LT_GENERATED_FILE_INIT(FILE, [COMMENT]) # ------------------------------------ # Generate a child script FILE with all initialization necessary to # reuse the environment learned by the parent script, and make the # file executable. If COMMENT is supplied, it is inserted after the # `#!' sequence but before initialization text begins. After this # macro, additional text can be appended to FILE to form the body of # the child script. The macro ends with non-zero status if the # file could not be fully written (such as if the disk is full). m4_ifdef([AS_INIT_GENERATED], [m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])], [m4_defun([_LT_GENERATED_FILE_INIT], [m4_require([AS_PREPARE])]dnl [m4_pushdef([AS_MESSAGE_LOG_FD])]dnl [lt_write_fail=0 cat >$1 <<_ASEOF || lt_write_fail=1 #! $SHELL # Generated by $as_me. $2 SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$1 <<\_ASEOF || lt_write_fail=1 AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 _ASEOF test $lt_write_fail = 0 && chmod +x $1[]dnl m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) _LT_GENERATED_FILE_INIT(["$CONFIG_LT"], [# Run this file to recreate a libtool stub with the current configuration.]) cat >>"$CONFIG_LT" <<\_LTEOF lt_cl_silent=false exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2011 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_REPLACE_SHELLFNS mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Go], [_LT_LANG(GO)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG m4_ifndef([AC_PROG_GO], [ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_GO. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # m4_defun([AC_PROG_GO], [AC_LANG_PUSH(Go)dnl AC_ARG_VAR([GOC], [Go compiler command])dnl AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl _AC_ARG_VAR_LDFLAGS()dnl AC_CHECK_TOOL(GOC, gccgo) if test -z "$GOC"; then if test -n "$ac_tool_prefix"; then AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo]) fi fi if test -z "$GOC"; then AC_CHECK_PROG(GOC, gccgo, gccgo, false) fi ])#m4_defun ])#m4_ifndef # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([AC_PROG_GO], [LT_LANG(GO)], [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) dnl AC_DEFUN([AC_LIBTOOL_RC], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test $_lt_result -eq 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load], [lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&AS_MESSAGE_LOG_FD elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then lt_cv_ld_force_load=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES([TAG]) # --------------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported if test "$lt_cv_ld_force_load" = "yes"; then _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes], [FC], [_LT_TAGVAR(compiler_needs_object, $1)=yes]) else _LT_TAGVAR(whole_archive_flag_spec, $1)='' fi _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX([TAGNAME]) # ---------------------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. # Store the results from the different compilers for each TAGNAME. # Allow to override them for all tags through lt_cv_aix_libpath. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl if test "${lt_cv_aix_libpath+set}" = set; then aix_libpath=$lt_cv_aix_libpath else AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])], [AC_LINK_IFELSE([AC_LANG_PROGRAM],[ lt_aix_libpath_sed='[ /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }]' _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib" fi ]) aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1]) fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [m4_divert_text([M4SH-INIT], [$1 ])])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Find how we can fake an echo command that does not interpret backslash. # In particular, with Autoconf 2.60 or later we add some code to the start # of the generated configure script which will find a shell with a builtin # printf (which we can use as an echo command). m4_defun([_LT_PROG_ECHO_BACKSLASH], [ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO AC_MSG_CHECKING([how to print strings]) # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $[]1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "$*" } case "$ECHO" in printf*) AC_MSG_RESULT([printf]) ;; print*) AC_MSG_RESULT([print -r]) ;; *) AC_MSG_RESULT([cat]) ;; esac m4_ifdef([_AS_DETECT_SUGGESTED], [_AS_DETECT_SUGGESTED([ test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test "X`printf %s $ECHO`" = "X$ECHO" \ || test "X`print -r -- $ECHO`" = "X$ECHO" )])]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that protects backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], [AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [ --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified).], [], [with_sysroot=no]) dnl lt_sysroot will always be passed unquoted. We quote it here dnl in case the user passed a directory name. lt_sysroot= case ${with_sysroot} in #( yes) if test "$GCC" = yes; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) AC_MSG_RESULT([${with_sysroot}]) AC_MSG_ERROR([The sysroot must be an absolute path.]) ;; esac AC_MSG_RESULT([${lt_sysroot:-no}]) _LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl [dependent libraries, and in which our libraries should be installed.])]) # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `/usr/bin/file conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; *-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD="${LD-ld}_sol2" fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_PROG_AR # ----------- m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} : ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM], [echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -eq 0; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a AC_TRY_EVAL([lt_ar_try]) if test "$ac_status" -ne 0; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a ]) ]) if test "x$lt_cv_ar_at_file" = xno; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi _LT_DECL([], [archiver_list_spec], [1], [How to feed a file listing to the archiver]) ])# _LT_PROG_AR # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [_LT_PROG_AR AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) _LT_DECL([], [lock_old_archive_extraction], [0], [Whether to use a lock for old archive extraction]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisbility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;; *) lt_sed_strip_eq="s,=/,/,g" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's,/\([[A-Za-z]]:\),\1,g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl*) # Native MSVC libname_spec='$name' soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' library_names_spec='${libname}.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec="$LIB" if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC wrapper library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[23]].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=yes sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[[3-9]]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath], [lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [lt_cv_shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir ]) shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [install_override_mode], [1], [Permission mode override for installation of shared libraries]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PROG_ECHO_BACKSLASH])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method = "file_magic"]) _LT_DECL([], [file_magic_glob], [1], [How to find potential files when deplibs_check_method = "file_magic"]) _LT_DECL([], [want_nocaseglob], [1], [Find potential files using nocaseglob when deplibs_check_method = "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols" ;; *) DUMPBIN=: ;; esac fi AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # _LT_CHECK_SHAREDLIB_FROM_LINKLIB # -------------------------------- # how to determine the name of the shared library # associated with a specific link library. # -- PORTME fill in with the dynamic library characteristics m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB], [m4_require([_LT_DECL_EGREP]) m4_require([_LT_DECL_OBJDUMP]) m4_require([_LT_DECL_DLLTOOL]) AC_CACHE_CHECK([how to associate runtime and link libraries], lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh # decide which to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd="$ECHO" ;; esac ]) sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO _LT_DECL([], [sharedlib_from_linklib_cmd], [1], [Command to associate shared and link libraries]) ])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB # _LT_PATH_MANIFEST_TOOL # ---------------------- # locate the manifest tool m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], [lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest*]) if test "x$lt_cv_path_mainfest_tool" != xyes; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl ])# _LT_PATH_MANIFEST_TOOL # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then case $cc_basename in nvcc*) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;; *) _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;; esac _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE) /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT@&t@_DLSYM_CONST #elif defined(__osf__) /* This system does not cope well with relocations in const data. */ # define LT@&t@_DLSYM_CONST #else # define LT@&t@_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT@&t@_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then nm_file_list_spec='@' fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) _LT_DECL([], [nm_file_list_spec], [1], [Specify filename containing input files for $NM]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL 8.0, 9.0 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. _LT_TAGVAR(lt_prog_compiler_static, $1)= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker ' if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; nagfor*) # NAG Fortran compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; *Sun\ F* | *Sun*Fortran*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Intel*\ [[CF]]*Compiler*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; *Portland\ Group*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_CACHE_CHECK([for $compiler option to produce PIC], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global defined # symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] ;; esac ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test "$with_gnu_ld" = yes; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;; *\ \(GNU\ Binutils\)\ [[3-9]]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test "$lt_use_gnu_ld_interface" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm # Also, AIX nm treats weak defined symbols like other global # defined symbols, whereas GNU nm marks them as "W". if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl*) # Native MSVC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes && test "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) m4_if($1, [], [ # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) _LT_LINKER_OPTION([if $CC understands -b], _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'], [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])], [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags']) ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol], [lt_cv_irix_exported_symbol], [save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE( [AC_LANG_SOURCE( [AC_LANG_CASE([C], [[int foo (void) { return 0; }]], [C++], [[int foo (void) { return 0; }]], [Fortran 77], [[ subroutine foo end]], [Fortran], [[ subroutine foo end]])])], [lt_cv_irix_exported_symbol=yes], [lt_cv_irix_exported_symbol=no]) LDFLAGS="$save_LDFLAGS"]) if test "$lt_cv_irix_exported_symbol" = yes; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_CACHE_CHECK([whether -lc should be explicitly linked in], [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1), [$RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no else lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* ]) _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [postlink_cmds], [2], [Commands necessary for finishing linking programs]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_PATH_MANIFEST_TOOL])dnl if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX([$1]) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' if test "$with_gnu_ld" = yes; then # We only use this code for GNU lds that support --whole-archive. _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' fi _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl*) # Native MSVC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(file_list_spec, $1)='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp; else $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes # Don't use ranlib _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib' _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile="$lt_outputfile.exe" lt_tool_outputfile="$lt_tool_outputfile.exe" ;; esac~ func_to_tool_file "$lt_outputfile"~ if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(link_all_deplibs, $1)=yes ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~ '"$_LT_TAGVAR(old_archive_cmds, $1)" _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~ '"$_LT_TAGVAR(reload_cmds, $1)" ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_FUNC_STRIPNAME_CNF # ---------------------- # func_stripname_cnf prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # # This function is identical to the (non-XSI) version of func_stripname, # except this one can be used by m4 code that may be executed by configure, # rather than the libtool script. m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl AC_REQUIRE([_LT_DECL_SED]) AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH]) func_stripname_cnf () { case ${2} in .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;; esac } # func_stripname_cnf ])# _LT_FUNC_STRIPNAME_CNF # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF package foo func foo() { } _LT_EOF ]) _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case ${prev}${p} in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test "$pre_test_object_deps_done" = no; then case ${prev} in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_LANG_PUSH(Fortran 77) if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${F77-"f77"} CFLAGS=$FFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" CFLAGS="$lt_save_CFLAGS" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_LANG_PUSH(Fortran) if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC lt_save_CFLAGS=$CFLAGS CC=${FC-"f95"} CFLAGS=$FCFLAGS compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} CFLAGS=$GCJFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_GO_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Go compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GO_CONFIG], [AC_REQUIRE([LT_PROG_GO])dnl AC_LANG_SAVE # Source file extension for Go test sources. ac_ext=go # Object file extension for compiled Go test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="package main; func main() { }" # Code to be used in simple link tests lt_simple_link_test_code='package main; func main() { }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC=yes CC=${GOC-"gccgo"} CFLAGS=$GOFLAGS compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # Go did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(reload_flag, $1)=$reload_flag _LT_TAGVAR(reload_cmds, $1)=$reload_cmds if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_GO_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_CFLAGS=$CFLAGS lt_save_GCC=$GCC GCC= CC=${RC-"windres"} CFLAGS= compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_GO # ---------- AC_DEFUN([LT_PROG_GO], [AC_CHECK_TOOL(GOC, gccgo,) ]) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_DLLTOOL # ---------------- # Ensure DLLTOOL variable is set. m4_defun([_LT_DECL_DLLTOOL], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program]) AC_SUBST([DLLTOOL]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,b/c, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY) # ------------------------------------------------------ # In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and # '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY. m4_defun([_LT_PROG_FUNCTION_REPLACE], [dnl { sed -e '/^$1 ()$/,/^} # $1 /c\ $1 ()\ {\ m4_bpatsubsts([$2], [$], [\\], [^\([ ]\)], [\\\1]) } # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: ]) # _LT_PROG_REPLACE_SHELLFNS # ------------------------- # Replace existing portable implementations of several shell functions with # equivalent extended shell implementations where those features are available.. m4_defun([_LT_PROG_REPLACE_SHELLFNS], [if test x"$xsi_shell" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}"]) _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"}]) _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl func_split_long_opt_name=${1%%=*} func_split_long_opt_arg=${1#*=}]) _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl func_split_short_opt_arg=${1#??} func_split_short_opt_name=${1%"$func_split_short_opt_arg"}]) _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac]) _LT_PROG_FUNCTION_REPLACE([func_xform], [ func_xform_result=${1%.*}.lo]) _LT_PROG_FUNCTION_REPLACE([func_arith], [ func_arith_result=$(( $[*] ))]) _LT_PROG_FUNCTION_REPLACE([func_len], [ func_len_result=${#1}]) fi if test x"$lt_shell_append" = xyes; then _LT_PROG_FUNCTION_REPLACE([func_append], [ eval "${1}+=\\${2}"]) _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl func_quote_for_eval "${2}" dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \ eval "${1}+=\\\\ \\$func_quote_for_eval_result"]) # Save a `func_append' function call where possible by direct use of '+=' sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: else # Save a `func_append' function call even when '+=' is not available sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \ && mv -f "$cfgfile.tmp" "$cfgfile" \ || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp") test 0 -eq $? || _lt_function_replace_fail=: fi if test x"$_lt_function_replace_fail" = x":"; then AC_MSG_WARN([Unable to substitute extended shell functions in $ofile]) fi ]) # _LT_PATH_CONVERSION_FUNCTIONS # ----------------------------- # Determine which file name conversion functions should be used by # func_to_host_file (and, implicitly, by func_to_host_path). These are needed # for certain cross-compile configurations and native mingw. m4_defun([_LT_PATH_CONVERSION_FUNCTIONS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl AC_MSG_CHECKING([how to convert $build file names to $host format]) AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac ]) to_host_file_cmd=$lt_cv_to_host_file_cmd AC_MSG_RESULT([$lt_cv_to_host_file_cmd]) _LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd], [0], [convert $build file names to $host format])dnl AC_MSG_CHECKING([how to convert $build file names to toolchain format]) AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac ]) to_tool_file_cmd=$lt_cv_to_tool_file_cmd AC_MSG_RESULT([$lt_cv_to_tool_file_cmd]) _LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd], [0], [convert $build files to toolchain format])dnl ])# _LT_PATH_CONVERSION_FUNCTIONS # Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, # Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 7 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [1], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for lt_pkg in $withval; do IFS="$lt_save_ifs" if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS="$lt_save_ifs" ;; esac], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) # ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # @configure_input@ # serial 3337 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.4.2]) m4_define([LT_PACKAGE_REVISION], [1.3337]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.4.2' macro_revision='1.3337' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 5 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS], [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])]) m4_ifndef([_LT_AC_PROG_CXXCPP], [AC_DEFUN([_LT_AC_PROG_CXXCPP])]) m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS], [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])]) m4_ifndef([_LT_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_LT_PROG_F77])]) m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) # Copyright (C) 2002-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.14' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.14.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.14.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named 'Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running 'make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "$am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each '.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from 'make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2013 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR tomcat-connectors-1.2.41-src/native/README.txt0000644000000000000020000000346411731402243017303 0ustar rootbin Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. $Id: README.txt 1302146 2012-03-18 15:52:03Z rjung $ README for tomcat-connectors (mod_jk) ===================================== What is tomcat-connector? ------------------------- tomcat-connectors is a project that provides web server connectors for the Tomcat servlet engine. The supported web servers are the Apache HTTP Server 1.3 and 2.x, Microsoft IIS and the Netscape/IPlanet web server. The AJP protocol used by the connector is supported in all Tomcat versions starting with Tomcat 3.2. Some other back end servers also support the AJP protocol. Main features of the tomcat-connectors are fault tolerance, load balancing, dynamic configuration, flexibility and robustness. The project was based on the original mod_jk code and keeps maintaining it. Originally the project also provided the Java parts of the connectors used inside Tomcat. These parts have since then been moved directly into the Tomcat source. How do i build it? ------------------ Just take a look at BUILDING.txt Where are the docs? ------------------- In the docs directory. tomcat-connectors-1.2.41-src/native/docs/0000755000000000000020000000000012555256551016544 5ustar rootbintomcat-connectors-1.2.41-src/native/docs/api/0000755000000000000020000000000012555256552017316 5ustar rootbintomcat-connectors-1.2.41-src/native/docs/api/README.txt0000644000000000000020000000165310666607673021026 0ustar rootbin Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. To generate the API documentation for the mod_jk library, simply invoke make apidocs from the mod_jk Library root source path. (tomcat-connectors/jk/native) tomcat-connectors-1.2.41-src/native/common/0000755000000000000020000000000012555256561017105 5ustar rootbintomcat-connectors-1.2.41-src/native/common/jk_ajp_common.h0000644000000000000020000004027312477544555022100 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: common stuff for bi-directional protocol ajp13/ajp14. * * Author: Gal Shachor * * Author: Henri Gomez * * Version: $Revision: 1665454 $ * ***************************************************************************/ #ifndef JK_AJP_COMMON_H #define JK_AJP_COMMON_H #include "jk_service.h" #include "jk_msg_buff.h" #include "jk_shm.h" #include "jk_mt.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define JK_AJP_STATE_IDLE (0) #define JK_AJP_STATE_OK (1) #define JK_AJP_STATE_ERROR (2) #define JK_AJP_STATE_PROBE (3) #define JK_AJP_STATE_DEF (JK_AJP_STATE_IDLE) #define JK_AJP_STATE_TEXT_IDLE ("OK/IDLE") #define JK_AJP_STATE_TEXT_OK ("OK") #define JK_AJP_STATE_TEXT_ERROR ("ERR") #define JK_AJP_STATE_TEXT_PROBE ("ERR/PRB") #define JK_AJP_STATE_TEXT_MAX (JK_AJP_STATE_PROBE) #define JK_AJP_STATE_TEXT_DEF (JK_AJP_STATE_TEXT_IDLE) /* * Conditional request attributes * */ #define SC_A_CONTEXT (unsigned char)1 #define SC_A_SERVLET_PATH (unsigned char)2 #define SC_A_REMOTE_USER (unsigned char)3 #define SC_A_AUTH_TYPE (unsigned char)4 #define SC_A_QUERY_STRING (unsigned char)5 #define SC_A_ROUTE (unsigned char)6 #define SC_A_SSL_CERT (unsigned char)7 #define SC_A_SSL_CIPHER (unsigned char)8 #define SC_A_SSL_SESSION (unsigned char)9 #define SC_A_REQ_ATTRIBUTE (unsigned char)10 #define SC_A_SSL_KEY_SIZE (unsigned char)11 /* only in if JkOptions +ForwardKeySize */ #define SC_A_SECRET (unsigned char)12 #define SC_A_STORED_METHOD (unsigned char)13 #define SC_A_ARE_DONE (unsigned char)0xFF /* * AJP private request attributes */ /* * The following request attribute is recognized by Tomcat * to contain the name of the ssl protocol used */ #define SC_A_SSL_PROTOCOL ("AJP_SSL_PROTOCOL") /* * The following request attribute is recognized by Tomcat * to contain the forwarded remote port. */ #define SC_A_REQ_REMOTE_PORT ("AJP_REMOTE_PORT") /* * The following request attribute is recognized by Tomcat * to contain the forwarded local ip address. */ #define SC_A_REQ_LOCAL_ADDR ("AJP_LOCAL_ADDR") /* * JK public request attributes * * Activation state of the worker in the load balancer. * Can be any of the JK_LB_ACTIVATION_TEXT_* strings * from jk_lb_worker.h. */ #define SC_A_JK_LB_ACTIVATION ("JK_LB_ACTIVATION") /* * Request methods, coded as numbers instead of strings. * The list of methods was taken from Section 5.1.1 of RFC 2616, * RFC 2518, the ACL IETF draft, and the DeltaV IESG Proposed Standard. * Method = "OPTIONS" * | "GET" * | "HEAD" * | "POST" * | "PUT" * | "DELETE" * | "TRACE" * | "PROPFIND" * | "PROPPATCH" * | "MKCOL" * | "COPY" * | "MOVE" * | "LOCK" * | "UNLOCK" * | "ACL" * | "REPORT" * | "VERSION-CONTROL" * | "CHECKIN" * | "CHECKOUT" * | "UNCHECKOUT" * | "SEARCH" * | "MKWORKSPACE" * | "UPDATE" * | "LABEL" * | "MERGE" * | "BASELINE-CONTROL" * | "MKACTIVITY" * */ #define SC_M_OPTIONS (unsigned char)1 #define SC_M_GET (unsigned char)2 #define SC_M_HEAD (unsigned char)3 #define SC_M_POST (unsigned char)4 #define SC_M_PUT (unsigned char)5 #define SC_M_DELETE (unsigned char)6 #define SC_M_TRACE (unsigned char)7 #define SC_M_PROPFIND (unsigned char)8 #define SC_M_PROPPATCH (unsigned char)9 #define SC_M_MKCOL (unsigned char)10 #define SC_M_COPY (unsigned char)11 #define SC_M_MOVE (unsigned char)12 #define SC_M_LOCK (unsigned char)13 #define SC_M_UNLOCK (unsigned char)14 #define SC_M_ACL (unsigned char)15 #define SC_M_REPORT (unsigned char)16 #define SC_M_VERSION_CONTROL (unsigned char)17 #define SC_M_CHECKIN (unsigned char)18 #define SC_M_CHECKOUT (unsigned char)19 #define SC_M_UNCHECKOUT (unsigned char)20 #define SC_M_SEARCH (unsigned char)21 #define SC_M_MKWORKSPACE (unsigned char)22 #define SC_M_UPDATE (unsigned char)23 #define SC_M_LABEL (unsigned char)24 #define SC_M_MERGE (unsigned char)25 #define SC_M_BASELINE_CONTROL (unsigned char)26 #define SC_M_MKACTIVITY (unsigned char)27 #define SC_M_JK_STORED (unsigned char)0xFF /* * Frequent request headers, these headers are coded as numbers * instead of strings. * * Accept * Accept-Charset * Accept-Encoding * Accept-Language * Authorization * Connection * Content-Type * Content-Length * Cookie * Cookie2 * Host * Pragma * Referer * User-Agent * */ #define SC_ACCEPT (unsigned short)0xA001 #define SC_ACCEPT_CHARSET (unsigned short)0xA002 #define SC_ACCEPT_ENCODING (unsigned short)0xA003 #define SC_ACCEPT_LANGUAGE (unsigned short)0xA004 #define SC_AUTHORIZATION (unsigned short)0xA005 #define SC_CONNECTION (unsigned short)0xA006 #define SC_CONTENT_TYPE (unsigned short)0xA007 #define SC_CONTENT_LENGTH (unsigned short)0xA008 #define SC_COOKIE (unsigned short)0xA009 #define SC_COOKIE2 (unsigned short)0xA00A #define SC_HOST (unsigned short)0xA00B #define SC_PRAGMA (unsigned short)0xA00C #define SC_REFERER (unsigned short)0xA00D #define SC_USER_AGENT (unsigned short)0xA00E /* * Frequent response headers, these headers are coded as numbers * instead of strings. * * Content-Type * Content-Language * Content-Length * Date * Last-Modified * Location * Set-Cookie * Servlet-Engine * Status * WWW-Authenticate * */ #define SC_RESP_CONTENT_TYPE (unsigned short)0xA001 #define SC_RESP_CONTENT_LANGUAGE (unsigned short)0xA002 #define SC_RESP_CONTENT_LENGTH (unsigned short)0xA003 #define SC_RESP_DATE (unsigned short)0xA004 #define SC_RESP_LAST_MODIFIED (unsigned short)0xA005 #define SC_RESP_LOCATION (unsigned short)0xA006 #define SC_RESP_SET_COOKIE (unsigned short)0xA007 #define SC_RESP_SET_COOKIE2 (unsigned short)0xA008 #define SC_RESP_SERVLET_ENGINE (unsigned short)0xA009 #define SC_RESP_STATUS (unsigned short)0xA00A #define SC_RESP_WWW_AUTHENTICATE (unsigned short)0xA00B #define SC_RES_HEADERS_NUM 11 /* * AJP13/AJP14 use same message structure */ #define AJP_DEF_RETRY_ATTEMPTS (1) #define AJP_HEADER_LEN (4) #define AJP_HEADER_SZ_LEN (2) #define CHUNK_BUFFER_PAD (12) #define AJP_DEF_CACHE_TIMEOUT (0) #define AJP_DEF_CONNECT_TIMEOUT (0) /* NO CONNECTION TIMEOUT => NO CPING/CPONG */ #define AJP_DEF_REPLY_TIMEOUT (0) /* NO REPLY TIMEOUT */ #define AJP_DEF_PREPOST_TIMEOUT (0) /* NO PREPOST TIMEOUT => NO CPING/CPONG */ #define AJP_DEF_RECOVERY_OPTS (0) /* NO RECOVERY / NO */ #define AJP_DEF_SOCKET_TIMEOUT (0) /* No timeout */ #define AJP_DEF_PING_TIMEOUT (10000) /* Default CPING/CPONG timeout (10 seconds) */ #define AJP_CPING_NONE (0) /* Do not send cping packets */ #define AJP_CPING_CONNECT (1) /* Send cping on fresh connection */ #define AJP_CPING_PREPOST (2) /* Send cping before sending request */ #define AJP_CPING_INTERVAL (4) /* Send cping on regular intervals */ #define AJP_CPING_MAX (AJP_CPING_INTERVAL) #define AJP_CPING_CONNECT_TEXT ('C') /* Send cping on fresh connection */ #define AJP_CPING_PREPOST_TEXT ('P') /* Send cping before sending request */ #define AJP_CPING_INTERVAL_TEXT ('I') /* Send cping on regular intervals */ #define AJP_CPING_ALL_TEXT ('A') /* Send cping on regular intervals */ #define RECOVER_ABORT_IF_TCGETREQUEST 0x0001 /* DON'T RECOVER IF TOMCAT FAILS AFTER RECEIVING REQUEST */ #define RECOVER_ABORT_IF_TCSENDHEADER 0x0002 /* DON'T RECOVER IF TOMCAT FAILS AFTER SENDING HEADERS */ #define RECOVER_ABORT_IF_CLIENTERROR 0x0004 /* CLOSE THE SOCKET IN CASE OF CLIENT ERROR */ #define RECOVER_ALWAYS_HTTP_HEAD 0x0008 /* RECOVER HTTP HEAD REQUESTS, EVEN IF ABORT OPTIONS ARE SET */ #define RECOVER_ALWAYS_HTTP_GET 0x0010 /* RECOVER HTTP GET REQUESTS, EVEN IF ABORT OPTIONS ARE SET */ struct jk_res_data { int status; #ifdef AS400 char *msg; #else const char *msg; #endif unsigned num_headers; char **header_names; char **header_values; }; typedef struct jk_res_data jk_res_data_t; #include "jk_ajp14.h" struct ajp_operation; typedef struct ajp_operation ajp_operation_t; struct ajp_endpoint; typedef struct ajp_endpoint ajp_endpoint_t; struct ajp_worker; typedef struct ajp_worker ajp_worker_t; struct ajp_worker { jk_worker_t worker; /* Shared memory worker data */ jk_shm_ajp_worker_t *s; char name[JK_SHM_STR_SIZ]; /* Sequence counter starting at 0 and increasing * every time we change the config */ volatile unsigned int sequence; jk_pool_t p; jk_pool_atom_t buf[TINY_POOL_SIZE]; JK_CRIT_SEC cs; jk_sockaddr_t worker_inet_addr; /* Contains host and port */ jk_sockaddr_t worker_source_inet_addr; /* Contains source ip */ unsigned connect_retry_attempts; char host[JK_SHM_STR_SIZ]; int port; char source[JK_SHM_STR_SIZ]; int addr_sequence; /* Whether the address is resolved */ int maintain_time; int prefer_ipv6; /* * Open connections cache... * * 1. Critical section object to protect the cache. * 2. Cache size. * 3. An array of "open" endpoints. */ unsigned int ep_cache_sz; unsigned int ep_mincache_sz; unsigned int ep_maxcache_sz; int cache_acquire_timeout; ajp_endpoint_t **ep_cache; int proto; /* PROTOCOL USED AJP13/AJP14 */ jk_login_service_t *login; /* Weak secret similar with ajp12, used in ajp13 */ const char *secret; /* * Post physical connect handler. * AJP14 will set here its login handler */ int (*logon) (ajp_endpoint_t * ae, jk_logger_t *l); /* * Handle Socket Timeouts */ int socket_timeout; int socket_connect_timeout; int keepalive; int socket_buf; /* * Handle Cache Timeouts */ int cache_timeout; /* * Handle Connection/Reply Timeouts */ int connect_timeout; /* connect cping/cpong delay in ms (0 means disabled) */ int reply_timeout; /* reply timeout delay in ms (0 means disabled) */ int prepost_timeout; /* before sending a request cping/cpong timeout delay in ms (0 means disabled) */ int conn_ping_interval; /* interval for sending keepalive cping packets on * unused connection */ int ping_timeout; /* generic cping/cpong timeout. Used for keepalive packets or * as default for boolean valued connect and prepost timeouts. */ unsigned int ping_mode; /* Ping mode flags (which types of cpings should be used) */ /* * Recovery options */ unsigned int recovery_opts; /* * Public property to enable the number of retry attempts * on this worker. */ int retries; unsigned int max_packet_size; /* Maximum AJP Packet size */ int retry_interval; /* Number of milliseconds to sleep before doing a retry */ int busy_limit; /* Maximum allowed number of concurrent requests (if > 0) */ /* * HTTP status that will cause failover (0 means disabled) */ unsigned int http_status_fail_num; int *http_status_fail; }; /* * endpoint, the remote connector which does the work */ struct ajp_endpoint { ajp_worker_t *worker; jk_pool_t pool; jk_pool_atom_t buf[BIG_POOL_SIZE]; int proto; /* PROTOCOL USED AJP13/AJP14 */ jk_sock_t sd; int reuse; int avail; /* Set to non-zero if cache slot is available */ /* Used with RECOVER_ABORT_IF_CLIENTERROR to hard abort write of AJP response on client write errors */ int hard_close; jk_endpoint_t endpoint; jk_uint64_t left_bytes_to_send; /* time of the last request handled by this endpoint */ time_t last_access; int last_errno; /* Last operation performed via this endpoint */ int last_op; int addr_sequence; /* Whether the address is resolved */ }; /* * little struct to avoid multiples ptr passing * this struct is ready to hold upload file fd * to add upload persistant storage */ struct ajp_operation { jk_msg_buf_t *request; /* original request storage */ jk_msg_buf_t *reply; /* reply storage (chuncked by ajp13 */ jk_msg_buf_t *post; /* small post data storage area */ int uploadfd; /* future persistant storage id */ int recoverable; /* if exchange could be conducted on another TC */ }; /* * Functions */ const char *jk_ajp_get_state(ajp_worker_t *aw, jk_logger_t *l); int jk_ajp_get_state_code(const char *v); int ajp_validate(jk_worker_t *pThis, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l, int proto); int ajp_init(jk_worker_t *pThis, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l, int proto); int JK_METHOD ajp_worker_factory(jk_worker_t **w, const char *name, jk_logger_t *l); int ajp_destroy(jk_worker_t **pThis, jk_logger_t *l, int proto); int JK_METHOD ajp_done(jk_endpoint_t **e, jk_logger_t *l); int ajp_get_endpoint(jk_worker_t *pThis, jk_endpoint_t **pend, jk_logger_t *l, int proto); int ajp_connect_to_endpoint(ajp_endpoint_t * ae, jk_logger_t *l); void ajp_close_endpoint(ajp_endpoint_t * ae, jk_logger_t *l); void jk_ajp_pull(ajp_worker_t * aw, int locked, jk_logger_t *l); void jk_ajp_push(ajp_worker_t * aw, int locked, jk_logger_t *l); int ajp_connection_tcp_send_message(ajp_endpoint_t * ae, jk_msg_buf_t *msg, jk_logger_t *l); int ajp_connection_tcp_get_message(ajp_endpoint_t * ae, jk_msg_buf_t *msg, jk_logger_t *l); int JK_METHOD ajp_maintain(jk_worker_t *pThis, time_t now, int global, jk_logger_t *l); int JK_METHOD ajp_shutdown(jk_worker_t *pThis, jk_logger_t *l); void jk_ajp_get_cping_text(int mode, char *buf); int jk_ajp_get_cping_mode(const char *m, int def); int ajp_has_endpoint(jk_worker_t *pThis, jk_logger_t *l); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_AJP_COMMON_H */ tomcat-connectors-1.2.41-src/native/common/jk_ajp12_worker.c0000644000000000000020000005545712465671172022262 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: ajpv1.2 worker, used to call local or remote jserv hosts * * This worker is deprecated * * Author: Gal Shachor * * Based on: jserv_ajpv12.c from Jserv * * Version: $Revision: 1658173 $ * ***************************************************************************/ #include "jk_ajp12_worker.h" #include "jk_pool.h" #include "jk_connect.h" #include "jk_util.h" #include "jk_sockbuf.h" #if defined(AS400) && !defined(AS400_UTF8) #include "util_ebcdic.h" #include #endif #define AJP_DEF_HOST ("localhost") #define AJP_DEF_PORT (8007) #define READ_BUF_SIZE (8*1024) #define DEF_RETRY_ATTEMPTS (1) struct ajp12_worker { jk_sockaddr_t worker_inet_addr; jk_sockaddr_t worker_source_inet_addr; unsigned connect_retry_attempts; char *name; jk_worker_t worker; }; typedef struct ajp12_worker ajp12_worker_t; struct ajp12_endpoint { ajp12_worker_t *worker; jk_sock_t sd; jk_sockbuf_t sb; jk_endpoint_t endpoint; }; typedef struct ajp12_endpoint ajp12_endpoint_t; static int ajpv12_mark(ajp12_endpoint_t * p, unsigned char type); #if defined(AS400) && !defined(AS400_UTF8) static int ajpv12_sendasciistring(ajp12_endpoint_t * p, char *buffer); #endif #if defined(AS400) && !defined(AS400_UTF8) static int ajpv12_sendstring(ajp12_endpoint_t * p, char *buffer); #else static int ajpv12_sendstring(ajp12_endpoint_t * p, const char *buffer); #endif static int ajpv12_sendint(ajp12_endpoint_t * p, int d); static int ajpv12_sendnbytes(ajp12_endpoint_t * p, const void *buffer, int bufferlen); static int ajpv12_flush(ajp12_endpoint_t * p); static int ajpv12_handle_response(ajp12_endpoint_t * p, jk_ws_service_t *s, jk_logger_t *l); static int ajpv12_handle_request(ajp12_endpoint_t * p, jk_ws_service_t *s, jk_logger_t *l); /* * Return values of service() method for ajp12 worker: * return value is_error reason * JK_FALSE JK_HTTP_SERVER_ERROR Invalid parameters (null values) * Error during connect to the backend * ajpv12_handle_request() returns false: * Any error during reading a request body from the client or * sending the request to the backend * JK_FALSE JK_HTTP_OK ajpv12_handle_response() returns false: * Any error during reading parts of response from backend or * sending to client * JK_TRUE JK_HTTP_OK All other cases */ static int JK_METHOD service(jk_endpoint_t *e, jk_ws_service_t *s, jk_logger_t *l, int *is_error) { ajp12_endpoint_t *p; unsigned int attempt; int rc = -1; /* * AJP12 protocol is not recoverable. */ JK_TRACE_ENTER(l); if (!e || !e->endpoint_private || !s || !is_error) { JK_LOG_NULL_PARAMS(l); if (is_error) *is_error = JK_HTTP_SERVER_ERROR; JK_TRACE_EXIT(l); return JK_FALSE; } p = e->endpoint_private; /* Set returned error to OK */ *is_error = JK_HTTP_OK; for (attempt = 0; attempt < p->worker->connect_retry_attempts; attempt++) { p->sd = jk_open_socket(&p->worker->worker_inet_addr, p->worker->worker_source_inet_addr.ipaddr_ptr != NULL ? &p->worker->worker_source_inet_addr : NULL, JK_FALSE, 0, 0, 0, l); jk_log(l, JK_LOG_DEBUG, "In jk_endpoint_t::service, sd = %d", p->sd); if (IS_VALID_SOCKET(p->sd)) { break; } } if (IS_VALID_SOCKET(p->sd)) { jk_sb_open(&p->sb, p->sd); if (ajpv12_handle_request(p, s, l)) { jk_log(l, JK_LOG_DEBUG, "In jk_endpoint_t::service, sent request"); rc = ajpv12_handle_response(p, s, l); JK_TRACE_EXIT(l); return rc; } } jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::service, Error sd = %d", p->sd); *is_error = JK_HTTP_SERVER_ERROR; JK_TRACE_EXIT(l); return JK_FALSE; } static int JK_METHOD done(jk_endpoint_t **e, jk_logger_t *l) { jk_log(l, JK_LOG_DEBUG, "Into jk_endpoint_t::done"); if (e && *e && (*e)->endpoint_private) { ajp12_endpoint_t *p = (*e)->endpoint_private; if (IS_VALID_SOCKET(p->sd)) { jk_shutdown_socket(p->sd, l); } free(p); *e = NULL; return JK_TRUE; } jk_log(l, JK_LOG_ERROR, "In jk_endpoint_t::done, NULL parameters"); return JK_FALSE; } static int JK_METHOD validate(jk_worker_t *pThis, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l) { jk_log(l, JK_LOG_DEBUG, "Into jk_worker_t::validate"); if (pThis && pThis->worker_private) { ajp12_worker_t *p = pThis->worker_private; int port = jk_get_worker_port(props, p->name, AJP_DEF_PORT); const char *host = jk_get_worker_host(props, p->name, AJP_DEF_HOST); const char *source = jk_get_worker_host(props, p->name, ""); jk_log(l, JK_LOG_DEBUG, "In jk_worker_t::validate for worker %s target is %s:%d", p->name, host, port); if (host) { if (!jk_resolve(host, port, &p->worker_inet_addr, we->pool, JK_FALSE, l)) { jk_log(l, JK_LOG_ERROR, "In jk_worker_t::validate, host '%s:%d' resolve failed", host, port); return JK_FALSE; } } else { jk_log(l, JK_LOG_ERROR, "In jk_worker_t::validate, Error no host name given"); return JK_FALSE; } if (source && *source) { if (!jk_resolve(source, 0, &p->worker_source_inet_addr, we->pool, JK_FALSE, l)) { p->worker_source_inet_addr.ipaddr_ptr = NULL; jk_log(l, JK_LOG_WARNING, "In jk_worker_t::validate, source addr '%s' resolve failed - ignored", source); } } } else { jk_log(l, JK_LOG_ERROR, "In jk_worker_t::validate, NULL parameters"); } return JK_FALSE; } static int JK_METHOD init(jk_worker_t *pThis, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *log) { /* Nothing to do for now */ return JK_TRUE; } static int JK_METHOD get_endpoint(jk_worker_t *pThis, jk_endpoint_t **pend, jk_logger_t *l) { jk_log(l, JK_LOG_DEBUG, "Into jk_worker_t::get_endpoint"); if (pThis && pThis->worker_private && pend) { ajp12_endpoint_t *p = (ajp12_endpoint_t *) malloc(sizeof(ajp12_endpoint_t)); if (p) { p->sd = JK_INVALID_SOCKET; p->worker = pThis->worker_private; p->endpoint.endpoint_private = p; p->endpoint.service = service; p->endpoint.done = done; *pend = &p->endpoint; return JK_TRUE; } jk_log(l, JK_LOG_ERROR, "In jk_worker_t::get_endpoint, malloc failed"); } else { jk_log(l, JK_LOG_ERROR, "In jk_worker_t::get_endpoint, NULL parameters"); } return JK_FALSE; } static int JK_METHOD destroy(jk_worker_t **pThis, jk_logger_t *l) { jk_log(l, JK_LOG_DEBUG, "Into jk_worker_t::destroy"); if (pThis && *pThis && (*pThis)->worker_private) { ajp12_worker_t *private_data = (*pThis)->worker_private; free(private_data->name); free(private_data); return JK_TRUE; } jk_log(l, JK_LOG_ERROR, "In jk_worker_t::destroy, NULL parameters"); return JK_FALSE; } int JK_METHOD ajp12_worker_factory(jk_worker_t **w, const char *name, jk_logger_t *l) { jk_log(l, JK_LOG_DEBUG, "Into ajp12_worker_factory"); if (NULL != name && NULL != w) { ajp12_worker_t *private_data = (ajp12_worker_t *) malloc(sizeof(ajp12_worker_t)); if (private_data) { private_data->name = strdup(name); if (private_data->name) { private_data->connect_retry_attempts = DEF_RETRY_ATTEMPTS; private_data->worker.worker_private = private_data; private_data->worker.validate = validate; private_data->worker.init = init; private_data->worker.get_endpoint = get_endpoint; private_data->worker.destroy = destroy; private_data->worker.maintain = NULL; *w = &private_data->worker; return JK_AJP12_WORKER_TYPE; } free(private_data); } jk_log(l, JK_LOG_ERROR, "In ajp12_worker_factory, malloc failed"); } else { jk_log(l, JK_LOG_ERROR, "In ajp12_worker_factory, NULL parameters"); } return 0; } static int ajpv12_sendnbytes(ajp12_endpoint_t * p, const void *buffer, int bufferlen) { unsigned char bytes[2]; static const unsigned char null_b[2] = { (unsigned char)0xff, (unsigned char)0xff }; if (buffer) { bytes[0] = (unsigned char)((bufferlen >> 8) & 0xff); bytes[1] = (unsigned char)(bufferlen & 0xff); if (jk_sb_write(&p->sb, bytes, 2)) { return jk_sb_write(&p->sb, buffer, bufferlen); } else { return JK_FALSE; } } else { return jk_sb_write(&p->sb, null_b, 2); } } #if defined(AS400) && !defined(AS400_UTF8) static int ajpv12_sendasciistring(ajp12_endpoint_t * p, const char *buffer) { int bufferlen; if (buffer && (bufferlen = strlen(buffer))) { return ajpv12_sendnbytes(p, buffer, bufferlen); } else { return ajpv12_sendnbytes(p, NULL, 0); } } #endif static int ajpv12_sendstring(ajp12_endpoint_t * p, const char *buffer) { int bufferlen; if (buffer && (bufferlen = (int)strlen(buffer))) { #if (defined(AS400) && !defined(AS400_UTF8)) || defined(_OSD_POSIX) char buf[2048]; if (bufferlen < 2048) { memcpy(buf, buffer, bufferlen); jk_xlate_to_ascii(buf, bufferlen); return ajpv12_sendnbytes(p, buf, bufferlen); } else return -1; #else return ajpv12_sendnbytes(p, buffer, bufferlen); #endif } else { return ajpv12_sendnbytes(p, NULL, 0); } } static int ajpv12_mark(ajp12_endpoint_t * p, unsigned char type) { if (jk_sb_write(&p->sb, &type, 1)) { return JK_TRUE; } else { return JK_FALSE; } } static int ajpv12_sendint(ajp12_endpoint_t * p, int d) { char buf[20]; sprintf(buf, "%d", d); return ajpv12_sendstring(p, buf); } static int ajpv12_flush(ajp12_endpoint_t * p) { return jk_sb_flush(&p->sb); } static int ajpv12_handle_request(ajp12_endpoint_t * p, jk_ws_service_t *s, jk_logger_t *l) { int ret; jk_log(l, JK_LOG_DEBUG, "Into ajpv12_handle_request"); /* * Start the ajp 12 service sequence */ jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_request, sending the ajp12 start sequence"); ret = (ajpv12_mark(p, 1) && ajpv12_sendstring(p, s->method) && ajpv12_sendstring(p, 0) && /* zone */ ajpv12_sendstring(p, 0) && /* servlet */ ajpv12_sendstring(p, s->server_name) && ajpv12_sendstring(p, 0) && /* doc root */ ajpv12_sendstring(p, 0) && /* path info */ ajpv12_sendstring(p, 0) && /* path translated */ #if defined(AS400) && !defined(AS400_UTF8) ajpv12_sendasciistring(p, s->query_string) && #else ajpv12_sendstring(p, s->query_string) && #endif ajpv12_sendstring(p, s->remote_addr) && ajpv12_sendstring(p, s->remote_host) && ajpv12_sendstring(p, s->remote_user) && ajpv12_sendstring(p, s->auth_type) && ajpv12_sendint(p, s->server_port) && #if defined(AS400) && !defined(AS400_UTF8) ajpv12_sendasciistring(p, s->method) && #else ajpv12_sendstring(p, s->method) && #endif ajpv12_sendstring(p, s->req_uri) && ajpv12_sendstring(p, 0) && /* */ ajpv12_sendstring(p, 0) && /* SCRIPT_NAME */ #if defined(AS400) && !defined(AS400_UTF8) ajpv12_sendasciistring(p, s->server_name) && #else ajpv12_sendstring(p, s->server_name) && #endif ajpv12_sendint(p, s->server_port) && ajpv12_sendstring(p, s->protocol) && ajpv12_sendstring(p, 0) && /* SERVER_SIGNATURE */ ajpv12_sendstring(p, s->server_software) && ajpv12_sendstring(p, s->route) && /* JSERV_ROUTE */ ajpv12_sendstring(p, "") && /* JSERV ajpv12 compatibility */ ajpv12_sendstring(p, "")); /* JSERV ajpv12 compatibility */ if (!ret) { jk_log(l, JK_LOG_ERROR, "In ajpv12_handle_request, failed to send the ajp12 start sequence"); return JK_FALSE; } if (s->num_attributes > 0) { unsigned i; jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_request, sending the environment variables"); for (i = 0; i < s->num_attributes; i++) { ret = (ajpv12_mark(p, 5) && ajpv12_sendstring(p, s->attributes_names[i]) && ajpv12_sendstring(p, s->attributes_values[i])); if (!ret) { jk_log(l, JK_LOG_ERROR, "In ajpv12_handle_request, failed to send environment"); return JK_FALSE; } } } jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_request, sending the headers"); /* Send the request headers */ if (s->num_headers) { unsigned i; for (i = 0; i < s->num_headers; ++i) { ret = (ajpv12_mark(p, 3) && ajpv12_sendstring(p, s->headers_names[i]) && ajpv12_sendstring(p, s->headers_values[i])); if (!ret) { jk_log(l, JK_LOG_ERROR, "In ajpv12_handle_request, failed to send headers"); return JK_FALSE; } } } jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_request, sending the terminating mark"); ret = (ajpv12_mark(p, 4) && ajpv12_flush(p)); if (!ret) { jk_log(l, JK_LOG_ERROR, "In ajpv12_handle_request, failed to send the terminating mark"); return JK_FALSE; } if (s->content_length) { char buf[READ_BUF_SIZE]; jk_uint64_t so_far = 0; jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_request, sending the request body"); while (so_far < s->content_length) { unsigned this_time = 0; unsigned to_read; if (s->content_length > so_far + READ_BUF_SIZE) { to_read = READ_BUF_SIZE; } else { to_read = (unsigned int)(s->content_length - so_far); } if (!s->read(s, buf, to_read, &this_time)) { jk_log(l, JK_LOG_ERROR, "In ajpv12_handle_request, failed to read from the web server"); return JK_FALSE; } jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_request, read %d bytes", this_time); if (this_time > 0) { so_far += this_time; if ((int)this_time != send(p->sd, buf, this_time, 0)) { jk_log(l, JK_LOG_ERROR, "In ajpv12_handle_request, failed to write to the container"); return JK_FALSE; } jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_request, sent %d bytes", this_time); } else if (this_time == 0) { jk_log(l, JK_LOG_ERROR, "In ajpv12_handle_request, Error: short read. content length is %" JK_UINT64_T_FMT ", read %" JK_UINT64_T_FMT, s->content_length, so_far); return JK_FALSE; } } } jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_request done"); return JK_TRUE; } static int ajpv12_handle_response(ajp12_endpoint_t * p, jk_ws_service_t *s, jk_logger_t *l) { int status = 200; char *reason = NULL; char **names = NULL; char **values = NULL; int headers_capacity = 0; int headers_len = 0; int write_to_ws; jk_log(l, JK_LOG_DEBUG, "Into ajpv12_handle_response"); /* * Read headers ... */ while (1) { char *line = NULL; char *name = NULL; char *value = NULL; #ifdef _MT_CODE_PTHREAD char *lasts; #endif if (!jk_sb_gets(&p->sb, &line)) { jk_log(l, JK_LOG_ERROR, "ajpv12_handle_response, error reading header line"); return JK_FALSE; } #if (defined(AS400) && !defined(AS400_UTF8)) || defined(_OSD_POSIX) jk_xlate_from_ascii(line, strlen(line)); #endif jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response, read %s", line); if (0 == strlen(line)) { jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response, headers are done"); break; /* Empty line -> end of headers */ } name = line; while (jk_isspace(*name) && *name) { name++; /* Skip leading white chars */ } if (!*name) { /* Empty header name */ jk_log(l, JK_LOG_ERROR, "ajpv12_handle_response, empty header name"); return JK_FALSE; } if (!(value = strchr(name, ':'))) { jk_log(l, JK_LOG_ERROR, "ajpv12_handle_response, no value supplied"); return JK_FALSE; /* No value !!! */ } *value = '\0'; value++; while (jk_isspace(*value) && *value) { value++; /* Skip leading white chars */ } if (!*value) { /* Empty header value */ jk_log(l, JK_LOG_ERROR, "ajpv12_handle_response, empty header value"); return JK_FALSE; } jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response, read %s=%s", name, value); if (0 == strcmp("Status", name)) { #ifdef _MT_CODE_PTHREAD char *numeric = strtok_r(value, " \t", &lasts); #else char *numeric = strtok(value, " \t"); #endif status = atoi(numeric); if (status < 100 || status > 999) { jk_log(l, JK_LOG_ERROR, "ajpv12_handle_response, invalid status code"); return JK_FALSE; } #ifdef _MT_CODE_PTHREAD reason = jk_pool_strdup(s->pool, strtok_r(NULL, " \t", &lasts)); #else reason = jk_pool_strdup(s->pool, strtok(NULL, " \t")); #endif } else { if (headers_capacity == headers_len) { jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response, allocating header arrays"); names = (char **)jk_pool_realloc(s->pool, sizeof(char *) * (headers_capacity + 5), names, sizeof(char *) * headers_capacity); values = (char **)jk_pool_realloc(s->pool, sizeof(char *) * (headers_capacity + 5), values, sizeof(char *) * headers_capacity); if (!values || !names) { jk_log(l, JK_LOG_ERROR, "ajpv12_handle_response, malloc error"); return JK_FALSE; } headers_capacity = headers_capacity + 5; } names[headers_len] = jk_pool_strdup(s->pool, name); values[headers_len] = jk_pool_strdup(s->pool, value); headers_len++; } } jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response, starting response"); if (!s->start_response(s, status, reason, (const char *const *)names, (const char *const *)values, headers_len)) { jk_log(l, JK_LOG_ERROR, "ajpv12_handle_response, error starting response"); return JK_FALSE; } jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response, reading response body"); /* * Read response body */ write_to_ws = JK_TRUE; while (1) { unsigned to_read = READ_BUF_SIZE; unsigned acc = 0; char *buf = NULL; if (!jk_sb_read(&p->sb, &buf, to_read, &acc)) { jk_log(l, JK_LOG_ERROR, "ajpv12_handle_response, error reading from "); return JK_FALSE; } if (!acc) { jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response, response body is done"); break; } if (write_to_ws) { if (!s->write(s, buf, acc)) { jk_log(l, JK_LOG_ERROR, "ajpv12_handle_response, error writing back to server"); write_to_ws = JK_FALSE; } } } jk_log(l, JK_LOG_DEBUG, "ajpv12_handle_response done"); return JK_TRUE; } tomcat-connectors-1.2.41-src/native/common/jk_msg_buff.c0000644000000000000020000002141511660673552021527 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Data marshaling. XDR like * * Author: Costin * * Author: Gal Shachor * * Author: Henri Gomez * * Version: $Revision: 1202585 $ * ***************************************************************************/ #include "jk_pool.h" #include "jk_connect.h" #include "jk_util.h" #include "jk_sockbuf.h" #include "jk_msg_buff.h" #include "jk_logger.h" static char *jk_HEX = "0123456789ABCDEFX"; /* * Simple marshaling code. */ void jk_b_reset(jk_msg_buf_t *msg) { msg->len = 4; msg->pos = 4; if (msg->buf && msg->maxlen) { /* Clear the message buffer */ memset(msg->buf, 0, msg->maxlen); } } int jk_b_append_long(jk_msg_buf_t *msg, unsigned long val) { if (msg->len + 4 > msg->maxlen) { return -1; } msg->buf[msg->len++] = (unsigned char)((val >> 24) & 0xFF); msg->buf[msg->len++] = (unsigned char)((val >> 16) & 0xFF); msg->buf[msg->len++] = (unsigned char)((val >> 8) & 0xFF); msg->buf[msg->len++] = (unsigned char)((val) & 0xFF); return 0; } int jk_b_append_int(jk_msg_buf_t *msg, unsigned short val) { if (msg->len + 2 > msg->maxlen) { return -1; } msg->buf[msg->len++] = (unsigned char)((val >> 8) & 0xFF); msg->buf[msg->len++] = (unsigned char)((val) & 0xFF); return 0; } int jk_b_append_byte(jk_msg_buf_t *msg, unsigned char val) { if (msg->len + 1 > msg->maxlen) { return -1; } msg->buf[msg->len++] = val; return 0; } void jk_b_end(jk_msg_buf_t *msg, int protoh) { /* * Ugly way to set the size in the right position */ int hlen = msg->len - 4; msg->buf[0] = (unsigned char)((protoh >> 8) & 0xFF); msg->buf[1] = (unsigned char)((protoh) & 0xFF); msg->buf[2] = (unsigned char)((hlen >> 8) & 0xFF); msg->buf[3] = (unsigned char)((hlen) & 0xFF); } jk_msg_buf_t *jk_b_new(jk_pool_t *p) { jk_msg_buf_t *msg = (jk_msg_buf_t *)jk_pool_alloc(p, sizeof(jk_msg_buf_t)); if (!msg) { return NULL; } memset(msg, 0, sizeof(jk_msg_buf_t)); msg->pool = p; return msg; } int jk_b_set_buffer(jk_msg_buf_t *msg, unsigned char *data, int buffSize) { if (!msg) { return -1; } msg->len = 0; msg->buf = data; msg->maxlen = buffSize; return 0; } int jk_b_set_buffer_size(jk_msg_buf_t *msg, int buffSize) { unsigned char *data = jk_pool_alloc(msg->pool, buffSize); if (!data) { return -1; } jk_b_set_buffer(msg, data, buffSize); return 0; } #if defined(AS400) && !defined(AS400_UTF8) int jk_b_append_asciistring(jk_msg_buf_t *msg, const char *param) { int len; if (!param) { jk_b_append_int(msg, 0xFFFF); return 0; } len = strlen(param); if (msg->len + len + 2 > msg->maxlen) { return -1; } /* ignore error - we checked once */ jk_b_append_int(msg, (unsigned short)len); /* We checked for space !! */ strncpy((char *)msg->buf + msg->len, param, len + 1); /* including \0 */ msg->len += len + 1; return 0; } #endif int jk_b_append_string(jk_msg_buf_t *msg, const char *param) { unsigned short len; if (!param) { jk_b_append_int(msg, 0xFFFF); return 0; } len = (unsigned short)strlen(param); if (msg->len + len + 3 > msg->maxlen) { return -1; } /* ignore error - we checked once */ jk_b_append_int(msg, len); /* We checked for space !! */ memcpy(msg->buf + msg->len, param, len + 1); /* including \0 */ #if (defined(AS400) && !defined(AS400_UTF8)) || defined(_OSD_POSIX) /* convert from EBCDIC if needed */ jk_xlate_to_ascii((char *)msg->buf + msg->len, len + 1); #endif msg->len += len + 1; return 0; } int jk_b_append_bytes(jk_msg_buf_t *msg, const unsigned char *param, int len) { if (!len) { return 0; } if (msg->len + len > msg->maxlen) { return -1; } /* We checked for space !! */ memcpy(msg->buf + msg->len, param, len); msg->len += len; return 0; } unsigned long jk_b_get_long(jk_msg_buf_t *msg) { unsigned long i; if (msg->pos + 3 > msg->len) { return 0xFFFFFFFF; } i = ((msg->buf[(msg->pos++)] & 0xFF) << 24); i |= ((msg->buf[(msg->pos++)] & 0xFF) << 16); i |= ((msg->buf[(msg->pos++)] & 0xFF) << 8); i |= ((msg->buf[(msg->pos++)] & 0xFF)); return i; } unsigned long jk_b_pget_long(jk_msg_buf_t *msg, int pos) { unsigned long i; i = ((msg->buf[(pos++)] & 0xFF) << 24); i |= ((msg->buf[(pos++)] & 0xFF) << 16); i |= ((msg->buf[(pos++)] & 0xFF) << 8); i |= ((msg->buf[(pos)] & 0xFF)); return i; } unsigned short jk_b_get_int(jk_msg_buf_t *msg) { unsigned short i; if (msg->pos + 1 > msg->len) { return 0xFFFF; } i = ((msg->buf[(msg->pos++)] & 0xFF) << 8); i += ((msg->buf[(msg->pos++)] & 0xFF)); return i; } unsigned short jk_b_pget_int(jk_msg_buf_t *msg, int pos) { unsigned short i; i = ((msg->buf[pos++] & 0xFF) << 8); i += ((msg->buf[pos] & 0xFF)); return i; } unsigned char jk_b_get_byte(jk_msg_buf_t *msg) { unsigned char rc; if (msg->pos > msg->len) { return 0xFF; } rc = msg->buf[msg->pos++]; return rc; } unsigned char jk_b_pget_byte(jk_msg_buf_t *msg, int pos) { return msg->buf[pos]; } char *jk_b_get_string(jk_msg_buf_t *msg) { unsigned short size = jk_b_get_int(msg); int start = msg->pos; if ((size == 0xFFFF) || (size + start > msg->maxlen)) { /* Error of overflow in AJP packet. * The complete message is probably invalid. */ return NULL; } msg->pos += size; msg->pos++; /* terminating NULL */ return (char *)(msg->buf + start); } int jk_b_get_bytes(jk_msg_buf_t *msg, unsigned char *buf, int len) { int start = msg->pos; if ((len < 0) || (len + start > msg->maxlen)) { return (-1); } memcpy(buf, msg->buf + start, len); msg->pos += len; return (len); } /** Helpie dump function */ void jk_dump_buff(jk_logger_t *l, const char *file, int line, const char *funcname, int level, char *what, jk_msg_buf_t *msg) { int i = 0; char lb[80]; char *current; int j; int len = msg->len; if (l == NULL) return; if (l->level != JK_LOG_TRACE_LEVEL && len > 1024) len = 1024; jk_log(l, file, line, funcname, level, "%s pos=%d len=%d max=%d", what, msg->pos, msg->len, msg->maxlen); for (i = 0; i < len; i += 16) { current = &lb[0]; for (j = 0; j < 16; j++) { unsigned char x = (msg->buf[i + j]); if ((i + j) >= len) x = 0; *current++ = jk_HEX[x >> 4]; *current++ = jk_HEX[x & 0x0f]; *current++ = ' '; } *current++ = ' '; *current++ = '-'; *current++ = ' '; for (j = 0; j < 16; j++) { unsigned char x = msg->buf[i + j]; if ((i + j) >= len) x = 0; if (x > 0x20 && x < 0x7F) { #ifdef USE_CHARSET_EBCDIC *current = x; jk_xlate_from_ascii(current, 1); current++; #else *current++ = x; #endif } else { *current++ = '.'; } } *current++ = '\0'; jk_log(l, file, line, funcname, level, "%.4x %s", i, lb); } } int jk_b_copy(jk_msg_buf_t *smsg, jk_msg_buf_t *dmsg) { if (smsg == NULL || dmsg == NULL) return (-1); if (dmsg->maxlen < smsg->len) return (-2); memcpy(dmsg->buf, smsg->buf, smsg->len); dmsg->len = smsg->len; return (smsg->len); } tomcat-connectors-1.2.41-src/native/common/jk_shm.c0000644000000000000020000007027412477544555020544 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Shared Memory support * * Author: Mladen Turk * * Author: Rainer Jung * * Version: $Revision: 1665454 $ * ***************************************************************************/ #include "jk_global.h" #include "jk_pool.h" #include "jk_util.h" #include "jk_mt.h" #include "jk_lb_worker.h" #include "jk_ajp13_worker.h" #include "jk_ajp14_worker.h" #include "jk_shm.h" /** jk shm header core data structure * This is always the first slot in shared memory. */ struct jk_shm_header_data { /* Shared memory magic JK_SHM_MAGIC */ char magic[JK_SHM_MAGIC_SIZ]; unsigned int size; unsigned int pos; unsigned int childs; unsigned int workers; unsigned int maintain_checking; volatile time_t maintain_time; }; typedef struct jk_shm_header_data jk_shm_header_data_t; /** jk shm header record structure */ struct jk_shm_header { union { jk_shm_header_data_t data; char alignbuf[JK_SHM_SLOT_SIZE]; } h; char buf[1]; }; typedef struct jk_shm_header jk_shm_header_t; /** jk shm in memory structure. */ struct jk_shm { unsigned int size; unsigned int ajp_workers; unsigned int lb_sub_workers; unsigned int lb_workers; char *filename; char *lockname; int fd; int fd_lock; int attached; jk_shm_header_t *hdr; JK_CRIT_SEC cs; }; typedef struct jk_shm jk_shm_t; static const char shm_signature[] = { JK_SHM_MAGIC }; static jk_shm_t jk_shmem = { 0, 0, 0, 0, NULL, NULL, -1, -1, 0, NULL}; #if defined (WIN32) static HANDLE jk_shm_map = NULL; static HANDLE jk_shm_hlock = NULL; #endif static int jk_shm_inited_cs = 0; static size_t jk_shm_calculate_slot_size() { int align = 64; size_t slot_size = 0; size_t this_size = 0; this_size = sizeof(jk_shm_header_data_t); if (this_size > slot_size) slot_size = this_size; this_size = sizeof(jk_shm_worker_header_t); if (this_size > slot_size) slot_size = this_size; this_size = sizeof(jk_shm_ajp_worker_t); if (this_size > slot_size) slot_size = this_size; this_size = sizeof(jk_shm_lb_sub_worker_t); if (this_size > slot_size) slot_size = this_size; this_size = sizeof(jk_shm_lb_worker_t); if (this_size > slot_size) slot_size = this_size; slot_size = JK_ALIGN(slot_size, align); return slot_size; } /* Calculate needed shm size */ int jk_shm_calculate_size(jk_map_t *init_data, jk_logger_t *l) { char **worker_list; size_t needed_slot_size = 0; unsigned int i; unsigned int num_of_workers; int num_of_ajp_workers = 0; int num_of_lb_sub_workers = 0; int num_of_lb_workers = 0; JK_TRACE_ENTER(l); if (jk_get_worker_list(init_data, &worker_list, &num_of_workers) == JK_FALSE) { jk_log(l, JK_LOG_ERROR, "Could not get worker list from map"); JK_TRACE_EXIT(l); return 0; } needed_slot_size = jk_shm_calculate_slot_size(); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "JK_SHM_SLOT_SIZE defined as %d, need at least %d", JK_SHM_SLOT_SIZE , needed_slot_size); if (needed_slot_size > JK_SHM_SLOT_SIZE) { jk_log(l, JK_LOG_ERROR, "JK_SHM_SLOT_SIZE %d is too small, need at least %d", JK_SHM_SLOT_SIZE, needed_slot_size); JK_TRACE_EXIT(l); return 0; } for (i = 0; i < num_of_workers; i++) { const char *type = jk_get_worker_type(init_data, worker_list[i]); if (!strcmp(type, JK_AJP13_WORKER_NAME) || !strcmp(type, JK_AJP14_WORKER_NAME)) { num_of_ajp_workers++; } else if (!strcmp(type, JK_LB_WORKER_NAME)) { char **member_list; unsigned int num_of_members; num_of_lb_workers++; if (jk_get_lb_worker_list(init_data, worker_list[i], &member_list, &num_of_members) == JK_FALSE) { jk_log(l, JK_LOG_ERROR, "Could not get member list for lb worker from map"); } else { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "worker %s of type %s has %u members", worker_list[i], JK_LB_WORKER_NAME, num_of_members); num_of_lb_sub_workers += num_of_members; } } } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "shared memory will contain %d ajp workers and %d lb workers with %d members", num_of_ajp_workers, num_of_lb_workers, num_of_lb_sub_workers); jk_shmem.ajp_workers = num_of_ajp_workers; jk_shmem.lb_sub_workers = num_of_lb_sub_workers; jk_shmem.lb_workers = num_of_lb_workers; JK_TRACE_EXIT(l); return (JK_SHM_SLOT_SIZE * (jk_shmem.ajp_workers + jk_shmem.lb_sub_workers * 2 + jk_shmem.lb_workers)); } #if defined (WIN32) || defined(NETWARE) /* Use plain memory */ int jk_shm_open(const char *fname, int sz, jk_logger_t *l) { int rc = -1; int attached = 0; char lkname[MAX_PATH]; char shname[MAX_PATH] = ""; JK_TRACE_ENTER(l); if (!jk_shm_inited_cs) { jk_shm_inited_cs = 1; JK_INIT_CS(&jk_shmem.cs, rc); } JK_ENTER_CS(&jk_shmem.cs); if (jk_shmem.hdr) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Shared memory is already opened"); JK_TRACE_EXIT(l); JK_LEAVE_CS(&jk_shmem.cs); return 0; } if (sz < 0) { jk_log(l, JK_LOG_ERROR, "Invalid shared memory size (%d)", sz); JK_TRACE_EXIT(l); return EINVAL; } jk_shmem.size = JK_SHM_ALIGN(JK_SHM_SLOT_SIZE + sz); #if defined (WIN32) jk_shm_map = NULL; jk_shm_hlock = NULL; if (fname) { int i; SIZE_T shmsz = 0; strcpy(shname, "Global\\"); strncat(shname, fname, MAX_PATH - 8); for(i = 7; i < (int)strlen(shname); i++) { if (!jk_isalnum(shname[i])) shname[i] = '_'; else shname[i] = toupper(shname[i]); } strcpy(lkname, shname); strncat(lkname, "_MUTEX", MAX_PATH - 1); jk_shm_hlock = CreateMutex(jk_get_sa_with_null_dacl(), TRUE, lkname); if (jk_shm_hlock == NULL) { if (GetLastError() == ERROR_ALREADY_EXISTS) { attached = 1; jk_shm_hlock = OpenMutex(MUTEX_ALL_ACCESS, FALSE, lkname); } } else if (GetLastError() == ERROR_ALREADY_EXISTS) attached = 1; if (jk_shm_hlock == NULL) { rc = GetLastError(); jk_log(l, JK_LOG_ERROR, "Failed to open shared memory mutex %s with errno=%d", lkname, rc); JK_LEAVE_CS(&jk_shmem.cs); JK_TRACE_EXIT(l); return rc; } if (attached) { DWORD ws = WaitForSingleObject(jk_shm_hlock, INFINITE); if (ws == WAIT_FAILED) { rc = GetLastError(); CloseHandle(jk_shm_hlock); jk_shm_hlock = NULL; JK_LEAVE_CS(&jk_shmem.cs); JK_TRACE_EXIT(l); return rc; } jk_shm_map = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, shname); if (jk_shm_map == NULL) { rc = GetLastError(); jk_log(l, JK_LOG_ERROR, "Failed to open shared memory %s with errno=%d", shname, rc); } } if (jk_shm_map == NULL) { shmsz = jk_shmem.size; jk_shm_map = CreateFileMapping(INVALID_HANDLE_VALUE, jk_get_sa_with_null_dacl(), PAGE_READWRITE, 0, (DWORD)shmsz, shname); } if (jk_shm_map == NULL || jk_shm_map == INVALID_HANDLE_VALUE) { rc = GetLastError(); jk_log(l, JK_LOG_ERROR, "Failed to map shared memory %s with errno=%d", fname, rc); CloseHandle(jk_shm_hlock); jk_shm_hlock = NULL; jk_shm_map = NULL; JK_LEAVE_CS(&jk_shmem.cs); JK_TRACE_EXIT(l); return rc; } jk_shmem.hdr = (jk_shm_header_t *)MapViewOfFile(jk_shm_map, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, shmsz); } else #endif jk_shmem.hdr = (jk_shm_header_t *)calloc(1, jk_shmem.size); if (!jk_shmem.hdr) { #if defined (WIN32) rc = GetLastError(); if (jk_shm_map) { CloseHandle(jk_shm_map); jk_shm_map = NULL; } if (jk_shm_hlock) { CloseHandle(jk_shm_hlock); jk_shm_hlock = NULL; } #endif JK_LEAVE_CS(&jk_shmem.cs); JK_TRACE_EXIT(l); return rc; } if (!jk_shmem.filename) { if (shname[0]) jk_shmem.filename = strdup(shname); else jk_shmem.filename = strdup("memory"); } jk_shmem.fd = 0; jk_shmem.attached = attached; if (!attached) { memset(jk_shmem.hdr, 0, jk_shmem.size); memcpy(jk_shmem.hdr->h.data.magic, shm_signature, JK_SHM_MAGIC_SIZ); jk_shmem.hdr->h.data.size = sz; jk_shmem.hdr->h.data.childs = 1; jk_shmem.hdr->h.data.maintain_checking = 0; jk_shmem.hdr->h.data.maintain_time = time(NULL); } else { jk_shmem.hdr->h.data.childs++; /* * Reset the shared memory so that * alloc works even for attached memory. * XXX: This might break already used memory * if the number of workers change between * open and attach or between two attach operations. */ #if 0 if (jk_shmem.hdr->h.data.childs > 1) { if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "Resetting the shared memory for child %d", jk_shmem.hdr->h.data.childs); } } jk_shmem.hdr->h.data.pos = 0; jk_shmem.hdr->h.data.workers = 0; #endif } #if defined (WIN32) if (jk_shm_hlock != NULL) { /* Unlock shared memory */ ReleaseMutex(jk_shm_hlock); } #endif JK_LEAVE_CS(&jk_shmem.cs); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "%s shared memory %s [%d] size=%u workers=%d free=%u addr=%#lx", attached ? "Attached" : "Initialized", jk_shm_name(), jk_shmem.hdr->h.data.childs, jk_shmem.size, jk_shmem.hdr->h.data.workers - 1, jk_shmem.hdr->h.data.size - jk_shmem.hdr->h.data.pos, jk_shmem.hdr); JK_TRACE_EXIT(l); return 0; } int jk_shm_attach(const char *fname, int sz, jk_logger_t *l) { JK_TRACE_ENTER(l); if (!jk_shm_open(fname, sz, l)) { if (!jk_shmem.attached) { jk_shmem.attached = 1; if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "Attached shared memory %s [%d] size=%u free=%u addr=%#lx", jk_shm_name(), jk_shmem.hdr->h.data.childs, jk_shmem.size, jk_shmem.hdr->h.data.size - jk_shmem.hdr->h.data.pos, jk_shmem.hdr); } } JK_TRACE_EXIT(l); return 0; } else { JK_TRACE_EXIT(l); return -1; } } void jk_shm_close(jk_logger_t *l) { if (jk_shm_inited_cs) { JK_ENTER_CS(&jk_shmem.cs); } if (jk_shmem.hdr) { if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "Closed shared memory %s childs=%u", jk_shm_name(), jk_shmem.hdr->h.data.childs); } #if defined (WIN32) if (jk_shm_hlock) { WaitForSingleObject(jk_shm_hlock, 60000); ReleaseMutex(jk_shm_hlock); CloseHandle(jk_shm_hlock); jk_shm_hlock = NULL; } if (jk_shm_map) { --jk_shmem.hdr->h.data.childs; UnmapViewOfFile(jk_shmem.hdr); CloseHandle(jk_shm_map); jk_shm_map = NULL; } else #endif free(jk_shmem.hdr); } jk_shmem.hdr = NULL; if (jk_shmem.filename) { free(jk_shmem.filename); jk_shmem.filename = NULL; } if (jk_shm_inited_cs) { JK_LEAVE_CS(&jk_shmem.cs); } } #else #include #include #include #include #include #include #ifndef MAP_FAILED #define MAP_FAILED (-1) #endif #ifndef MAP_FILE #define MAP_FILE (0) #endif static int do_shm_open_lock(const char *fname, int attached, jk_logger_t *l) { int rc; char flkname[256]; #ifdef AS400_UTF8 char *wptr; #endif JK_TRACE_ENTER(l); if (attached && jk_shmem.lockname) { #ifdef JK_SHM_LOCK_REOPEN jk_shmem.fd_lock = open(jk_shmem.lockname, O_RDWR, 0666); #else errno = EINVAL; #endif if (jk_shmem.fd_lock == -1) { rc = errno; JK_TRACE_EXIT(l); return rc; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Duplicated shared memory lock %s", jk_shmem.lockname); JK_TRACE_EXIT(l); return 0; } if (!jk_shmem.lockname) { #ifdef JK_SHM_LOCK_REOPEN int i; jk_shmem.fd_lock = -1; mode_t mask = umask(0); for (i = 0; i < 8; i++) { strcpy(flkname, "/tmp/jkshmlock.XXXXXX"); if (mktemp(flkname)) { jk_shmem.fd_lock = open(flkname, O_RDWR|O_CREAT|O_TRUNC, 0666); if (jk_shmem.fd_lock >= 0) break; } } umask(mask); #else strcpy(flkname, fname); strcat(flkname, ".lock"); #ifdef AS400_UTF8 wptr = (char *)malloc(strlen(flkname) + 1); jk_ascii2ebcdic((char *)flkname, wptr); jk_shmem.fd_lock = open(wptr, O_RDWR|O_CREAT|O_TRUNC, 0666); free(wptr); #else jk_shmem.fd_lock = open(flkname, O_RDWR|O_CREAT|O_TRUNC, 0666); #endif #endif if (jk_shmem.fd_lock == -1) { rc = errno; JK_TRACE_EXIT(l); return rc; } jk_shmem.lockname = strdup(flkname); } else { /* Nothing to do */ JK_TRACE_EXIT(l); return 0; } if (ftruncate(jk_shmem.fd_lock, 1)) { rc = errno; close(jk_shmem.fd_lock); jk_shmem.fd_lock = -1; JK_TRACE_EXIT(l); return rc; } if (lseek(jk_shmem.fd_lock, 0, SEEK_SET) != 0) { rc = errno; close(jk_shmem.fd_lock); jk_shmem.fd_lock = -1; return rc; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Opened shared memory lock %s", jk_shmem.lockname); JK_TRACE_EXIT(l); return 0; } static int do_shm_open(const char *fname, int attached, int sz, jk_logger_t *l) { int rc; int fd; void *base; #ifdef AS400_UTF8 char *wptr; #endif JK_TRACE_ENTER(l); if (!jk_shm_inited_cs) { jk_shm_inited_cs = 1; JK_INIT_CS(&jk_shmem.cs, rc); } if (jk_shmem.hdr) { /* Probably a call from vhost */ if (!attached) attached = 1; } else if (attached) { /* We should already have a header * Use memory if we don't */ JK_TRACE_EXIT(l); return 0; } if (sz < 0) { jk_log(l, JK_LOG_ERROR, "Invalid shared memory size (%d)", sz); JK_TRACE_EXIT(l); return EINVAL; } jk_shmem.size = JK_SHM_ALIGN(JK_SHM_SLOT_SIZE + sz); if (!fname) { /* Use plain memory in case there is no file name */ if (!jk_shmem.filename) jk_shmem.filename = strdup("memory"); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Using process memory as shared memory"); JK_TRACE_EXIT(l); return 0; } if (!jk_shmem.filename) { jk_shmem.filename = (char *)malloc(strlen(fname) + 32); sprintf(jk_shmem.filename, "%s.%" JK_PID_T_FMT, fname, getpid()); } if (!attached) { size_t size; jk_shmem.attached = 0; #ifdef AS400_UTF8 wptr = (char *)malloc(strlen(jk_shmem.filename) + 1); jk_ascii2ebcdic((char *)jk_shmem.filename, wptr); fd = open(wptr, O_RDWR|O_CREAT|O_TRUNC, 0666); free(wptr); #else fd = open(jk_shmem.filename, O_RDWR|O_CREAT|O_TRUNC, 0666); #endif if (fd == -1) { jk_shmem.size = 0; JK_TRACE_EXIT(l); return errno; } size = lseek(fd, 0, SEEK_END); if (size < jk_shmem.size) { size = jk_shmem.size; if (ftruncate(fd, jk_shmem.size)) { rc = errno; close(fd); #ifdef AS400_UTF8 wptr = (char *)malloc(strlen(jk_shmem.filename) + 1); jk_ascii2ebcdic((char *)jk_shmem.filename, wptr); unlink(wptr); free(wptr); #else unlink(jk_shmem.filename); #endif jk_shmem.size = 0; JK_TRACE_EXIT(l); return rc; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Truncated shared memory to %u", size); } if (lseek(fd, 0, SEEK_SET) != 0) { rc = errno; close(fd); #ifdef AS400_UTF8 wptr = (char *)malloc(strlen(jk_shmem.filename) + 1); jk_ascii2ebcdic((char *)jk_shmem.filename, wptr); unlink(wptr); free(wptr); #else unlink(jk_shmem.filename); #endif jk_shmem.size = 0; JK_TRACE_EXIT(l); return rc; } base = mmap((caddr_t)0, jk_shmem.size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, 0); if (base == (caddr_t)MAP_FAILED || base == (caddr_t)0) { rc = errno; close(fd); #ifdef AS400_UTF8 wptr = (char *)malloc(strlen(jk_shmem.filename) + 1); jk_ascii2ebcdic((char *)jk_shmem.filename, wptr); unlink(wptr); free(wptr); #else unlink(jk_shmem.filename); #endif jk_shmem.size = 0; JK_TRACE_EXIT(l); return rc; } jk_shmem.hdr = base; jk_shmem.fd = fd; memset(jk_shmem.hdr, 0, jk_shmem.size); memcpy(jk_shmem.hdr->h.data.magic, shm_signature, JK_SHM_MAGIC_SIZ); jk_shmem.hdr->h.data.size = sz; jk_shmem.hdr->h.data.childs = 1; jk_shmem.hdr->h.data.maintain_checking = 0; jk_shmem.hdr->h.data.maintain_time = time(NULL); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Initialized shared memory %s size=%u free=%u addr=%#lx", jk_shm_name(), jk_shmem.size, jk_shmem.hdr->h.data.size - jk_shmem.hdr->h.data.pos, jk_shmem.hdr); } else { jk_shmem.hdr->h.data.childs++; jk_shmem.attached = (int)getpid(); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Attached shared memory %s [%d] size=%u workers=%u free=%u addr=%#lx", jk_shm_name(), jk_shmem.hdr->h.data.childs, jk_shmem.size, jk_shmem.hdr->h.data.workers - 1, jk_shmem.hdr->h.data.size - jk_shmem.hdr->h.data.pos, jk_shmem.hdr); #if 0 /* * Reset the shared memory so that * alloc works even for attached memory. * XXX: This might break already used memory * if the number of workers change between * open and attach or between two attach operations. */ if (nchild > 1) { if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "Resetting the shared memory for child %d", nchild); } } jk_shmem.hdr->h.data.pos = 0; jk_shmem.hdr->h.data.workers = 0; #endif } if ((rc = do_shm_open_lock(jk_shmem.filename, attached, l))) { if (!attached) { munmap((void *)jk_shmem.hdr, jk_shmem.size); close(jk_shmem.fd); #ifdef AS400_UTF8 wptr = (char *)malloc(strlen(jk_shmem.filename) + 1); jk_ascii2ebcdic((char *)jk_shmem.filename, wptr); unlink(wptr); free(wptr); #else unlink(jk_shmem.filename); #endif } jk_shmem.hdr = NULL; jk_shmem.fd = -1; JK_TRACE_EXIT(l); return rc; } JK_TRACE_EXIT(l); return 0; } int jk_shm_open(const char *fname, int sz, jk_logger_t *l) { return do_shm_open(fname, 0, sz, l); } int jk_shm_attach(const char *fname, int sz, jk_logger_t *l) { return do_shm_open(fname, 1, sz, l); } void jk_shm_close(jk_logger_t *l) { #ifdef AS400_UTF8 char *wptr; #endif if (jk_shmem.hdr) { if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "Closed shared memory %s childs=%u", jk_shm_name(), jk_shmem.hdr->h.data.childs); } --jk_shmem.hdr->h.data.childs; #ifdef JK_SHM_LOCK_REOPEN if (jk_shmem.fd_lock >= 0) { close(jk_shmem.fd_lock); jk_shmem.fd_lock = -1; } #endif if (jk_shmem.attached) { int p = (int)getpid(); if (p == jk_shmem.attached) { /* In case this is a forked child * do not close the shared memory. * It will be closed by the parent. */ jk_shmem.size = 0; jk_shmem.hdr = NULL; jk_shmem.fd = -1; return; } } if (jk_shmem.fd >= 0) { munmap((void *)jk_shmem.hdr, jk_shmem.size); close(jk_shmem.fd); } if (jk_shmem.fd_lock >= 0) close(jk_shmem.fd_lock); if (jk_shmem.lockname) { #ifdef AS400_UTF8 wptr = (char *)malloc(strlen(jk_shmem.lockname) + 1); jk_ascii2ebcdic((char *)jk_shmem.lockname, wptr); unlink(wptr); free(wptr); #else unlink(jk_shmem.lockname); #endif free(jk_shmem.lockname); jk_shmem.lockname = NULL; } if (jk_shmem.filename) { #ifdef AS400_UTF8 wptr = (char *)malloc(strlen(jk_shmem.filename) + 1); jk_ascii2ebcdic((char *)jk_shmem.filename, wptr); unlink(wptr); free(wptr); #else unlink(jk_shmem.filename); #endif free(jk_shmem.filename); jk_shmem.filename = NULL; } } jk_shmem.size = 0; jk_shmem.hdr = NULL; jk_shmem.fd = -1; jk_shmem.fd_lock = -1; } #endif jk_shm_worker_header_t *jk_shm_alloc_worker(jk_pool_t *p, int type, int parent_id, const char *name, jk_logger_t *l) { unsigned int i; jk_shm_worker_header_t *w = 0; if (jk_check_attribute_length("name", name, l) == JK_FALSE) { return NULL; } if (jk_shmem.hdr) { jk_shm_lock(); for (i = 0; i < jk_shmem.hdr->h.data.pos; i += JK_SHM_SLOT_SIZE) { w = (jk_shm_worker_header_t *)(jk_shmem.hdr->buf + i); if (w->type == type && w-> parent_id == parent_id && strcmp(w->name, name) == 0) { /* We have found already created worker */ jk_shm_unlock(); return w; } } /* Allocate new worker */ if ((jk_shmem.hdr->h.data.size - jk_shmem.hdr->h.data.pos) >= JK_SHM_SLOT_SIZE) { w = (jk_shm_worker_header_t *)(jk_shmem.hdr->buf + jk_shmem.hdr->h.data.pos); memset(w, 0, JK_SHM_SLOT_SIZE); strncpy(w->name, name, JK_SHM_STR_SIZ); jk_shmem.hdr->h.data.workers++; w->id = jk_shmem.hdr->h.data.workers; w->type = type; w->parent_id = parent_id; jk_shmem.hdr->h.data.pos += JK_SHM_SLOT_SIZE; } else { /* No more free memory left. */ jk_log(l, JK_LOG_ERROR, "Could not allocate shared memory for worker %s", name); w = NULL; } jk_shm_unlock(); } else if (p) { w = (jk_shm_worker_header_t *)jk_pool_alloc(p, JK_SHM_SLOT_SIZE); if (w) { memset(w, 0, JK_SHM_SLOT_SIZE); strncpy(w->name, name, JK_SHM_STR_SIZ); w->id = 0; w->type = type; w->parent_id = parent_id; } } return w; } const char *jk_shm_name() { return jk_shmem.filename; } int jk_shm_check_maintain(time_t trigger) { int rv = JK_FALSE; int maintain_checking = JK_ATOMIC_INCREMENT(&(jk_shmem.hdr->h.data.maintain_checking)); /* Another process (or thread) is already checking */ if (maintain_checking > 1) { JK_ATOMIC_DECREMENT(&(jk_shmem.hdr->h.data.maintain_checking)); return rv; } if (jk_shmem.hdr->h.data.maintain_time < trigger) { jk_shmem.hdr->h.data.maintain_time = time(NULL); rv = JK_TRUE; } JK_ATOMIC_DECREMENT(&(jk_shmem.hdr->h.data.maintain_checking)); return rv; } int jk_shm_lock() { int rc = JK_TRUE; if (!jk_shm_inited_cs) return JK_FALSE; JK_ENTER_CS(&jk_shmem.cs); #if defined (WIN32) if (jk_shm_hlock != NULL) { if (WaitForSingleObject(jk_shm_hlock, INFINITE) == WAIT_FAILED) rc = JK_FALSE; } #else if (jk_shmem.fd_lock != -1) { JK_ENTER_LOCK(jk_shmem.fd_lock, rc); } #endif return rc; } int jk_shm_unlock() { int rc = JK_TRUE; if (!jk_shm_inited_cs) return JK_FALSE; #if defined (WIN32) if (jk_shm_hlock != NULL) { ReleaseMutex(jk_shm_hlock); } #else if (jk_shmem.fd_lock != -1) { JK_LEAVE_LOCK(jk_shmem.fd_lock, rc); } #endif JK_LEAVE_CS(&jk_shmem.cs); return rc; } jk_shm_ajp_worker_t *jk_shm_alloc_ajp_worker(jk_pool_t *p, const char *name, jk_logger_t *l) { return (jk_shm_ajp_worker_t *)jk_shm_alloc_worker(p, JK_AJP13_WORKER_TYPE, 0, name, l); } jk_shm_lb_sub_worker_t *jk_shm_alloc_lb_sub_worker(jk_pool_t *p, int lb_id, const char *name, jk_logger_t *l) { return (jk_shm_lb_sub_worker_t *)jk_shm_alloc_worker(p, JK_LB_SUB_WORKER_TYPE, lb_id, name, l); } jk_shm_lb_worker_t *jk_shm_alloc_lb_worker(jk_pool_t *p, const char *name, jk_logger_t *l) { return (jk_shm_lb_worker_t *)jk_shm_alloc_worker(p, JK_LB_WORKER_TYPE, 0, name, l); } tomcat-connectors-1.2.41-src/native/common/jk_ajp14_worker.c0000644000000000000020000002476612447527647022272 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: AJP14 next generation Bi-directional protocol. * * Author: Henri Gomez * * Version: $Revision: 1648052 $ * ***************************************************************************/ #include "jk_context.h" #include "jk_ajp14_worker.h" /* * AJP14 Autoconf Phase * * CONTEXT QUERY / REPLY */ #define MAX_URI_SIZE 512 static int handle_discovery(ajp_endpoint_t * ae, jk_worker_env_t *we, jk_msg_buf_t *msg, jk_logger_t *l) { int cmd; int i, j; #if 0 /* Not used for now */ jk_login_service_t *jl = ae->worker->login; #endif jk_context_item_t *ci; jk_context_t *c; char *buf; #ifndef TESTME JK_TRACE_ENTER(l); ajp14_marshal_context_query_into_msgb(msg, we->virtual, l); jk_log(l, JK_LOG_DEBUG, "send query"); if (ajp_connection_tcp_send_message(ae, msg, l) != JK_TRUE) { JK_TRACE_EXIT(l); return JK_FALSE; } jk_log(l, JK_LOG_DEBUG, "wait context reply"); jk_b_reset(msg); if (ajp_connection_tcp_get_message(ae, msg, l) != JK_TRUE) { JK_TRACE_EXIT(l); return JK_FALSE; } if ((cmd = jk_b_get_byte(msg)) != AJP14_CONTEXT_INFO_CMD) { jk_log(l, JK_LOG_ERROR, "awaited command %d, received %d", AJP14_CONTEXT_INFO_CMD, cmd); JK_TRACE_EXIT(l); return JK_FALSE; } if (context_alloc(&c, we->virtual) != JK_TRUE) { jk_log(l, JK_LOG_ERROR, "can't allocate context room"); JK_TRACE_EXIT(l); return JK_FALSE; } if (ajp14_unmarshal_context_info(msg, c, l) != JK_TRUE) { jk_log(l, JK_LOG_ERROR, "can't get context reply"); JK_TRACE_EXIT(l); return JK_FALSE; } jk_log(l, JK_LOG_DEBUG, "received context"); buf = malloc(MAX_URI_SIZE); /* Really a very long URI */ if (!buf) { jk_log(l, JK_LOG_ERROR, "can't malloc buf"); JK_TRACE_EXIT(l); return JK_FALSE; } for (i = 0; i < c->size; i++) { ci = c->contexts[i]; for (j = 0; j < ci->size; j++) { #ifndef USE_SPRINTF snprintf(buf, MAX_URI_SIZE - 1, "/%s/%s", ci->cbase, ci->uris[j]); #else sprintf(buf, "/%s/%s", ci->cbase, ci->uris[j]); #endif jk_log(l, JK_LOG_INFO, "worker %s will handle uri %s in context %s [%s]", ae->worker->name, ci->uris[j], ci->cbase, buf); uri_worker_map_add(we->uri_to_worker, buf, ae->worker->name, SOURCE_TYPE_DISCOVER, l); } } free(buf); context_free(&c); #else uri_worker_map_add(we->uri_to_worker, "/examples/servlet/*", ae->worker->name, SOURCE_TYPE_DISCOVER, l); uri_worker_map_add(we->uri_to_worker, "/examples/*.jsp", ae->worker->name, SOURCE_TYPE_DISCOVER, l); uri_worker_map_add(we->uri_to_worker, "/examples/*.gif", ae->worker->name, SOURCE_TYPE_DISCOVER, l); #endif JK_TRACE_EXIT(l); return JK_TRUE; } /* * AJP14 Logon Phase * * INIT + REPLY / NEGO + REPLY */ static int handle_logon(ajp_endpoint_t * ae, jk_msg_buf_t *msg, jk_logger_t *l) { int cmd; jk_login_service_t *jl = ae->worker->login; JK_TRACE_ENTER(l); ajp14_marshal_login_init_into_msgb(msg, jl, l); jk_log(l, JK_LOG_DEBUG, "send init"); if (ajp_connection_tcp_send_message(ae, msg, l) != JK_TRUE) { JK_TRACE_EXIT(l); return JK_FALSE; } jk_log(l, JK_LOG_DEBUG, "wait init reply"); jk_b_reset(msg); if (ajp_connection_tcp_get_message(ae, msg, l) != JK_TRUE) { JK_TRACE_EXIT(l); return JK_FALSE; } if ((cmd = jk_b_get_byte(msg)) != AJP14_LOGSEED_CMD) { jk_log(l, JK_LOG_ERROR, "awaited command %d, received %d", AJP14_LOGSEED_CMD, cmd); JK_TRACE_EXIT(l); return JK_FALSE; } if (ajp14_unmarshal_login_seed(msg, jl, l) != JK_TRUE) { JK_TRACE_EXIT(l); return JK_FALSE; } jk_log(l, JK_LOG_DEBUG, "received entropy %s", jl->entropy); ajp14_compute_md5(jl, l); if (ajp14_marshal_login_comp_into_msgb(msg, jl, l) != JK_TRUE) { JK_TRACE_EXIT(l); return JK_FALSE; } if (ajp_connection_tcp_send_message(ae, msg, l) != JK_TRUE) { JK_TRACE_EXIT(l); return JK_FALSE; } jk_b_reset(msg); if (ajp_connection_tcp_get_message(ae, msg, l) != JK_TRUE) { JK_TRACE_EXIT(l); return JK_FALSE; } switch (jk_b_get_byte(msg)) { case AJP14_LOGOK_CMD: if (ajp14_unmarshal_log_ok(msg, jl, l) == JK_TRUE) { jk_log(l, JK_LOG_DEBUG, "Successfully connected to servlet-engine %s", jl->servlet_engine_name); JK_TRACE_EXIT(l); return JK_TRUE; } break; case AJP14_LOGNOK_CMD: ajp14_unmarshal_log_nok(msg, l); break; } JK_TRACE_EXIT(l); return JK_FALSE; } static int logon(ajp_endpoint_t * ae, jk_logger_t *l) { jk_pool_t *p = &ae->pool; jk_msg_buf_t *msg; int rc; JK_TRACE_ENTER(l); msg = jk_b_new(p); jk_b_set_buffer_size(msg, AJP13_DEF_PACKET_SIZE); if ((rc = handle_logon(ae, msg, l)) == JK_FALSE) ajp_close_endpoint(ae, l); JK_TRACE_EXIT(l); return rc; } static int discovery(ajp_endpoint_t * ae, jk_worker_env_t *we, jk_logger_t *l) { jk_pool_t *p = &ae->pool; jk_msg_buf_t *msg; int rc; JK_TRACE_ENTER(l); msg = jk_b_new(p); jk_b_set_buffer_size(msg, AJP13_DEF_PACKET_SIZE); if ((rc = handle_discovery(ae, we, msg, l)) == JK_FALSE) ajp_close_endpoint(ae, l); JK_TRACE_EXIT(l); return rc; } /* -------------------- Method -------------------- */ static int JK_METHOD validate(jk_worker_t *pThis, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l) { ajp_worker_t *aw; const char *secret_key; JK_TRACE_ENTER(l); if (ajp_validate(pThis, props, we, l, AJP14_PROTO) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } aw = pThis->worker_private; secret_key = jk_get_worker_secret_key(props, aw->name); if ((!secret_key) || (!strlen(secret_key))) { jk_log(l, JK_LOG_ERROR, "validate error, empty or missing secretkey"); JK_TRACE_EXIT(l); return JK_FALSE; } /* jk_log(l, JK_LOG_DEBUG, "Into ajp14:validate - secret_key=%s", secret_key); */ JK_TRACE_EXIT(l); return JK_TRUE; } static int JK_METHOD get_endpoint(jk_worker_t *pThis, jk_endpoint_t **pend, jk_logger_t *l) { int rc; JK_TRACE_ENTER(l); rc = ajp_get_endpoint(pThis, pend, l, AJP14_PROTO); JK_TRACE_EXIT(l); return rc; } static int JK_METHOD init(jk_worker_t *pThis, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l) { ajp_worker_t *aw; ajp_endpoint_t *ae; jk_endpoint_t *je; int rc; JK_TRACE_EXIT(l); if (ajp_init(pThis, props, we, l, AJP14_PROTO) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } aw = pThis->worker_private; /* Set Secret Key (used at logon time) */ aw->login->secret_key = jk_get_worker_secret_key(props, aw->name); if (aw->login->secret_key == NULL) { jk_log(l, JK_LOG_ERROR, "can't malloc secret_key"); JK_TRACE_EXIT(l); return JK_FALSE; } /* Set WebServerName (used at logon time) */ aw->login->web_server_name = strdup(we->server_name); if (aw->login->web_server_name == NULL) { jk_log(l, JK_LOG_ERROR, "can't malloc web_server_name"); JK_TRACE_EXIT(l); return JK_FALSE; } if (get_endpoint(pThis, &je, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } ae = je->endpoint_private; if (ajp_connect_to_endpoint(ae, l) == JK_TRUE) { /* connection stage passed - try to get context info * this is the long awaited autoconf feature :) */ rc = discovery(ae, we, l); ajp_close_endpoint(ae, l); JK_TRACE_EXIT(l); return rc; } JK_TRACE_EXIT(l); return JK_TRUE; } static int JK_METHOD destroy(jk_worker_t **pThis, jk_logger_t *l) { int rc; ajp_worker_t *aw = (*pThis)->worker_private; JK_TRACE_ENTER(l); if (aw->login) { free(aw->login); aw->login = NULL; } rc = ajp_destroy(pThis, l, AJP14_PROTO); JK_TRACE_EXIT(l); return rc; } int JK_METHOD ajp14_worker_factory(jk_worker_t **w, const char *name, jk_logger_t *l) { ajp_worker_t *aw; JK_TRACE_ENTER(l); if (ajp_worker_factory(w, name, l) == JK_FALSE) return 0; aw = (*w)->worker_private; aw->proto = AJP14_PROTO; aw->login = (jk_login_service_t *)malloc(sizeof(jk_login_service_t)); if (aw->login == NULL) { jk_log(l, JK_LOG_ERROR, "malloc failed for login area"); JK_TRACE_EXIT(l); return 0; } memset(aw->login, 0, sizeof(jk_login_service_t)); aw->login->negotiation = (AJP14_CONTEXT_INFO_NEG | AJP14_PROTO_SUPPORT_AJP14_NEG); aw->login->web_server_name = NULL; /* must be set in init */ aw->worker.validate = validate; aw->worker.init = init; aw->worker.get_endpoint = get_endpoint; aw->worker.destroy = destroy; aw->logon = logon; /* LogOn Handler for AJP14 */ JK_TRACE_EXIT(l); return JK_AJP14_WORKER_TYPE; } tomcat-connectors-1.2.41-src/native/common/ap_snprintf.c0000644000000000000020000010534611007303570021565 0ustar rootbin/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * This code is based on, and used with the permission of, the * SIO stdio-replacement strx_* functions by Panos Tsirigotis * for xinetd. */ #define BUILD_STANDALONE #ifndef BUILD_STANDALONE #include "httpd.h" #else #include "ap_snprintf.h" #endif #include #include #ifndef NETWARE #include #endif #include #include #include #include #ifdef WIN32 #include #endif typedef enum { NO = 0, YES = 1 } boolean_e; #ifndef FALSE #define FALSE 0 #endif #ifndef TRUE #define TRUE 1 #endif #ifndef AP_LONGEST_LONG #define AP_LONGEST_LONG long #endif #define NUL '\0' #define WIDE_INT long #define WIDEST_INT AP_LONGEST_LONG typedef WIDE_INT wide_int; typedef unsigned WIDE_INT u_wide_int; typedef WIDEST_INT widest_int; #ifdef __TANDEM /* Although Tandem supports "long long" there is no unsigned variant. */ typedef unsigned long u_widest_int; #else typedef unsigned WIDEST_INT u_widest_int; #endif typedef int bool_int; #define S_NULL "(null)" #define S_NULL_LEN 6 #define FLOAT_DIGITS 6 #define EXPONENT_LENGTH 10 /* * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions * * XXX: this is a magic number; do not decrease it */ #define NUM_BUF_SIZE 512 /* * cvt - IEEE floating point formatting routines. * Derived from UNIX V7, Copyright(C) Caldera International Inc. */ /* * ap_ecvt converts to decimal * the number of digits is specified by ndigit * decpt is set to the position of the decimal point * sign is set to 0 for positive, 1 for negative */ #define NDIG 80 /* buf must have at least NDIG bytes */ static char *ap_cvt(double arg, int ndigits, int *decpt, int *sign, int eflag, char *buf) { register int r2; double fi, fj; register char *p, *p1; if (ndigits >= NDIG - 1) ndigits = NDIG - 2; r2 = 0; *sign = 0; p = &buf[0]; if (arg < 0) { *sign = 1; arg = -arg; } arg = modf(arg, &fi); p1 = &buf[NDIG]; /* * Do integer part */ if (fi != 0) { p1 = &buf[NDIG]; while (p1 > &buf[0] && fi != 0) { fj = modf(fi / 10, &fi); *--p1 = (int) ((fj + .03) * 10) + '0'; r2++; } while (p1 < &buf[NDIG]) *p++ = *p1++; } else if (arg > 0) { while ((fj = arg * 10) < 1) { arg = fj; r2--; } } p1 = &buf[ndigits]; if (eflag == 0) p1 += r2; *decpt = r2; if (p1 < &buf[0]) { buf[0] = '\0'; return (buf); } while (p <= p1 && p < &buf[NDIG]) { arg *= 10; arg = modf(arg, &fj); *p++ = (int) fj + '0'; } if (p1 >= &buf[NDIG]) { buf[NDIG - 1] = '\0'; return (buf); } p = p1; *p1 += 5; while (*p1 > '9') { *p1 = '0'; if (p1 > buf) ++ * --p1; else { *p1 = '1'; (*decpt)++; if (eflag == 0) { if (p > buf) *p = '0'; p++; } } } *p = '\0'; return (buf); } static char *ap_ecvt(double arg, int ndigits, int *decpt, int *sign, char *buf) { return (ap_cvt(arg, ndigits, decpt, sign, 1, buf)); } static char *ap_fcvt(double arg, int ndigits, int *decpt, int *sign, char *buf) { return (ap_cvt(arg, ndigits, decpt, sign, 0, buf)); } /* * ap_gcvt - Floating output conversion to * minimal length string */ static char *ap_gcvt(double number, int ndigit, char *buf, boolean_e altform) { int sign, decpt; register char *p1, *p2; register int i; char buf1[NDIG]; p1 = ap_ecvt(number, ndigit, &decpt, &sign, buf1); p2 = buf; if (sign) *p2++ = '-'; for (i = ndigit - 1; i > 0 && p1[i] == '0'; i--) ndigit--; if ((decpt >= 0 && decpt - ndigit > 4) || (decpt < 0 && decpt < -3)) { /* use E-style */ decpt--; *p2++ = *p1++; *p2++ = '.'; for (i = 1; i < ndigit; i++) *p2++ = *p1++; *p2++ = 'e'; if (decpt < 0) { decpt = -decpt; *p2++ = '-'; } else *p2++ = '+'; if (decpt / 100 > 0) *p2++ = decpt / 100 + '0'; if (decpt / 10 > 0) *p2++ = (decpt % 100) / 10 + '0'; *p2++ = decpt % 10 + '0'; } else { if (decpt <= 0) { if (*p1 != '0') *p2++ = '.'; while (decpt < 0) { decpt++; *p2++ = '0'; } } for (i = 1; i <= ndigit; i++) { *p2++ = *p1++; if (i == decpt) *p2++ = '.'; } if (ndigit < decpt) { while (ndigit++ < decpt) *p2++ = '0'; *p2++ = '.'; } } if (p2[-1] == '.' && !altform) p2--; *p2 = '\0'; return (buf); } /* * The INS_CHAR macro inserts a character in the buffer and writes * the buffer back to disk if necessary * It uses the char pointers sp and bep: * sp points to the next available character in the buffer * bep points to the end-of-buffer+1 * While using this macro, note that the nextb pointer is NOT updated. * * NOTE: Evaluation of the c argument should not have any side-effects */ #define INS_CHAR(c, sp, bep, cc) \ { \ if (sp >= bep) { \ vbuff->curpos = sp; \ if (flush_func(vbuff)) \ return -1; \ sp = vbuff->curpos; \ bep = vbuff->endpos; \ } \ *sp++ = (c); \ cc++; \ } #define NUM( c ) ( c - '0' ) #define STR_TO_DEC( str, num ) \ num = NUM( *str++ ) ; \ while ( ap_isdigit( *str ) ) \ { \ num *= 10 ; \ num += NUM( *str++ ) ; \ } /* * This macro does zero padding so that the precision * requirement is satisfied. The padding is done by * adding '0's to the left of the string that is going * to be printed. We don't allow precision to be large * enough that we continue past the start of s. * * NOTE: this makes use of the magic info that s is * always based on num_buf with a size of NUM_BUF_SIZE. */ #define FIX_PRECISION( adjust, precision, s, s_len ) \ if ( adjust ) { \ int p = precision < NUM_BUF_SIZE - 1 ? precision : NUM_BUF_SIZE - 1; \ while ( s_len < p ) \ { \ *--s = '0' ; \ s_len++ ; \ } \ } /* * Macro that does padding. The padding is done by printing * the character ch. */ #define PAD( width, len, ch ) do \ { \ INS_CHAR( ch, sp, bep, cc ) ; \ width-- ; \ } \ while ( width > len ) /* * Prefix the character ch to the string str * Increase length * Set the has_prefix flag */ #define PREFIX( str, length, ch ) *--str = ch ; length++ ; has_prefix = YES /* * Convert num to its decimal format. * Return value: * - a pointer to a string containing the number (no sign) * - len contains the length of the string * - is_negative is set to TRUE or FALSE depending on the sign * of the number (always set to FALSE if is_unsigned is TRUE) * * The caller provides a buffer for the string: that is the buf_end argument * which is a pointer to the END of the buffer + 1 (i.e. if the buffer * is declared as buf[ 100 ], buf_end should be &buf[ 100 ]) * * Note: we have 2 versions. One is used when we need to use quads * (conv_10_quad), the other when we don't (conv_10). We're assuming the * latter is faster. */ static char *conv_10(register wide_int num, register bool_int is_unsigned, register bool_int *is_negative, char *buf_end, register int *len) { register char *p = buf_end; register u_wide_int magnitude; if (is_unsigned) { magnitude = (u_wide_int) num; *is_negative = FALSE; } else { *is_negative = (num < 0); /* * On a 2's complement machine, negating the most negative integer * results in a number that cannot be represented as a signed integer. * Here is what we do to obtain the number's magnitude: * a. add 1 to the number * b. negate it (becomes positive) * c. convert it to unsigned * d. add 1 */ if (*is_negative) { wide_int t = num + 1; magnitude = ((u_wide_int) -t) + 1; } else magnitude = (u_wide_int) num; } /* * We use a do-while loop so that we write at least 1 digit */ do { register u_wide_int new_magnitude = magnitude / 10; *--p = (char) (magnitude - new_magnitude * 10 + '0'); magnitude = new_magnitude; } while (magnitude); *len = buf_end - p; return (p); } static char *conv_10_quad(widest_int num, register bool_int is_unsigned, register bool_int *is_negative, char *buf_end, register int *len) { register char *p = buf_end; u_widest_int magnitude; /* * We see if we can use the faster non-quad version by checking the * number against the largest long value it can be. If <=, we * punt to the quicker version. */ if ((num <= ULONG_MAX && is_unsigned) || (num <= LONG_MAX && !is_unsigned)) return(conv_10( (wide_int)num, is_unsigned, is_negative, buf_end, len)); if (is_unsigned) { magnitude = (u_widest_int) num; *is_negative = FALSE; } else { *is_negative = (num < 0); /* * On a 2's complement machine, negating the most negative integer * results in a number that cannot be represented as a signed integer. * Here is what we do to obtain the number's magnitude: * a. add 1 to the number * b. negate it (becomes positive) * c. convert it to unsigned * d. add 1 */ if (*is_negative) { widest_int t = num + 1; magnitude = ((u_widest_int) -t) + 1; } else magnitude = (u_widest_int) num; } /* * We use a do-while loop so that we write at least 1 digit */ do { u_widest_int new_magnitude = magnitude / 10; *--p = (char) (magnitude - new_magnitude * 10 + '0'); magnitude = new_magnitude; } while (magnitude); *len = buf_end - p; return (p); } #ifndef BUILD_STANDALONE static char *conv_in_addr(struct in_addr *ia, char *buf_end, int *len) { unsigned addr = ntohl(ia->s_addr); char *p = buf_end; bool_int is_negative; int sub_len; p = conv_10((addr & 0x000000FF) , TRUE, &is_negative, p, &sub_len); *--p = '.'; p = conv_10((addr & 0x0000FF00) >> 8, TRUE, &is_negative, p, &sub_len); *--p = '.'; p = conv_10((addr & 0x00FF0000) >> 16, TRUE, &is_negative, p, &sub_len); *--p = '.'; p = conv_10((addr & 0xFF000000) >> 24, TRUE, &is_negative, p, &sub_len); *len = buf_end - p; return (p); } static char *conv_sockaddr_in(struct sockaddr_in *si, char *buf_end, int *len) { char *p = buf_end; bool_int is_negative; int sub_len; p = conv_10(ntohs(si->sin_port), TRUE, &is_negative, p, &sub_len); *--p = ':'; p = conv_in_addr(&si->sin_addr, p, &sub_len); *len = buf_end - p; return (p); } #endif /* * Convert a floating point number to a string formats 'f', 'e' or 'E'. * The result is placed in buf, and len denotes the length of the string * The sign is returned in the is_negative argument (and is not placed * in buf). */ static char *conv_fp(register char format, register double num, boolean_e add_dp, int precision, bool_int *is_negative, char *buf, int *len) { register char *s = buf; register char *p; int decimal_point; char buf1[NDIG]; if (format == 'f') p = ap_fcvt(num, precision, &decimal_point, is_negative, buf1); else /* either e or E format */ p = ap_ecvt(num, precision + 1, &decimal_point, is_negative, buf1); /* * Check for Infinity and NaN */ if (ap_isalpha(*p)) { *len = strlen(strcpy(buf, p)); *is_negative = FALSE; return (buf); } if (format == 'f') { if (decimal_point <= 0) { *s++ = '0'; if (precision > 0) { *s++ = '.'; while (decimal_point++ < 0) *s++ = '0'; } else if (add_dp) *s++ = '.'; } else { while (decimal_point-- > 0) *s++ = *p++; if (precision > 0 || add_dp) *s++ = '.'; } } else { *s++ = *p++; if (precision > 0 || add_dp) *s++ = '.'; } /* * copy the rest of p, the NUL is NOT copied */ while (*p) *s++ = *p++; if (format != 'f') { char temp[EXPONENT_LENGTH]; /* for exponent conversion */ int t_len; bool_int exponent_is_negative; *s++ = format; /* either e or E */ decimal_point--; if (decimal_point != 0) { p = conv_10((wide_int) decimal_point, FALSE, &exponent_is_negative, &temp[EXPONENT_LENGTH], &t_len); *s++ = exponent_is_negative ? '-' : '+'; /* * Make sure the exponent has at least 2 digits */ if (t_len == 1) *s++ = '0'; while (t_len--) *s++ = *p++; } else { *s++ = '+'; *s++ = '0'; *s++ = '0'; } } *len = s - buf; return (buf); } /* * Convert num to a base X number where X is a power of 2. nbits determines X. * For example, if nbits is 3, we do base 8 conversion * Return value: * a pointer to a string containing the number * * The caller provides a buffer for the string: that is the buf_end argument * which is a pointer to the END of the buffer + 1 (i.e. if the buffer * is declared as buf[ 100 ], buf_end should be &buf[ 100 ]) * * As with conv_10, we have a faster version which is used when * the number isn't quad size. */ static char *conv_p2(register u_wide_int num, register int nbits, char format, char *buf_end, register int *len) { register int mask = (1 << nbits) - 1; register char *p = buf_end; static const char low_digits[] = "0123456789abcdef"; static const char upper_digits[] = "0123456789ABCDEF"; register const char *digits = (format == 'X') ? upper_digits : low_digits; do { *--p = digits[num & mask]; num >>= nbits; } while (num); *len = buf_end - p; return (p); } static char *conv_p2_quad(u_widest_int num, register int nbits, char format, char *buf_end, register int *len) { register int mask = (1 << nbits) - 1; register char *p = buf_end; static const char low_digits[] = "0123456789abcdef"; static const char upper_digits[] = "0123456789ABCDEF"; register const char *digits = (format == 'X') ? upper_digits : low_digits; if (num <= ULONG_MAX) return(conv_p2( (u_wide_int)num, nbits, format, buf_end, len)); do { *--p = digits[num & mask]; num >>= nbits; } while (num); *len = buf_end - p; return (p); } /* * Do format conversion placing the output in buffer */ API_EXPORT(int) ap_vformatter(int (*flush_func)(ap_vformatter_buff *), ap_vformatter_buff *vbuff, const char *fmt, va_list ap) { register char *sp; register char *bep; register int cc = 0; register int i; register char *s = NULL; char *q; int s_len; register int min_width = 0; int precision = 0; enum { LEFT, RIGHT } adjust; char pad_char; char prefix_char; double fp_num; widest_int i_quad = (widest_int) 0; u_widest_int ui_quad; wide_int i_num = (wide_int) 0; u_wide_int ui_num; char num_buf[NUM_BUF_SIZE]; char char_buf[2]; /* for printing %% and % */ enum var_type_enum { IS_QUAD, IS_LONG, IS_SHORT, IS_INT }; enum var_type_enum var_type = IS_INT; /* * Flag variables */ boolean_e alternate_form; boolean_e print_sign; boolean_e print_blank; boolean_e adjust_precision; boolean_e adjust_width; bool_int is_negative; sp = vbuff->curpos; bep = vbuff->endpos; while (*fmt) { if (*fmt != '%') { INS_CHAR(*fmt, sp, bep, cc); } else { /* * Default variable settings */ adjust = RIGHT; alternate_form = print_sign = print_blank = NO; pad_char = ' '; prefix_char = NUL; fmt++; /* * Try to avoid checking for flags, width or precision */ if (!ap_islower(*fmt)) { /* * Recognize flags: -, #, BLANK, + */ for (;; fmt++) { if (*fmt == '-') adjust = LEFT; else if (*fmt == '+') print_sign = YES; else if (*fmt == '#') alternate_form = YES; else if (*fmt == ' ') print_blank = YES; else if (*fmt == '0') pad_char = '0'; else break; } /* * Check if a width was specified */ if (ap_isdigit(*fmt)) { STR_TO_DEC(fmt, min_width); adjust_width = YES; } else if (*fmt == '*') { min_width = va_arg(ap, int); fmt++; adjust_width = YES; if (min_width < 0) { adjust = LEFT; min_width = -min_width; } } else adjust_width = NO; /* * Check if a precision was specified */ if (*fmt == '.') { adjust_precision = YES; fmt++; if (ap_isdigit(*fmt)) { STR_TO_DEC(fmt, precision); } else if (*fmt == '*') { precision = va_arg(ap, int); fmt++; if (precision < 0) precision = 0; } else precision = 0; } else adjust_precision = NO; } else adjust_precision = adjust_width = NO; /* * Modifier check */ if (*fmt == 'q') { var_type = IS_QUAD; fmt++; } else if (*fmt == 'l') { var_type = IS_LONG; fmt++; } else if (*fmt == 'h') { var_type = IS_SHORT; fmt++; } else { var_type = IS_INT; } /* * Argument extraction and printing. * First we determine the argument type. * Then, we convert the argument to a string. * On exit from the switch, s points to the string that * must be printed, s_len has the length of the string * The precision requirements, if any, are reflected in s_len. * * NOTE: pad_char may be set to '0' because of the 0 flag. * It is reset to ' ' by non-numeric formats */ switch (*fmt) { case 'u': if (var_type == IS_QUAD) { i_quad = va_arg(ap, u_widest_int); s = conv_10_quad(i_quad, 1, &is_negative, &num_buf[NUM_BUF_SIZE], &s_len); } else { if (var_type == IS_LONG) i_num = (wide_int) va_arg(ap, u_wide_int); else if (var_type == IS_SHORT) i_num = (wide_int) (unsigned short) va_arg(ap, unsigned int); else i_num = (wide_int) va_arg(ap, unsigned int); s = conv_10(i_num, 1, &is_negative, &num_buf[NUM_BUF_SIZE], &s_len); } FIX_PRECISION(adjust_precision, precision, s, s_len); break; case 'd': case 'i': if (var_type == IS_QUAD) { i_quad = va_arg(ap, widest_int); s = conv_10_quad(i_quad, 0, &is_negative, &num_buf[NUM_BUF_SIZE], &s_len); } else { if (var_type == IS_LONG) i_num = (wide_int) va_arg(ap, wide_int); else if (var_type == IS_SHORT) i_num = (wide_int) (short) va_arg(ap, int); else i_num = (wide_int) va_arg(ap, int); s = conv_10(i_num, 0, &is_negative, &num_buf[NUM_BUF_SIZE], &s_len); } FIX_PRECISION(adjust_precision, precision, s, s_len); if (is_negative) prefix_char = '-'; else if (print_sign) prefix_char = '+'; else if (print_blank) prefix_char = ' '; break; case 'o': if (var_type == IS_QUAD) { ui_quad = va_arg(ap, u_widest_int); s = conv_p2_quad(ui_quad, 3, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); } else { if (var_type == IS_LONG) ui_num = (u_wide_int) va_arg(ap, u_wide_int); else if (var_type == IS_SHORT) ui_num = (u_wide_int) (unsigned short) va_arg(ap, unsigned int); else ui_num = (u_wide_int) va_arg(ap, unsigned int); s = conv_p2(ui_num, 3, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); } FIX_PRECISION(adjust_precision, precision, s, s_len); if (alternate_form && *s != '0') { *--s = '0'; s_len++; } break; case 'x': case 'X': if (var_type == IS_QUAD) { ui_quad = va_arg(ap, u_widest_int); s = conv_p2_quad(ui_quad, 4, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); } else { if (var_type == IS_LONG) ui_num = (u_wide_int) va_arg(ap, u_wide_int); else if (var_type == IS_SHORT) ui_num = (u_wide_int) (unsigned short) va_arg(ap, unsigned int); else ui_num = (u_wide_int) va_arg(ap, unsigned int); s = conv_p2(ui_num, 4, *fmt, &num_buf[NUM_BUF_SIZE], &s_len); } FIX_PRECISION(adjust_precision, precision, s, s_len); if (alternate_form && i_num != 0) { *--s = *fmt; /* 'x' or 'X' */ *--s = '0'; s_len += 2; } break; case 's': s = va_arg(ap, char *); if (s != NULL) { s_len = strlen(s); if (adjust_precision && precision < s_len) s_len = precision; } else { s = S_NULL; s_len = S_NULL_LEN; } pad_char = ' '; break; case 'f': case 'e': case 'E': fp_num = va_arg(ap, double); /* * * We use &num_buf[ 1 ], so that we have room for the sign */ #ifdef HAVE_ISNAN if (isnan(fp_num)) { s = "nan"; s_len = 3; } else #endif #ifdef HAVE_ISINF if (isinf(fp_num)) { s = "inf"; s_len = 3; } else #endif { s = conv_fp(*fmt, fp_num, alternate_form, (adjust_precision == NO) ? FLOAT_DIGITS : precision, &is_negative, &num_buf[1], &s_len); if (is_negative) prefix_char = '-'; else if (print_sign) prefix_char = '+'; else if (print_blank) prefix_char = ' '; } break; case 'g': case 'G': if (adjust_precision == NO) precision = FLOAT_DIGITS; else if (precision == 0) precision = 1; /* * * We use &num_buf[ 1 ], so that we have room for the sign */ s = ap_gcvt(va_arg(ap, double), precision, &num_buf[1], alternate_form); if (*s == '-') prefix_char = *s++; else if (print_sign) prefix_char = '+'; else if (print_blank) prefix_char = ' '; s_len = strlen(s); if (alternate_form && (q = strchr(s, '.')) == NULL) { s[s_len++] = '.'; s[s_len] = '\0'; /* delimit for following strchr() */ } if (*fmt == 'G' && (q = strchr(s, 'e')) != NULL) *q = 'E'; break; case 'c': char_buf[0] = (char) (va_arg(ap, int)); s = &char_buf[0]; s_len = 1; pad_char = ' '; break; case '%': char_buf[0] = '%'; s = &char_buf[0]; s_len = 1; pad_char = ' '; break; case 'n': if (var_type == IS_QUAD) *(va_arg(ap, widest_int *)) = cc; else if (var_type == IS_LONG) *(va_arg(ap, long *)) = cc; else if (var_type == IS_SHORT) *(va_arg(ap, short *)) = cc; else *(va_arg(ap, int *)) = cc; break; /* * This is where we extend the printf format, with a second * type specifier */ case 'p': switch(*++fmt) { /* * If the pointer size is equal to or smaller than the size * of the largest unsigned int, we convert the pointer to a * hex number, otherwise we print "%p" to indicate that we * don't handle "%p". */ case 'p': #ifdef AP_VOID_P_IS_QUAD if (sizeof(void *) <= sizeof(u_widest_int)) { ui_quad = (u_widest_int) va_arg(ap, void *); s = conv_p2_quad(ui_quad, 4, 'x', &num_buf[NUM_BUF_SIZE], &s_len); } #else if (sizeof(void *) <= sizeof(u_wide_int)) { ui_num = (u_wide_int) va_arg(ap, void *); s = conv_p2(ui_num, 4, 'x', &num_buf[NUM_BUF_SIZE], &s_len); } #endif else { s = "%p"; s_len = 2; prefix_char = NUL; } pad_char = ' '; break; #ifndef BUILD_STANDALONE /* print a struct sockaddr_in as a.b.c.d:port */ case 'I': { struct sockaddr_in *si; si = va_arg(ap, struct sockaddr_in *); if (si != NULL) { s = conv_sockaddr_in(si, &num_buf[NUM_BUF_SIZE], &s_len); if (adjust_precision && precision < s_len) s_len = precision; } else { s = S_NULL; s_len = S_NULL_LEN; } pad_char = ' '; } break; /* print a struct in_addr as a.b.c.d */ case 'A': { struct in_addr *ia; ia = va_arg(ap, struct in_addr *); if (ia != NULL) { s = conv_in_addr(ia, &num_buf[NUM_BUF_SIZE], &s_len); if (adjust_precision && precision < s_len) s_len = precision; } else { s = S_NULL; s_len = S_NULL_LEN; } pad_char = ' '; } break; #endif case NUL: /* if %p ends the string, oh well ignore it */ continue; default: s = "bogus %p"; s_len = 8; prefix_char = NUL; break; } break; case NUL: /* * The last character of the format string was %. * We ignore it. */ continue; /* * The default case is for unrecognized %'s. * We print % to help the user identify what * option is not understood. * This is also useful in case the user wants to pass * the output of format_converter to another function * that understands some other % (like syslog). * Note that we can't point s inside fmt because the * unknown could be preceded by width etc. */ default: char_buf[0] = '%'; char_buf[1] = *fmt; s = char_buf; s_len = 2; pad_char = ' '; break; } if (prefix_char != NUL && s != S_NULL && s != char_buf) { *--s = prefix_char; s_len++; } if (adjust_width && adjust == RIGHT && min_width > s_len) { if (pad_char == '0' && prefix_char != NUL) { INS_CHAR(*s, sp, bep, cc); s++; s_len--; min_width--; } PAD(min_width, s_len, pad_char); } /* * Print the string s. */ for (i = s_len; i != 0; i--) { INS_CHAR(*s, sp, bep, cc); s++; } if (adjust_width && adjust == LEFT && min_width > s_len) PAD(min_width, s_len, pad_char); } fmt++; } vbuff->curpos = sp; return cc; } static int snprintf_flush(ap_vformatter_buff *vbuff) { /* if the buffer fills we have to abort immediately, there is no way * to "flush" an ap_snprintf... there's nowhere to flush it to. */ return -1; } API_EXPORT_NONSTD(int) ap_snprintf(char *buf, size_t len, const char *format,...) { int cc; va_list ap; ap_vformatter_buff vbuff; if (len == 0) return 0; /* save one byte for nul terminator */ vbuff.curpos = buf; vbuff.endpos = buf + len - 1; va_start(ap, format); cc = ap_vformatter(snprintf_flush, &vbuff, format, ap); va_end(ap); *vbuff.curpos = '\0'; return (cc == -1) ? len : cc; } API_EXPORT(int) ap_vsnprintf(char *buf, size_t len, const char *format, va_list ap) { int cc; ap_vformatter_buff vbuff; if (len == 0) return 0; /* save one byte for nul terminator */ vbuff.curpos = buf; vbuff.endpos = buf + len - 1; cc = ap_vformatter(snprintf_flush, &vbuff, format, ap); *vbuff.curpos = '\0'; return (cc == -1) ? len : cc; } tomcat-connectors-1.2.41-src/native/common/jk_mt.h0000644000000000000020000001050411660566755020367 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Multi thread portability code for JK * * Author: Gal Shachor * * Version: $Revision: 1202459 $ * ***************************************************************************/ #ifndef _JK_MT_H #define _JK_MT_H #include "jk_global.h" #if defined(WIN32) #define jk_gettid() ((jk_uint32_t)GetCurrentThreadId()) #elif defined(NETWARE) && !defined(__NOVELL_LIBC__) #define getpid() ((int)GetThreadGroupID()) #endif #ifdef JK_PREFORK #define _MT_CODE 0 #else #define _MT_CODE 1 #endif /* * Marks execution under MT compilation */ #if _MT_CODE #ifdef WIN32 #include typedef CRITICAL_SECTION JK_CRIT_SEC; #define JK_INIT_CS(x, rc) InitializeCriticalSection(x); rc = JK_TRUE #define JK_DELETE_CS(x) DeleteCriticalSection(x) #define JK_ENTER_CS(x) EnterCriticalSection(x) #define JK_LEAVE_CS(x) LeaveCriticalSection(x) #else /* !WIN32 */ #define _MT_CODE_PTHREAD #include #include #include typedef pthread_mutex_t JK_CRIT_SEC; #define JK_INIT_CS(x, rc) \ if (pthread_mutex_init(x, NULL)) rc = JK_FALSE; else rc = JK_TRUE #define JK_DELETE_CS(x) pthread_mutex_destroy(x) #define JK_ENTER_CS(x) pthread_mutex_lock(x) #define JK_LEAVE_CS(x) pthread_mutex_unlock(x) #if defined(AS400) || defined(NETWARE) #define jk_pthread_t jk_uint32_t #endif /* AS400 || NETWARE */ jk_pthread_t jk_gettid(void); #endif /* WIN32 */ #else /* !_MT_CODE */ typedef void *JK_CRIT_SEC; #define JK_INIT_CS(x, rc) rc = JK_TRUE #define JK_DELETE_CS(x) (void)0 #define JK_ENTER_CS(x) (void)0 #define JK_LEAVE_CS(x) (void)0 #define jk_gettid() 0 #endif /* MT_CODE */ #if !defined(WIN32) && !defined(NETWARE) #include #include #if HAVE_FLOCK #ifdef JK_USE_FLOCK #define USE_FLOCK_LK 1 #endif #endif #ifndef USE_FLOCK_LK #define USE_FLOCK_LK 0 #endif #if USE_FLOCK_LK #include #define JK_ENTER_LOCK(x, rc) \ do { \ while ((rc = flock((x), LOCK_EX) < 0) && (errno == EINTR)); \ rc = rc == 0 ? JK_TRUE : JK_FALSE; \ } while (0) #define JK_LEAVE_LOCK(x, rc) \ do { \ while ((rc = flock((x), LOCK_UN) < 0) && (errno == EINTR)); \ rc = rc == 0 ? JK_TRUE : JK_FALSE; \ } while (0) #else /* !USE_FLOCK_LK */ #define JK_ENTER_LOCK(x, rc) \ do { \ struct flock _fl; \ _fl.l_type = F_WRLCK; \ _fl.l_whence = SEEK_SET; \ _fl.l_start = 0; \ _fl.l_len = 1L; \ _fl.l_pid = 0; \ while ((rc = fcntl((x), F_SETLKW, &_fl) < 0) && (errno == EINTR)); \ rc = rc == 0 ? JK_TRUE : JK_FALSE; \ } while (0) #define JK_LEAVE_LOCK(x, rc) \ do { \ struct flock _fl; \ _fl.l_type = F_UNLCK; \ _fl.l_whence = SEEK_SET; \ _fl.l_start = 0; \ _fl.l_len = 1L; \ _fl.l_pid = 0; \ while ((rc = fcntl((x), F_SETLKW, &_fl) < 0) && (errno == EINTR)); \ rc = rc == 0 ? JK_TRUE : JK_FALSE; \ } while (0) #endif /* USE_FLOCK_LK */ #else /* WIN32 || NETWARE */ #define JK_ENTER_LOCK(x, rc) rc = JK_TRUE #define JK_LEAVE_LOCK(x, rc) rc = JK_TRUE #endif #endif /* _JK_MT_H */ tomcat-connectors-1.2.41-src/native/common/jk_ajp13_worker.h0000644000000000000020000000344510516516102022240 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: ajpv1.3 worker header file * * Author: Gal Shachor * * Version: $Revision: 466585 $ * ***************************************************************************/ #ifndef JK_AJP13_WORKER_H #define JK_AJP13_WORKER_H #include "jk_pool.h" #include "jk_connect.h" #include "jk_util.h" #include "jk_msg_buff.h" #include "jk_ajp_common.h" #include "jk_ajp13.h" #include "jk_logger.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define JK_AJP13_WORKER_NAME ("ajp13") #define JK_AJP13_WORKER_TYPE (2) int JK_METHOD ajp13_worker_factory(jk_worker_t **w, const char *name, jk_logger_t *l); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_AJP13_WORKER_H */ tomcat-connectors-1.2.41-src/native/common/jk_context.c0000644000000000000020000001374410516516102021413 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Context handling (Autoconf) * * Author: Henri Gomez * * Version: $Revision: 466585 $ * ***************************************************************************/ #include "jk_global.h" #include "jk_context.h" #include "jk_ajp_common.h" /* * Set the virtual name of the context */ int context_set_virtual(jk_context_t *c, char *virt) { if (c) { if (virt) { c->virt = jk_pool_strdup(&c->p, virt); if (!c->virt) return JK_FALSE; } return JK_TRUE; } return JK_FALSE; } /* * Init the context info struct */ int context_open(jk_context_t *c, char *virt) { if (c) { jk_open_pool(&c->p, c->buf, sizeof(jk_pool_atom_t) * SMALL_POOL_SIZE); c->size = 0; c->capacity = 0; c->contexts = NULL; return context_set_virtual(c, virt); } return JK_FALSE; } /* * Close the context info struct */ int context_close(jk_context_t *c) { if (c) { jk_close_pool(&c->p); return JK_TRUE; } return JK_FALSE; } /* * Allocate and open context */ int context_alloc(jk_context_t **c, char *virt) { if (c) return context_open(*c = (jk_context_t *)calloc(1, sizeof(jk_context_t)), virt); return JK_FALSE; } /* * Close and destroy context */ int context_free(jk_context_t **c) { if (c && *c) { context_close(*c); free(*c); *c = NULL; return JK_TRUE; } return JK_FALSE; } /* * Ensure there will be memory in context info to store Context Bases */ static int context_realloc(jk_context_t *c) { if (c->size == c->capacity) { jk_context_item_t **contexts; int capacity = c->capacity + CBASE_INC_SIZE; contexts = (jk_context_item_t **)jk_pool_alloc(&c->p, sizeof(jk_context_item_t *) * capacity); if (!contexts) return JK_FALSE; if (c->capacity && c->contexts) memcpy(contexts, c->contexts, sizeof(jk_context_item_t *) * c->capacity); c->contexts = contexts; c->capacity = capacity; } return JK_TRUE; } /* * Ensure there will be memory in context info to URIS */ static int context_item_realloc(jk_context_t *c, jk_context_item_t *ci) { if (ci->size == ci->capacity) { char **uris; int capacity = ci->capacity + URI_INC_SIZE; uris = (char **)jk_pool_alloc(&c->p, sizeof(char *) * capacity); if (!uris) return JK_FALSE; memcpy(uris, ci->uris, sizeof(char *) * ci->capacity); ci->uris = uris; ci->capacity = capacity; } return JK_TRUE; } /* * Locate a context base in context list */ jk_context_item_t *context_find_base(jk_context_t *c, char *cbase) { int i; jk_context_item_t *ci; if (!c || !cbase) return NULL; for (i = 0; i < c->size; i++) { ci = c->contexts[i]; if (!ci) continue; if (!strcmp(ci->cbase, cbase)) return ci; } return NULL; } /* * Locate an URI in a context item */ char *context_item_find_uri(jk_context_item_t *ci, char *uri) { int i; if (!ci || !uri) return NULL; for (i = 0; i < ci->size; i++) { if (!strcmp(ci->uris[i], uri)) return ci->uris[i]; } return NULL; } void context_dump_uris(jk_context_t *c, char *cbase, FILE * f) { jk_context_item_t *ci; int i; ci = context_find_base(c, cbase); if (!ci) return; for (i = 0; i < ci->size; i++) fprintf(f, "/%s/%s\n", ci->cbase, ci->uris[i]); fflush(f); } /* * Add a new context item to context */ jk_context_item_t *context_add_base(jk_context_t *c, char *cbase) { jk_context_item_t *ci; if (!c || !cbase) return NULL; /* Check if the context base was not allready created */ ci = context_find_base(c, cbase); if (ci) return ci; if (context_realloc(c) != JK_TRUE) return NULL; ci = (jk_context_item_t *)jk_pool_alloc(&c->p, sizeof(jk_context_item_t)); if (!ci) return NULL; c->contexts[c->size] = ci; c->size++; ci->cbase = jk_pool_strdup(&c->p, cbase); ci->status = 0; ci->size = 0; ci->capacity = 0; ci->uris = NULL; return ci; } /* * Add a new URI to a context item */ int context_add_uri(jk_context_t *c, char *cbase, char *uri) { jk_context_item_t *ci; if (!uri) return JK_FALSE; /* Get/Create the context base */ ci = context_add_base(c, cbase); if (!ci) return JK_FALSE; if (context_item_find_uri(ci, uri) != NULL) return JK_TRUE; if (context_item_realloc(c, ci) == JK_FALSE) return JK_FALSE; ci->uris[ci->size] = jk_pool_strdup(&c->p, uri); if (ci->uris[ci->size] == NULL) return JK_FALSE; ci->size++; return JK_TRUE; } tomcat-connectors-1.2.41-src/native/common/jk_worker.c0000644000000000000020000002714412477544555021264 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Workers controller * * Author: Gal Shachor * * Author: Henri Gomez * * Version: $Revision: 1665454 $ * ***************************************************************************/ #define _PLACE_WORKER_LIST_HERE #include "jk_worker_list.h" #include "jk_worker.h" #include "jk_shm.h" #include "jk_util.h" #include "jk_mt.h" #define JK_WORKER_SHUTDOWN_WAIT 100 #define JK_WORKER_SHUTDOWN_COUNT 10 static void close_workers(jk_logger_t *l); static worker_factory get_factory_for(const char *type); static int build_worker_map(jk_map_t *init_data, char **worker_list, unsigned num_of_workers, jk_worker_env_t *we, jk_logger_t *l); /* Global worker list */ static jk_map_t *worker_map; static int running_maintain = 0; #if _MT_CODE static JK_CRIT_SEC worker_lock; #endif static int worker_maintain_time = 0; int wc_open(jk_map_t *init_data, jk_worker_env_t *we, jk_logger_t *l) { int rc; JK_TRACE_ENTER(l); if (!jk_map_alloc(&worker_map)) { JK_TRACE_EXIT(l); return JK_FALSE; } JK_INIT_CS(&worker_lock, rc); if (rc == JK_FALSE) { jk_log(l, JK_LOG_ERROR, "creating thread lock (errno=%d)", errno); JK_TRACE_EXIT(l); return JK_FALSE; } jk_map_dump(init_data, l); we->init_data = init_data; if (!jk_get_worker_list(init_data, &(we->worker_list), &we->num_of_workers)) { JK_TRACE_EXIT(l); we->num_of_workers = 0; we->worker_list = NULL; return JK_FALSE; } worker_maintain_time = jk_get_worker_maintain_time(init_data); if(worker_maintain_time < 0) worker_maintain_time = 0; if (!build_worker_map(init_data, we->worker_list, we->num_of_workers, we, l)) { close_workers(l); we->num_of_workers = 0; we->worker_list = NULL; JK_TRACE_EXIT(l); return JK_FALSE; } JK_TRACE_EXIT(l); return JK_TRUE; } void wc_close(jk_logger_t *l) { JK_TRACE_ENTER(l); JK_DELETE_CS(&worker_lock); close_workers(l); JK_TRACE_EXIT(l); } jk_worker_t *wc_get_worker_for_name(const char *name, jk_logger_t *l) { jk_worker_t *rc; JK_TRACE_ENTER(l); if (!name) { JK_LOG_NULL_PARAMS(l); JK_TRACE_EXIT(l); return NULL; } rc = jk_map_get(worker_map, name, NULL); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "%s a worker %s", rc ? "found" : "did not find", name); JK_TRACE_EXIT(l); return rc; } int wc_create_worker(const char *name, int use_map, jk_map_t *init_data, jk_worker_t **rc, jk_worker_env_t *we, jk_logger_t *l) { JK_TRACE_ENTER(l); if (jk_check_attribute_length("name", name, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } if (rc) { const char *type = jk_get_worker_type(init_data, name); worker_factory fac = get_factory_for(type); jk_worker_t *w = NULL; unsigned int i, num_of_maps; char **map_names; int wtype; *rc = NULL; if (!fac) { jk_log(l, JK_LOG_ERROR, "Unknown worker type %s for worker %s", type, name); JK_TRACE_EXIT(l); return JK_FALSE; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "about to create instance %s of %s", name, type); if (((wtype = fac(&w, name, l)) == 0) || !w) { jk_log(l, JK_LOG_ERROR, "factory for %s failed for %s", type, name); JK_TRACE_EXIT(l); return JK_FALSE; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "about to validate and init %s", name); if (!w->validate(w, init_data, we, l)) { w->destroy(&w, l); jk_log(l, JK_LOG_ERROR, "validate failed for %s", name); JK_TRACE_EXIT(l); return JK_FALSE; } if (!w->init(w, init_data, we, l)) { w->destroy(&w, l); jk_log(l, JK_LOG_ERROR, "init failed for %s", name); JK_TRACE_EXIT(l); return JK_FALSE; } if (use_map && jk_get_worker_mount_list(init_data, name, &map_names, &num_of_maps) && num_of_maps) { for (i = 0; i < num_of_maps; i++) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "mounting %s to worker %s", map_names[i], name); if (uri_worker_map_add(we->uri_to_worker, map_names[i], name, SOURCE_TYPE_WORKERDEF, l) == JK_FALSE) { w->destroy(&w, l); jk_log(l, JK_LOG_ERROR, "mounting %s failed for %s", map_names[i], name); JK_TRACE_EXIT(l); return JK_FALSE; } } } w->type = wtype; *rc = w; JK_TRACE_EXIT(l); return JK_TRUE; } JK_LOG_NULL_PARAMS(l); return JK_FALSE; } static void close_workers(jk_logger_t *l) { int sz = jk_map_size(worker_map); JK_TRACE_ENTER(l); if (sz > 0) { int i; for (i = 0; i < sz; i++) { jk_worker_t *w = jk_map_value_at(worker_map, i); if (w) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "close_workers will destroy worker %s", jk_map_name_at(worker_map, i)); w->destroy(&w, l); } } } jk_map_free(&worker_map); JK_TRACE_EXIT(l); } static int build_worker_map(jk_map_t *init_data, char **worker_list, unsigned num_of_workers, jk_worker_env_t *we, jk_logger_t *l) { unsigned i; JK_TRACE_ENTER(l); for (i = 0; i < num_of_workers; i++) { jk_worker_t *w = NULL; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "creating worker %s", worker_list[i]); if (wc_create_worker(worker_list[i], 1, init_data, &w, we, l)) { jk_worker_t *oldw = NULL; if (!jk_map_put(worker_map, worker_list[i], w, (void *)&oldw)) { jk_log(l, JK_LOG_ERROR, "failed to add worker %s to worker map", worker_list[i]); w->destroy(&w, l); JK_TRACE_EXIT(l); return JK_FALSE; } if (oldw) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "removing old %s worker", worker_list[i]); oldw->destroy(&oldw, l); } } else { jk_log(l, JK_LOG_ERROR, "failed to create worker %s", worker_list[i]); JK_TRACE_EXIT(l); return JK_FALSE; } } JK_TRACE_EXIT(l); return JK_TRUE; } static worker_factory get_factory_for(const char *type) { worker_factory_record_t *factory = &worker_factories[0]; while (factory->name) { if (0 == strcmp(factory->name, type)) { return factory->fac; } factory++; } return NULL; } const char *wc_get_name_for_type(int type, jk_logger_t *l) { worker_factory_record_t *factory = &worker_factories[0]; while (factory->name) { if (type == factory->type) { jk_log(l, JK_LOG_DEBUG, "Found worker type '%s'", factory->name); return factory->name; } factory++; } return NULL; } void wc_maintain(jk_logger_t *l) { static time_t last_maintain = 0; int needs_global_maintenance; int sz = jk_map_size(worker_map); JK_TRACE_ENTER(l); /* Only proceed if all of the below hold true: * - there are workers * - maintenance wasn't disabled by configuration * - time since last maintenance is big enough */ if (sz > 0 && worker_maintain_time > 0 && difftime(time(NULL), last_maintain) >= worker_maintain_time && !running_maintain) { int i; JK_ENTER_CS(&worker_lock); if (running_maintain || difftime(time(NULL), last_maintain) < worker_maintain_time) { /* Already in maintain */ JK_LEAVE_CS(&worker_lock); JK_TRACE_EXIT(l); return; } /* Set the maintain run flag so other threads skip * the maintain until we are finished. */ running_maintain = 1; last_maintain = time(NULL); JK_LEAVE_CS(&worker_lock); needs_global_maintenance = jk_shm_check_maintain(last_maintain - worker_maintain_time); for (i = 0; i < sz; i++) { jk_worker_t *w = jk_map_value_at(worker_map, i); if (w && w->maintain) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Maintaining worker %s", jk_map_name_at(worker_map, i)); w->maintain(w, time(NULL), needs_global_maintenance, l); } } JK_ENTER_CS(&worker_lock); running_maintain = 0; JK_LEAVE_CS(&worker_lock); } JK_TRACE_EXIT(l); } void wc_shutdown(jk_logger_t *l) { int sz = jk_map_size(worker_map); JK_TRACE_ENTER(l); if (sz > 0) { int i; i = JK_WORKER_SHUTDOWN_COUNT; while (running_maintain && i > 0) { jk_sleep(JK_WORKER_SHUTDOWN_WAIT); i--; } if (running_maintain) jk_log(l, JK_LOG_WARNING, "Worker maintain still running while shutting down worker %s", jk_map_name_at(worker_map, i)); running_maintain = 1; for (i = 0; i < sz; i++) { jk_worker_t *w = jk_map_value_at(worker_map, i); if (w && w->shutdown) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Shutting down worker %s", jk_map_name_at(worker_map, i)); w->shutdown(w, l); } } } JK_TRACE_EXIT(l); } tomcat-connectors-1.2.41-src/native/common/.indent.pro0000644000000000000020000000050110131441424021140 0ustar rootbin-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1 -nut -ncs -Tjk_env_t -Tjk_worker_t -Tjk_worker_env_t -Tjk_endpoint_t -Tjk_channel_t -Tjk_sockbuf_t -Tjk_msg_t -Tjk_msg_buf_t -Tjk_map_t -Tjk_uri_worker_map_t -Tjk_pool_t -Tjk_pool_atom_t -Tjk_logger_t -Tjk_ws_service_t -Tjk_context_item_t -Tjk_context_t -Tjk_login_service_t tomcat-connectors-1.2.41-src/native/common/jk_lb_worker.c0000644000000000000020000022562312477544555021743 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Load balancer worker, knows how to load balance among * * several workers. * * Author: Gal Shachor * * Author: Mladen Turk * * Author: Rainer Jung * * Based on: * * Version: $Revision: 1665454 $ * ***************************************************************************/ #include "jk_pool.h" #include "jk_service.h" #include "jk_util.h" #include "jk_worker.h" #include "jk_lb_worker.h" #include "jk_ajp13_worker.h" #include "jk_ajp14_worker.h" #include "jk_mt.h" #include "jk_shm.h" /* * The load balancing code in this */ /* * The following two macros need to be kept in sync with * the existing values for state and activation. * Note: state <= JK_LB_STATE_FORCE is equivalent to * state is none of JK_LB_STATE_BUSY, JK_LB_STATE_ERROR, JK_LB_STATE_PROBE * Note: state <= JK_LB_STATE_BUSY is equivalent to * state is none of JK_LB_STATE_ERROR, JK_LB_STATE_PROBE * Note: activation == JK_LB_ACTIVATION_ACTIVE is equivalent to * activation is none of JK_LB_ACTIVATION_STOPPED, JK_LB_ACTIVATION_DISABLED */ #define JK_WORKER_USABLE(s, activation) ((s) <= JK_LB_STATE_FORCE && activation == JK_LB_ACTIVATION_ACTIVE) #define JK_WORKER_USABLE_STICKY(s, activation) ((s) <= JK_LB_STATE_FORCE && activation != JK_LB_ACTIVATION_STOPPED) static const char *lb_locking_type[] = { JK_LB_LOCK_TEXT_OPTIMISTIC, JK_LB_LOCK_TEXT_PESSIMISTIC, "unknown", NULL }; static const char *lb_method_type[] = { JK_LB_METHOD_TEXT_REQUESTS, JK_LB_METHOD_TEXT_TRAFFIC, JK_LB_METHOD_TEXT_BUSYNESS, JK_LB_METHOD_TEXT_SESSIONS, JK_LB_METHOD_TEXT_NEXT, "unknown", NULL }; static const char *lb_state_type[] = { JK_LB_STATE_TEXT_IDLE, JK_LB_STATE_TEXT_OK, JK_LB_STATE_TEXT_RECOVER, JK_LB_STATE_TEXT_FORCE, JK_LB_STATE_TEXT_BUSY, JK_LB_STATE_TEXT_ERROR, JK_LB_STATE_TEXT_PROBE, "unknown", NULL }; static const char *lb_activation_type[] = { JK_LB_ACTIVATION_TEXT_ACTIVE, JK_LB_ACTIVATION_TEXT_DISABLED, JK_LB_ACTIVATION_TEXT_STOPPED, "unknown", NULL }; static const char *lb_first_log_names[] = { JK_NOTE_LB_FIRST_NAME, JK_NOTE_LB_FIRST_VALUE, JK_NOTE_LB_FIRST_ACCESSED, JK_NOTE_LB_FIRST_SESSIONS, JK_NOTE_LB_FIRST_READ, JK_NOTE_LB_FIRST_TRANSFERRED, JK_NOTE_LB_FIRST_ERRORS, JK_NOTE_LB_FIRST_BUSY, JK_NOTE_LB_FIRST_ACTIVATION, JK_NOTE_LB_FIRST_STATE, NULL }; static const char *lb_last_log_names[] = { JK_NOTE_LB_LAST_NAME, JK_NOTE_LB_LAST_VALUE, JK_NOTE_LB_LAST_ACCESSED, JK_NOTE_LB_LAST_SESSIONS, JK_NOTE_LB_LAST_READ, JK_NOTE_LB_LAST_TRANSFERRED, JK_NOTE_LB_LAST_ERRORS, JK_NOTE_LB_LAST_BUSY, JK_NOTE_LB_LAST_ACTIVATION, JK_NOTE_LB_LAST_STATE, NULL }; struct lb_endpoint { lb_worker_t *worker; jk_endpoint_t endpoint; int *states; }; typedef struct lb_endpoint lb_endpoint_t; /* Calculate the greatest common divisor of two positive integers */ static jk_uint64_t gcd(jk_uint64_t a, jk_uint64_t b) { jk_uint64_t r; if (b > a) { r = a; a = b; b = r; } while (b > 0) { r = a % b; a = b; b = r; } return a; } /* Calculate the smallest common multiple of two positive integers */ static jk_uint64_t scm(jk_uint64_t a, jk_uint64_t b) { return a * b / gcd(a, b); } /* Return the string representation of the lb lock type */ /* based on the integer representation */ const char *jk_lb_get_lock_direct(int lblock, jk_logger_t *l) { return lb_locking_type[lblock]; } /* Return the string representation of the lb lock type */ /* based on the lb worker struct */ const char *jk_lb_get_lock(lb_worker_t *p, jk_logger_t *l) { return lb_locking_type[p->lblock]; } /* Return the int representation of the lb lock type */ int jk_lb_get_lock_code(const char *v) { if (!v) return JK_LB_LOCK_DEF; if (*v == 'o' || *v == 'O' || *v == '0') return JK_LB_LOCK_OPTIMISTIC; if (*v == 'p' || *v == 'P' || *v == '1') return JK_LB_LOCK_PESSIMISTIC; return JK_LB_LOCK_DEF; } /* Return the string representation of the lb method type */ /* based on the integer representation */ const char *jk_lb_get_method_direct(int lbmethod, jk_logger_t *l) { return lb_method_type[lbmethod]; } /* Return the string representation of the lb method type */ /* based on the lb worker struct */ const char *jk_lb_get_method(lb_worker_t *p, jk_logger_t *l) { return lb_method_type[p->lbmethod]; } /* Return the int representation of the lb method type */ int jk_lb_get_method_code(const char *v) { if (!v) return JK_LB_METHOD_DEF; if (*v == 'r' || *v == 'R' || *v == '0') return JK_LB_METHOD_REQUESTS; if (*v == 't' || *v == 'T' || *v == '1') return JK_LB_METHOD_TRAFFIC; if (*v == 'b' || *v == 'B' || *v == '2') return JK_LB_METHOD_BUSYNESS; if (*v == 's' || *v == 'S' || *v == '3') return JK_LB_METHOD_SESSIONS; if (*v == 'n' || *v == 'N' || *v == '4') return JK_LB_METHOD_NEXT; return JK_LB_METHOD_DEF; } /* Return the string representation of the balance worker state */ /* based on the integer representation */ const char *jk_lb_get_state_direct(int state, jk_logger_t *l) { return lb_state_type[state]; } /* Return the string representation of the balance worker state */ /* based on the sub worker struct */ const char *jk_lb_get_state(lb_sub_worker_t *p, jk_logger_t *l) { return lb_state_type[p->s->state]; } /* Return the int representation of the lb state */ int jk_lb_get_state_code(const char *v) { if (!v) return JK_LB_STATE_DEF; if (*v == 'i' || *v == 'I' || *v == 'n' || *v == 'N' || *v == '0') return JK_LB_STATE_IDLE; if (*v == 'o' || *v == 'O' || *v == '1') return JK_LB_STATE_OK; if (*v == 'r' || *v == 'R' || *v == '2') return JK_LB_STATE_RECOVER; if (*v == 'f' || *v == 'F' || *v == '3') return JK_LB_STATE_FORCE; if (*v == 'b' || *v == 'B' || *v == '4') return JK_LB_STATE_BUSY; if (*v == 'e' || *v == 'E' || *v == '5') return JK_LB_STATE_ERROR; if (*v == 'p' || *v == 'P' || *v == '6') return JK_LB_STATE_PROBE; return JK_LB_STATE_DEF; } /* Return the string representation of the balance worker activation */ /* based on the integer representation */ const char *jk_lb_get_activation_direct(int activation, jk_logger_t *l) { return lb_activation_type[activation]; } /* Return the string representation of the balance worker activation */ /* based on the sub worker struct */ const char *jk_lb_get_activation(lb_sub_worker_t *p, jk_logger_t *l) { return lb_activation_type[p->activation]; } int jk_lb_get_activation_code(const char *v) { if (!v) return JK_LB_ACTIVATION_DEF; if (*v == 'a' || *v == 'A' || *v == '0') return JK_LB_ACTIVATION_ACTIVE; if (*v == 'd' || *v == 'D' || *v == '1') return JK_LB_ACTIVATION_DISABLED; if (*v == 's' || *v == 'S' || *v == '2') return JK_LB_ACTIVATION_STOPPED; return JK_LB_ACTIVATION_DEF; } /* Update the load multipliers wrt. lb_factor */ void update_mult(lb_worker_t *p, jk_logger_t *l) { unsigned int i = 0; jk_uint64_t s = 1; JK_TRACE_ENTER(l); for (i = 0; i < p->num_of_workers; i++) { s = scm(s, p->lb_workers[i].lb_factor); } for (i = 0; i < p->num_of_workers; i++) { p->lb_workers[i].lb_mult = s / p->lb_workers[i].lb_factor; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "worker %s gets multiplicity %" JK_UINT64_T_FMT, p->lb_workers[i].name, p->lb_workers[i].lb_mult); } JK_TRACE_EXIT(l); } /* Reset all lb values. */ void reset_lb_values(lb_worker_t *p, jk_logger_t *l) { unsigned int i = 0; JK_TRACE_ENTER(l); if (p->lbmethod != JK_LB_METHOD_BUSYNESS) { for (i = 0; i < p->num_of_workers; i++) { p->lb_workers[i].s->lb_value = 0; } } JK_TRACE_EXIT(l); } static void jk_lb_pull_worker(lb_worker_t *p, int i, jk_logger_t *l) { lb_sub_worker_t *w = &p->lb_workers[i]; if (w->sequence < w->s->h.sequence) { jk_worker_t *jw = w->worker; ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "syncing mem for member '%s' of lb '%s' from shm", w->name, p->name); jk_ajp_pull(aw, JK_TRUE, l); strncpy(w->route, w->s->route, JK_SHM_STR_SIZ); strncpy(w->domain, w->s->domain, JK_SHM_STR_SIZ); strncpy(w->redirect, w->s->redirect, JK_SHM_STR_SIZ); w->distance = w->s->distance; w->activation = w->s->activation; w->lb_factor = w->s->lb_factor; w->lb_mult = w->s->lb_mult; w->sequence = w->s->h.sequence; } } /* Syncing config values from shm */ void jk_lb_pull(lb_worker_t *p, int locked, jk_logger_t *l) { unsigned int i = 0; JK_TRACE_ENTER(l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "syncing mem for lb '%s' from shm (%u->%u)", p->name, p->sequence, p->s->h.sequence); if (locked == JK_FALSE) jk_shm_lock(); if (p->sequence == p->s->h.sequence) { if (locked == JK_FALSE) jk_shm_unlock(); return; } p->sticky_session = p->s->sticky_session; p->sticky_session_force = p->s->sticky_session_force; p->recover_wait_time = p->s->recover_wait_time; p->error_escalation_time = p->s->error_escalation_time; p->max_reply_timeouts = p->s->max_reply_timeouts; p->retries = p->s->retries; p->retry_interval = p->s->retry_interval; p->lbmethod = p->s->lbmethod; p->lblock = p->s->lblock; p->max_packet_size = p->s->max_packet_size; for (i = 0; i < p->num_of_workers; i++) { jk_lb_pull_worker(p, i, l); } p->sequence = p->s->h.sequence; if (locked == JK_FALSE) jk_shm_unlock(); JK_TRACE_EXIT(l); } /* Syncing config values to shm */ void jk_lb_push(lb_worker_t *p, int locked, jk_logger_t *l) { unsigned int i = 0; JK_TRACE_ENTER(l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "syncing shm for lb '%s' from mem (%u->%u)", p->name, p->s->h.sequence, p->sequence); if (locked == JK_FALSE) jk_shm_lock(); p->s->sticky_session = p->sticky_session; p->s->sticky_session_force = p->sticky_session_force; p->s->recover_wait_time = p->recover_wait_time; p->s->error_escalation_time = p->error_escalation_time; p->s->max_reply_timeouts = p->max_reply_timeouts; p->s->retries = p->retries; p->s->retry_interval = p->retry_interval; p->s->lbmethod = p->lbmethod; p->s->lblock = p->lblock; p->s->max_packet_size = p->max_packet_size; for (i = 0; i < p->num_of_workers; i++) { lb_sub_worker_t *w = &p->lb_workers[i]; if (w->sequence != w->s->h.sequence) { jk_worker_t *jw = w->worker; ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "syncing shm for member '%s' of lb '%s' from mem", w->name, p->name); jk_ajp_push(aw, JK_TRUE, l); strncpy(w->s->route, w->route, JK_SHM_STR_SIZ); strncpy(w->s->domain, w->domain, JK_SHM_STR_SIZ); strncpy(w->s->redirect, w->redirect, JK_SHM_STR_SIZ); w->s->distance = w->distance; w->s->activation = w->activation; w->s->lb_factor = w->lb_factor; w->s->lb_mult = w->lb_mult; w->s->h.sequence++; w->sequence = w->s->h.sequence; } } /* Increment the shared memory sequence number. * Our number can be behind the actual value in * shared memory. */ p->s->h.sequence++; p->sequence = p->s->h.sequence; if (locked == JK_FALSE) jk_shm_unlock(); JK_TRACE_EXIT(l); } /* Retrieve the parameter with the given name */ static char *get_path_param(jk_ws_service_t *s, const char *name) { char *id_start = NULL; for (id_start = strstr(s->req_uri, name); id_start; id_start = strstr(id_start + 1, name)) { if (id_start[strlen(name)] == '=') { /* * Session path-cookie was found, get it's value */ id_start += (1 + strlen(name)); if (strlen(id_start)) { char *id_end; id_start = jk_pool_strdup(s->pool, id_start); /* * The query string is not part of req_uri, however * to be on the safe side lets remove the trailing query * string if appended... */ if ((id_end = strchr(id_start, '?')) != NULL) { *id_end = '\0'; } /* * Remove any trailing path element. */ if ((id_end = strchr(id_start, ';')) != NULL) { *id_end = '\0'; } return id_start; } } } return NULL; } /* Retrieve the cookie with the given name */ static char *get_cookie(jk_ws_service_t *s, const char *name) { unsigned i; char *result = NULL; for (i = 0; i < s->num_headers; i++) { if (strcasecmp(s->headers_names[i], "cookie") == 0) { char *id_start; for (id_start = strstr(s->headers_values[i], name); id_start; id_start = strstr(id_start + 1, name)) { if (id_start == s->headers_values[i] || id_start[-1] == ';' || id_start[-1] == ',' || jk_isspace(id_start[-1])) { id_start += strlen(name); while (*id_start && jk_isspace(*id_start)) ++id_start; if (*id_start == '=' && id_start[1]) { /* * Session cookie was found, get it's value */ char *id_end; size_t sz; ++id_start; if ((id_end = strpbrk(id_start, ";,")) != NULL) sz = id_end - id_start; else { sz = strlen(id_start); id_end = id_start + sz; } /* Chop off surrounding '"' (quoted cookie) */ if (sz > 1 && *id_start == '"' && *(id_start + sz - 1) == '"') { id_start++; sz -= 2; } if (result == NULL) { result = jk_pool_alloc(s->pool, sz + 1); memcpy(result, id_start, sz); result[sz] = '\0'; } else { size_t osz = strlen(result) + 1; result = jk_pool_realloc(s->pool, osz + sz + 1, result, osz); strcat(result, ";"); strncat(result, id_start, sz); } id_start = id_end; } } } } } return result; } /* Retrieve session id from the cookie or the parameter * (parameter first) */ static char *get_sessionid(jk_ws_service_t *s, lb_worker_t *p, jk_logger_t *l) { char *val; char *session_path; char *session_cookie; /* If the web server sets a route, ignore the real session id * and fake a new one for that route. */ if (s->route) { size_t sz = strlen(s->route) + 1; val = jk_pool_alloc(s->pool, sz + 1); val[0] = '.'; memcpy(val + 1, s->route, sz); return val; } /* set session_path */ session_path = (s->extension.session_path) ? s->extension.session_path : p->session_path; /* set session_cookie */ session_cookie = (s->extension.session_cookie) ? s->extension.session_cookie : p->session_cookie; val = get_path_param(s, session_path); if (!val) { val = get_cookie(s, session_cookie); } if (val && !*val) { /* TODO: For now only log the empty sessions. * However we should probably return 400 * (BAD_REQUEST) in this case */ jk_log(l, JK_LOG_INFO, "Detected empty session identifier."); return NULL; } return val; } static void close_workers(lb_worker_t *p, int num_of_workers, jk_logger_t *l) { int i = 0; for (i = 0; i < num_of_workers; i++) { p->lb_workers[i].worker->destroy(&(p->lb_workers[i].worker), l); } } /* If the worker is in error state run * retry on that worker. It will be marked as * operational if the retry timeout is elapsed. * The worker might still be unusable, but we try * anyway. * If the worker is in ok state and got no requests * since the last global maintenance, we mark its * state as not available. * Return the number of workers not in error state. */ static int recover_workers(lb_worker_t *p, jk_uint64_t curmax, time_t now, jk_logger_t *l) { unsigned int i; int non_error = 0; int elapsed; lb_sub_worker_t *w = NULL; ajp_worker_t *aw = NULL; JK_TRACE_ENTER(l); if (p->sequence < p->s->h.sequence) jk_lb_pull(p, JK_TRUE, l); for (i = 0; i < p->num_of_workers; i++) { w = &p->lb_workers[i]; aw = (ajp_worker_t *)w->worker->worker_private; if (w->s->state == JK_LB_STATE_ERROR) { elapsed = (int)difftime(now, w->s->last_error_time); if (elapsed <= p->recover_wait_time) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "worker %s will recover in %d seconds", w->name, p->recover_wait_time - elapsed); } else { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "worker %s is marked for recovery", w->name); if (p->lbmethod != JK_LB_METHOD_BUSYNESS) w->s->lb_value = curmax; aw->s->reply_timeouts = 0; w->s->state = JK_LB_STATE_RECOVER; non_error++; } } else if (w->s->first_error_time > 0 && (int)difftime(now, w->s->first_error_time) >= p->error_escalation_time && w->s->state != JK_LB_STATE_RECOVER) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "worker %s escalating local error to global error", w->name); w->s->state = JK_LB_STATE_ERROR; } else { non_error++; if (w->s->state == JK_LB_STATE_OK && aw->s->used == w->s->elected_snapshot) w->s->state = JK_LB_STATE_IDLE; } w->s->elected_snapshot = aw->s->used; } JK_TRACE_EXIT(l); return non_error; } static int force_recovery(lb_worker_t *p, int *states, jk_logger_t *l) { unsigned int i; int forced = 0; lb_sub_worker_t *w = NULL; ajp_worker_t *aw = NULL; JK_TRACE_ENTER(l); for (i = 0; i < p->num_of_workers; i++) { w = &p->lb_workers[i]; if (w->s->state == JK_LB_STATE_ERROR) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_INFO, "worker %s is marked for forced recovery", w->name); aw = (ajp_worker_t *)w->worker->worker_private; aw->s->reply_timeouts = 0; w->s->state = JK_LB_STATE_FORCE; if (states != NULL) states[i] = JK_LB_STATE_FORCE; forced++; } } JK_TRACE_EXIT(l); return forced; } /* Divide old load values by the decay factor, * such that older values get less important * for the routing decisions. */ static jk_uint64_t decay_load(lb_worker_t *p, time_t exponent, jk_logger_t *l) { unsigned int i; jk_uint64_t curmax = 0; jk_uint64_t curmin = 0; int no_curmin = JK_TRUE; lb_sub_worker_t *w; ajp_worker_t *aw; JK_TRACE_ENTER(l); for (i = 0; i < p->num_of_workers; i++) { w = &p->lb_workers[i]; if (p->lbmethod != JK_LB_METHOD_BUSYNESS) { if (p->lbmethod != JK_LB_METHOD_NEXT) { w->s->lb_value >>= exponent; } if (w->s->lb_value > curmax) { curmax = w->s->lb_value; } } aw = (ajp_worker_t *)w->worker->worker_private; aw->s->reply_timeouts >>= exponent; } if (p->lbmethod == JK_LB_METHOD_NEXT) { for (i = 0; i < p->num_of_workers; i++) { w = &p->lb_workers[i]; /* Take into account only the workers that are * not in error state, stopped, disabled or busy. * Unfortunately we can not respect activations * defined by mapping rules here. */ if (JK_WORKER_USABLE(w->s->state, w->activation)) { if (w->s->lb_value < curmin || no_curmin == JK_TRUE) { no_curmin = JK_FALSE; curmin = w->s->lb_value; } } } for (i = 0; i < p->num_of_workers; i++) { w = &p->lb_workers[i]; if (w->s->lb_value >= curmin) w->s->lb_value -= curmin; else w->s->lb_value = 0; } } JK_TRACE_EXIT(l); return curmax; } static int JK_METHOD maintain_workers(jk_worker_t *p, time_t now, int global, jk_logger_t *l) { unsigned int i = 0; jk_uint64_t curmax = 0; JK_TRACE_ENTER(l); if (p && p->worker_private) { lb_worker_t *lb = (lb_worker_t *)p->worker_private; /* Now we check for global maintenance (once for all processes). * Checking workers for recovery and applying decay to the * load values should not be done by each process individually. * Therefore we globally sync and we use a global timestamp. * Since it's possible that we come here a few milliseconds * before the interval has passed, we allow a little tolerance. */ if (global == JK_TRUE) { time_t exponent = JK_LB_DECAY_MULT * difftime(now, lb->s->last_maintain_time) / lb->maintain_time; lb->s->last_maintain_time = now; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "decay with 2^%d", exponent); jk_shm_lock(); curmax = decay_load(lb, exponent, l); if (!recover_workers(lb, curmax, now, l)) { force_recovery(lb, NULL, l); } /* * Checking workers for idleness. */ for (i = 0; i < lb->num_of_workers; i++) { ajp_worker_t *aw = lb->lb_workers[i].worker->worker_private; if (aw->s->state == JK_AJP_STATE_OK && aw->s->used == aw->s->used_snapshot) aw->s->state = JK_AJP_STATE_IDLE; aw->s->used_snapshot = aw->s->used; } jk_shm_unlock(); } for (i = 0; i < lb->num_of_workers; i++) { if (lb->lb_workers[i].worker->maintain) { lb->lb_workers[i].worker->maintain(lb->lb_workers[i].worker, now, global, l); } } } else { JK_LOG_NULL_PARAMS(l); } JK_TRACE_EXIT(l); return JK_TRUE; } static int JK_METHOD shutdown_workers(jk_worker_t *p, jk_logger_t *l) { unsigned int i = 0; JK_TRACE_ENTER(l); if (p && p->worker_private) { lb_worker_t *lb = (lb_worker_t *)p->worker_private; for (i = 0; i < lb->num_of_workers; i++) { if (lb->lb_workers[i].worker->shutdown) { lb->lb_workers[i].worker->shutdown(lb->lb_workers[i].worker, l); } } } else { JK_LOG_NULL_PARAMS(l); } JK_TRACE_EXIT(l); return JK_TRUE; } static int find_by_session(jk_ws_service_t *s, lb_worker_t *p, const char *session_route, jk_logger_t *l) { int rc = -1; unsigned int i; for (i = 0; i < p->num_of_workers; i++) { if (strcmp(p->lb_workers[i].route, session_route) == 0) { rc = i; break; } } return rc; } static int find_best_bydomain(jk_ws_service_t *s, lb_worker_t *p, const char *route_or_domain, int *states, jk_logger_t *l) { unsigned int i; int d = 0; jk_uint64_t curmin = 0; int candidate = -1; int activation; lb_sub_worker_t wr; char *idpart = strchr(route_or_domain, '.'); size_t domain_len = 0; if (idpart) { domain_len = idpart - route_or_domain; } else { domain_len = strlen(route_or_domain); } /* First try to see if we have available candidate */ for (i = 0; i < p->num_of_workers; i++) { /* Skip all workers that are not member of domain */ wr = p->lb_workers[i]; if (strlen(wr.domain) == 0 || strlen(wr.domain) != domain_len || strncmp(wr.domain, route_or_domain, domain_len)) continue; /* Take into account only the workers that are * not in error state, stopped, disabled or busy. */ activation = s->extension.activation ? s->extension.activation[i] : JK_LB_ACTIVATION_UNSET; if (activation == JK_LB_ACTIVATION_UNSET) activation = wr.activation; if (JK_WORKER_USABLE(states[wr.i], activation)) { if (candidate < 0 || wr.distance < d || (wr.s->lb_value < curmin && wr.distance == d)) { candidate = i; curmin = wr.s->lb_value; d = wr.distance; } } } return candidate; } static int find_best_byvalue(jk_ws_service_t *s, lb_worker_t *p, int *states, jk_logger_t *l) { unsigned int i; unsigned int j; unsigned int offset; int d = 0; jk_uint64_t curmin = 0; /* find the least busy worker */ int candidate = -1; int activation; lb_sub_worker_t wr; offset = p->next_offset; /* First try to see if we have available candidate */ for (j = offset; j < p->num_of_workers + offset; j++) { i = j % p->num_of_workers; wr = p->lb_workers[i]; activation = s->extension.activation ? s->extension.activation[i] : JK_LB_ACTIVATION_UNSET; if (activation == JK_LB_ACTIVATION_UNSET) activation = wr.activation; /* Take into account only the workers that are * not in error state, stopped, disabled or busy. */ if (JK_WORKER_USABLE(states[wr.i], activation)) { if (candidate < 0 || wr.distance < d || (s->extension.stateless != JK_TRUE && wr.s->lb_value < curmin && wr.distance == d)) { candidate = i; curmin = wr.s->lb_value; d = wr.distance; p->next_offset = i + 1; } } } return candidate; } static int find_bysession_route(jk_ws_service_t *s, lb_worker_t *p, const char *session_route, int *states, jk_logger_t *l) { int uses_domain = 0; int candidate = -1; candidate = find_by_session(s, p, session_route, l); if (candidate < 0) { uses_domain = 1; candidate = find_best_bydomain(s, p, session_route, states, l); } else { s->sticky = JK_TRUE; } if (candidate >= 0) { lb_sub_worker_t wr = p->lb_workers[candidate]; int activation; if (uses_domain) s->route = wr.domain; activation = s->extension.activation ? s->extension.activation[candidate] : JK_LB_ACTIVATION_UNSET; if (activation == JK_LB_ACTIVATION_UNSET) activation = wr.activation; if (!JK_WORKER_USABLE_STICKY(states[wr.i], activation)) { /* We have a worker that is error state or stopped. * If it has a redirection set use that redirection worker. * This enables to safely remove the member from the * balancer. Of course you will need a some kind of * session replication between those two remote. */ if (p->sticky_session_force) candidate = -1; else if (*wr.redirect) { candidate = find_by_session(s, p, wr.redirect, l); s->route = NULL; } else if (*wr.domain && !uses_domain) { candidate = find_best_bydomain(s, p, wr.domain, states, l); if (candidate >= 0) { s->route = wr.domain; } else { s->route = NULL; } } if (candidate >= 0) { wr = p->lb_workers[candidate]; activation = s->extension.activation ? s->extension.activation[candidate] : JK_LB_ACTIVATION_UNSET; if (activation == JK_LB_ACTIVATION_UNSET) activation = wr.activation; if (!JK_WORKER_USABLE_STICKY(states[wr.i], activation)) candidate = -1; } } } return candidate; } static int find_failover_worker(jk_ws_service_t *s, lb_worker_t *p, int *states, jk_logger_t *l) { int rc = -1; unsigned int i; char *redirect = NULL; for (i = 0; i < p->num_of_workers; i++) { if (strlen(p->lb_workers[i].redirect)) { redirect = p->lb_workers[i].redirect; break; } } if (redirect) { rc = find_bysession_route(s, p, redirect, states, l); s->sticky = JK_FALSE; } return rc; } static int find_best_worker(jk_ws_service_t *s, lb_worker_t *p, int *states, jk_logger_t *l) { int rc = -1; rc = find_best_byvalue(s, p, states, l); /* By default use worker route as session route */ if (rc < 0) rc = find_failover_worker(s, p, states, l); return rc; } static int get_most_suitable_worker(jk_ws_service_t *s, lb_worker_t *p, char *sessionid, int *states, jk_logger_t *l) { int rc = -1; JK_TRACE_ENTER(l); s->sticky = JK_FALSE; if (p->num_of_workers == 1) { /* No need to find the best worker * if there is a single one */ int activation = s->extension.activation ? s->extension.activation[0] : JK_LB_ACTIVATION_UNSET; if (activation == JK_LB_ACTIVATION_UNSET) activation = p->lb_workers[0].activation; if (JK_WORKER_USABLE_STICKY(states[0], activation)) { if (activation != JK_LB_ACTIVATION_DISABLED) { s->sticky = JK_TRUE; JK_TRACE_EXIT(l); return 0; } } else { JK_TRACE_EXIT(l); return -1; } } if (p->lblock == JK_LB_LOCK_PESSIMISTIC) { if (!jk_shm_lock()) { jk_log(l, JK_LOG_ERROR, "locking failed (errno=%d)", errno); JK_TRACE_EXIT(l); return -1; } } else { JK_ENTER_CS(&p->cs); } if (sessionid) { char *session = sessionid; while (sessionid) { char *next = strchr(sessionid, ';'); char *session_route = NULL; if (next) *next++ = '\0'; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "searching worker for partial sessionid %s", sessionid); session_route = strchr(sessionid, '.'); if (session_route) { ++session_route; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "searching worker for session route %s", session_route); /* We have a session route. Whow! */ rc = find_bysession_route(s, p, session_route, states, l); if (rc >= 0) { lb_sub_worker_t *wr = &(p->lb_workers[rc]); if (p->lblock == JK_LB_LOCK_PESSIMISTIC) { jk_shm_unlock(); } else { JK_LEAVE_CS(&p->cs); } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "found worker %s (%s) for route %s and partial sessionid %s", wr->name, wr->route, session_route, sessionid); JK_TRACE_EXIT(l); return rc; } } /* Try next partial sessionid if present */ sessionid = next; rc = -1; } if (rc < 0 && p->sticky_session_force) { if (p->lblock == JK_LB_LOCK_PESSIMISTIC) { jk_shm_unlock(); } else { JK_LEAVE_CS(&p->cs); } jk_log(l, JK_LOG_INFO, "all workers are in error state for session %s", session); JK_TRACE_EXIT(l); return -1; } } rc = find_best_worker(s, p, states, l); if (p->lblock == JK_LB_LOCK_PESSIMISTIC) { jk_shm_unlock(); } else { JK_LEAVE_CS(&p->cs); } if (rc >= 0) { lb_sub_worker_t *wr = &(p->lb_workers[rc]); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "found best worker %s (%s) using method '%s'", wr->name, wr->route, jk_lb_get_method(p, l)); JK_TRACE_EXIT(l); return rc; } JK_TRACE_EXIT(l); return -1; } static void lb_add_log_items(jk_ws_service_t *s, const char *const *log_names, lb_sub_worker_t *w, jk_logger_t *l) { /* ADJUST JK_LB_NOTES_COUNT WHEN ADDING MORE NOTES HERE! */ ajp_worker_t *aw = (ajp_worker_t *)w->worker->worker_private; const char **log_values = jk_pool_alloc(s->pool, sizeof(char *) * JK_LB_NOTES_COUNT); char *buf = jk_pool_alloc(s->pool, sizeof(char *) * JK_LB_NOTES_COUNT * JK_LB_UINT64_STR_SZ); if (log_values && buf) { /* JK_NOTE_LB_FIRST/LAST_NAME */ log_values[0] = w->name; snprintf(buf, JK_LB_UINT64_STR_SZ, "%" JK_UINT64_T_FMT, w->s->lb_value); /* JK_NOTE_LB_FIRST/LAST_VALUE */ log_values[1] = buf; buf += JK_LB_UINT64_STR_SZ; snprintf(buf, JK_LB_UINT64_STR_SZ, "%" JK_UINT64_T_FMT, aw->s->used); /* JK_NOTE_LB_FIRST/LAST_ACCESSED */ log_values[2] = buf; buf += JK_LB_UINT64_STR_SZ; snprintf(buf, JK_LB_UINT64_STR_SZ, "%" JK_UINT64_T_FMT, w->s->sessions); /* JK_NOTE_LB_FIRST/LAST_SESSIONS */ log_values[3] = buf; buf += JK_LB_UINT64_STR_SZ; snprintf(buf, JK_LB_UINT64_STR_SZ, "%" JK_UINT64_T_FMT, aw->s->readed); /* JK_NOTE_LB_FIRST/LAST_READ */ log_values[4] = buf; buf += JK_LB_UINT64_STR_SZ; snprintf(buf, JK_LB_UINT64_STR_SZ, "%" JK_UINT64_T_FMT, aw->s->transferred); /* JK_NOTE_LB_FIRST/LAST_TRANSFERRED */ log_values[5] = buf; buf += JK_LB_UINT64_STR_SZ; snprintf(buf, JK_LB_UINT64_STR_SZ, "%" JK_UINT32_T_FMT, w->s->errors); /* JK_NOTE_LB_FIRST/LAST_ERRORS */ log_values[6] = buf; buf += JK_LB_UINT64_STR_SZ; snprintf(buf, JK_LB_UINT64_STR_SZ, "%d", aw->s->busy); /* JK_NOTE_LB_FIRST/LAST_BUSY */ log_values[7] = buf; /* JK_NOTE_LB_FIRST/LAST_ACTIVATION */ log_values[8] = jk_lb_get_activation(w, l); /* JK_NOTE_LB_FIRST/LAST_STATE */ log_values[9] = jk_lb_get_state(w, l); s->add_log_items(s, log_names, log_values, JK_LB_NOTES_COUNT); } } static int JK_METHOD service(jk_endpoint_t *e, jk_ws_service_t *s, jk_logger_t *l, int *is_error) { lb_endpoint_t *p; int attempt = 0; lb_sub_worker_t *prec = NULL; int num_of_workers; int first = 1; int was_forced = 0; int recoverable = JK_TRUE; int rc = JK_UNSET; char *sessionid = NULL; int i; int retry = 0; JK_TRACE_ENTER(l); if (!e || !e->endpoint_private || !s || !is_error) { JK_LOG_NULL_PARAMS(l); if (is_error) *is_error = JK_HTTP_SERVER_ERROR; JK_TRACE_EXIT(l); return JK_FALSE; } p = e->endpoint_private; num_of_workers = p->worker->num_of_workers; /* Set returned error to OK */ *is_error = JK_HTTP_OK; if (p->worker->sequence < p->worker->s->h.sequence) jk_lb_pull(p->worker, JK_FALSE, l); for (i = 0; i < num_of_workers; i++) { lb_sub_worker_t *rec = &(p->worker->lb_workers[i]); ajp_worker_t *aw = (ajp_worker_t *)rec->worker->worker_private; if (rec->s->state == JK_LB_STATE_BUSY) { if ((aw->busy_limit <= 0 || aw->s->busy < aw->busy_limit) && ajp_has_endpoint(rec->worker, l)) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "worker %s busy state ended", rec->name); rec->s->state = JK_LB_STATE_OK; } } /* Copy the shared state info */ p->states[i] = rec->s->state; } /* set the recovery post, for LB mode */ s->reco_buf = jk_b_new(s->pool); if (!s->reco_buf) { *is_error = JK_HTTP_SERVER_ERROR; jk_log(l, JK_LOG_ERROR, "Failed allocating AJP message"); JK_TRACE_EXIT(l); return JK_SERVER_ERROR; } if (jk_b_set_buffer_size(s->reco_buf, p->worker->max_packet_size)) { *is_error = JK_HTTP_SERVER_ERROR; jk_log(l, JK_LOG_ERROR, "Failed allocating AJP message buffer of %d bytes.", p->worker->max_packet_size); JK_TRACE_EXIT(l); return JK_SERVER_ERROR; } jk_b_reset(s->reco_buf); s->reco_status = RECO_INITED; if (p->worker->sticky_session && s->extension.sticky_ignore != JK_TRUE) { /* Use sessionid only if sticky_session is * defined and not overwritten for this load balancer */ sessionid = get_sessionid(s, p->worker, l); } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "service sticky_session=%d id='%s'", p->worker->sticky_session, sessionid ? sessionid : "empty"); while (recoverable == JK_TRUE) { if (attempt >= num_of_workers) { retry++; if (retry >= p->worker->retries) { /* Done with retrying */ break; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "retry %d, sleeping for %d ms before retrying", retry, p->worker->retry_interval); jk_sleep(p->worker->retry_interval); /* Pull shared memory if something changed during sleep */ if (p->worker->sequence < p->worker->s->h.sequence) jk_lb_pull(p->worker, JK_FALSE, l); for (i = 0; i < num_of_workers; i++) { /* Copy the shared state info */ p->states[i] = p->worker->lb_workers[i].s->state; } attempt = 0; } rc = JK_FALSE; *is_error = JK_HTTP_SERVER_BUSY; i = get_most_suitable_worker(s, p->worker, sessionid, p->states, l); if (i >= 0) { int r; int is_service_error = JK_HTTP_OK; lb_sub_worker_t *rec = &(p->worker->lb_workers[i]); ajp_worker_t *aw = (ajp_worker_t *)rec->worker->worker_private; jk_endpoint_t *end = NULL; int activation = s->extension.activation ? s->extension.activation[i] : JK_LB_ACTIVATION_UNSET; if (activation == JK_LB_ACTIVATION_UNSET) activation = rec->activation; if (!s->route) s->route = rec->route; s->activation = jk_lb_get_activation_direct(activation, l); prec = rec; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "service worker=%s route=%s failover=%s", rec->name, s->route, s->sticky ? "false" : "true"); if (p->worker->lblock == JK_LB_LOCK_PESSIMISTIC) jk_shm_lock(); if (rec->s->state == JK_LB_STATE_RECOVER) { rec->s->state = JK_LB_STATE_PROBE; p->states[rec->i] = JK_LB_STATE_PROBE; } if (p->worker->lblock == JK_LB_LOCK_PESSIMISTIC) jk_shm_unlock(); r = rec->worker->get_endpoint(rec->worker, &end, l); if (!r || !end) { /* If we can not get the endpoint * mark the worker as busy rather then * as in error if the retry number is * greater then the number of retries. */ if (p->worker->lblock == JK_LB_LOCK_PESSIMISTIC) jk_shm_lock(); if (rec->s->state != JK_LB_STATE_ERROR) { rec->s->state = JK_LB_STATE_BUSY; p->states[rec->i] = JK_LB_STATE_BUSY; } if (p->worker->lblock == JK_LB_LOCK_PESSIMISTIC) jk_shm_unlock(); jk_log(l, JK_LOG_INFO, "could not get free endpoint for worker %s (%d retries)", rec->name, retry); } else { int service_stat = JK_UNSET; jk_uint64_t rd = 0; jk_uint64_t wr = 0; int busy; /* Reset endpoint read and write sizes for * this request. */ end->rd = end->wr = 0; end->recoverable = JK_TRUE; if (p->worker->lblock == JK_LB_LOCK_PESSIMISTIC) jk_shm_lock(); /* Increment the number of workers serving request */ busy = JK_ATOMIC_INCREMENT(&(p->worker->s->busy)); if (busy > p->worker->s->max_busy) p->worker->s->max_busy = busy; if (p->worker->lbmethod == JK_LB_METHOD_REQUESTS || p->worker->lbmethod == JK_LB_METHOD_BUSYNESS || (!sessionid && s->extension.stateless != JK_TRUE && (p->worker->lbmethod == JK_LB_METHOD_SESSIONS || p->worker->lbmethod == JK_LB_METHOD_NEXT))) rec->s->lb_value += rec->lb_mult; if (!sessionid && s->extension.stateless != JK_TRUE) { rec->s->sessions++; } if (p->worker->lblock == JK_LB_LOCK_PESSIMISTIC) jk_shm_unlock(); if (!s->sticky && (s->extension.set_session_cookie || p->worker->set_session_cookie)) { char **old_names = s->resp_headers_names; char **old_values = s->resp_headers_values; s->resp_headers_names = jk_pool_alloc(s->pool, (s->num_resp_headers + 1) * sizeof(char *)); s->resp_headers_values = jk_pool_alloc(s->pool, (s->num_resp_headers + 1) * sizeof(char *)); if (!s->resp_headers_names || !s->resp_headers_values) { jk_log(l, JK_LOG_ERROR, "Failed allocating %d new response headers.", s->num_resp_headers + 1); s->resp_headers_names = old_names; s->resp_headers_values = old_values; } else if (s->num_resp_headers) { memcpy(s->resp_headers_names, old_names, s->num_resp_headers * sizeof(char *)); memcpy(s->resp_headers_values, old_values, s->num_resp_headers * sizeof(char *)); } s->resp_headers_names[s->num_resp_headers] = "Set-Cookie"; s->resp_headers_values[s->num_resp_headers] = jk_pool_strcatv(s->pool, p->worker->session_cookie, "=.", rec->route, NULL); if (p->worker->session_cookie_path && *p->worker->session_cookie_path) { s->resp_headers_values[s->num_resp_headers] = jk_pool_strcatv(s->pool, s->resp_headers_values[s->num_resp_headers], ";PATH=", p->worker->session_cookie_path, NULL); } s->resp_headers_values[s->num_resp_headers] = jk_pool_strcatv(s->pool, s->resp_headers_values[s->num_resp_headers], ";HttpOnly", (s->is_ssl ? ";Secure" : ""), NULL); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Added cookie header '%s' with value '%s' ", s->resp_headers_names[s->num_resp_headers], s->resp_headers_values[s->num_resp_headers]); s->num_resp_headers++; } service_stat = end->service(end, s, l, &is_service_error); rd = end->rd; wr = end->wr; recoverable = end->recoverable; *is_error = is_service_error; end->done(&end, l); if (p->worker->lblock == JK_LB_LOCK_PESSIMISTIC) jk_shm_lock(); /* Update partial reads and writes if any */ if (p->worker->lbmethod == JK_LB_METHOD_TRAFFIC) { rec->s->lb_value += (rd+wr)*rec->lb_mult; } else if (p->worker->lbmethod == JK_LB_METHOD_BUSYNESS) { if (rec->s->lb_value >= rec->lb_mult) { rec->s->lb_value -= rec->lb_mult; } else { rec->s->lb_value = 0; if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "worker %s has load value to low (%" JK_UINT64_T_FMT " < %" JK_UINT64_T_FMT ") ", "- correcting to 0", rec->name, rec->s->lb_value, rec->lb_mult); } } } /* When have an endpoint and we ran a request, assume * we are OK, unless we last were in error. * We will below explicitely set OK or ERROR according * to the returned service_stat. */ if (rec->s->state != JK_LB_STATE_ERROR) { rec->s->state = JK_LB_STATE_OK; p->states[rec->i] = JK_LB_STATE_OK; } /* Decrement the busy worker count. * Check if the busy was reset to zero by graceful * restart of the server. */ JK_ATOMIC_DECREMENT(&(p->worker->s->busy)); if (service_stat == JK_TRUE) { /* * Successful request. */ rec->s->state = JK_LB_STATE_OK; p->states[rec->i] = JK_LB_STATE_OK; rec->s->first_error_time = 0; rec->s->last_error_time = 0; rc = JK_TRUE; recoverable = JK_UNSET; } else if (service_stat == JK_CLIENT_ERROR) { /* * Client error !!! * Since this is bad request do not fail over. */ rec->s->state = JK_LB_STATE_OK; p->states[rec->i] = JK_LB_STATE_ERROR; rec->s->first_error_time = 0; rec->s->last_error_time = 0; rc = JK_CLIENT_ERROR; recoverable = JK_FALSE; } else if (service_stat == JK_SERVER_ERROR) { /* * Internal JK server error. * Keep previous global state. * Do not try to reuse the same node for the same request. * Failing over to another node could help. */ p->states[rec->i] = JK_LB_STATE_ERROR; rc = JK_FALSE; } else if (service_stat == JK_AJP_PROTOCOL_ERROR) { /* * We've received a bad AJP message from the backend. * Keep previous global state. * Do not try to reuse the same node for the same request. * Failing over to another node could help. */ p->states[rec->i] = JK_LB_STATE_ERROR; rc = JK_FALSE; } else if (service_stat == JK_STATUS_ERROR) { /* * Status code configured as service is down. * The node is fine. * Do not try to reuse the same node for the same request. * Failing over to another node could help. */ rec->s->state = JK_LB_STATE_OK; p->states[rec->i] = JK_LB_STATE_ERROR; rec->s->first_error_time = 0; rec->s->last_error_time = 0; rc = JK_FALSE; } else if (service_stat == JK_BUSY_ERROR) { /* * Node was busy. * Do not try to reuse the same node for the same request. * Failing over to another node could help. */ rec->s->state = JK_LB_STATE_BUSY; p->states[rec->i] = JK_LB_STATE_BUSY; rc = JK_FALSE; } else if (service_stat == JK_STATUS_FATAL_ERROR) { /* * Status code configured as service is down. * Mark the node as bad. * Do not try to reuse the same node for the same request. * Failing over to another node could help. */ rec->s->errors++; rec->s->state = JK_LB_STATE_ERROR; p->states[rec->i] = JK_LB_STATE_ERROR; rec->s->first_error_time = time(NULL); rec->s->last_error_time = rec->s->first_error_time; rc = JK_FALSE; } else if (service_stat == JK_REPLY_TIMEOUT) { if (aw->s->reply_timeouts > (unsigned)p->worker->max_reply_timeouts) { /* * Service failed - to many reply timeouts * Mark the node as bad. * Do not try to reuse the same node for the same request. * Failing over to another node could help. */ rec->s->errors++; rec->s->state = JK_LB_STATE_ERROR; p->states[rec->i] = JK_LB_STATE_ERROR; rec->s->first_error_time = time(NULL); rec->s->last_error_time = rec->s->first_error_time; } else { /* * Reply timeout, bot not yet too many of them. * Keep previous global state. * Do not try to reuse the same node for the same request. * Failing over to another node could help. */ p->states[rec->i] = JK_LB_STATE_ERROR; } rc = JK_FALSE; } else { /* * Various unspecific error cases. * Keep previous global state, if we are not in local error since to long. * Do not try to reuse the same node for the same request. * Failing over to another node could help. */ time_t now = time(NULL); rec->s->errors++; if (aw->s->busy == 0 || p->worker->error_escalation_time == 0 || (rec->s->first_error_time > 0 && (int)difftime(now, rec->s->first_error_time) >= p->worker->error_escalation_time)) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "worker %s escalating local error to global error", rec->name); rec->s->state = JK_LB_STATE_ERROR; } p->states[rec->i] = JK_LB_STATE_ERROR; if (rec->s->first_error_time == 0) { rec->s->first_error_time = now; } rec->s->last_error_time = now; rc = JK_FALSE; } if (p->worker->lblock == JK_LB_LOCK_PESSIMISTIC) jk_shm_unlock(); if (p->states[rec->i] == JK_LB_STATE_ERROR) jk_log(l, JK_LOG_INFO, "service failed, worker %s is in %serror state", rec->name, rec->s->state == JK_LB_STATE_ERROR ? "" : "local "); } if (recoverable == JK_TRUE) { /* * Error is recoverable by submitting the request to * another worker... Lets try to do that. */ if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "recoverable error... will try to recover on other worker"); } else { /* * Error is not recoverable - break with an error. */ if (rc == JK_CLIENT_ERROR) jk_log(l, JK_LOG_INFO, "unrecoverable error %d, request failed." " Client failed in the middle of request," " we can't recover to another instance.", *is_error); else if (rc != JK_TRUE) jk_log(l, JK_LOG_ERROR, "unrecoverable error %d, request failed." " Tomcat failed in the middle of request," " we can't recover to another instance.", *is_error); } if (first == 1 && s->add_log_items) { first = 0; lb_add_log_items(s, lb_first_log_names, prec, l); } } else { /* No more workers left ... */ if (!was_forced) { int nf; /* Force recovery only once. * If it still fails, Tomcat is still disconnected. */ jk_shm_lock(); nf = force_recovery(p->worker, p->states, l); jk_shm_unlock(); was_forced = 1; if (nf) { /* We have forced recovery. * Reset the service loop and go again */ prec = NULL; jk_log(l, JK_LOG_INFO, "Forcing recovery once for %d workers", nf); continue; } else { /* No workers in error state. * Somebody set them all to disabled? */ jk_log(l, JK_LOG_INFO, "All tomcat instances failed, no more workers " "left for recovery (attempt=%d, retry=%d)", attempt, retry); *is_error = JK_HTTP_SERVER_BUSY; rc = JK_FALSE; } } else { jk_log(l, JK_LOG_INFO, "All tomcat instances failed, no more workers " "left (attempt=%d, retry=%d)", attempt, retry); *is_error = JK_HTTP_SERVER_BUSY; rc = JK_FALSE; } } attempt++; } if (recoverable == JK_TRUE) { jk_log(l, JK_LOG_INFO, "All tomcat instances are busy or in error state"); /* rc and http error must be set above */ } if (rc == JK_FALSE) { jk_log(l, JK_LOG_ERROR, "All tomcat instances failed, no more workers left"); } if (prec && s->add_log_items) { lb_add_log_items(s, lb_last_log_names, prec, l); } JK_TRACE_EXIT(l); return rc; } static int JK_METHOD done(jk_endpoint_t **e, jk_logger_t *l) { JK_TRACE_ENTER(l); if (e && *e && (*e)->endpoint_private) { lb_endpoint_t *p = (*e)->endpoint_private; free(p->states); free(p); *e = NULL; JK_TRACE_EXIT(l); return JK_TRUE; } JK_LOG_NULL_PARAMS(l); JK_TRACE_EXIT(l); return JK_FALSE; } static int JK_METHOD validate(jk_worker_t *pThis, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l) { JK_TRACE_ENTER(l); if (pThis && pThis->worker_private) { lb_worker_t *p = pThis->worker_private; char **worker_names; unsigned int num_of_workers; const char *secret; p->worker.we = we; p->sticky_session = jk_get_is_sticky_session(props, p->name); p->sticky_session_force = jk_get_is_sticky_session_force(props, p->name); secret = jk_get_worker_secret(props, p->name); if (jk_get_lb_worker_list(props, p->name, &worker_names, &num_of_workers) && num_of_workers) { unsigned int i = 0; unsigned int j = 0; p->lb_workers = jk_pool_alloc(&p->p, num_of_workers * sizeof(lb_sub_worker_t)); if (!p->lb_workers) { JK_TRACE_EXIT(l); return JK_FALSE; } memset(p->lb_workers, 0, num_of_workers * sizeof(lb_sub_worker_t)); for (i = 0; i < num_of_workers; i++) { if (jk_check_attribute_length("host name", worker_names[i], l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } p->lb_workers[i].s = jk_shm_alloc_lb_sub_worker(&p->p, p->s->h.id, worker_names[i], l); if (p->lb_workers[i].s == NULL) { jk_log(l, JK_LOG_ERROR, "allocating lb sub worker record from shared memory"); JK_TRACE_EXIT(l); return JK_FALSE; } p->lb_workers[i].i = i; strncpy(p->lb_workers[i].name, worker_names[i], JK_SHM_STR_SIZ); } for (i = 0; i < num_of_workers; i++) { const char *s; unsigned int ms; if (p->lb_workers[i].s->h.sequence != 0) { /* Somebody already setup this worker. * Just pull the data. */ if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "Balanced worker %s already configured (sequence=%d)", p->lb_workers[i].name, p->lb_workers[i].s->h.sequence); } if (!wc_create_worker(p->lb_workers[i].name, 0, props, &(p->lb_workers[i].worker), we, l) || !p->lb_workers[i].worker) { break; } jk_lb_pull_worker(p, i, l); continue; } p->lb_workers[i].lb_factor = jk_get_lb_factor(props, worker_names[i]); if (p->lb_workers[i].lb_factor < 1) { p->lb_workers[i].lb_factor = 1; } /* Calculate the maximum packet size from all workers * for the recovery buffer. */ ms = jk_get_max_packet_size(props, worker_names[i]); if (ms > p->max_packet_size) p->max_packet_size = ms; p->lb_workers[i].distance = jk_get_distance(props, worker_names[i]); if ((s = jk_get_worker_route(props, worker_names[i], NULL))) { if (jk_check_attribute_length("route", s, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } strncpy(p->lb_workers[i].route, s, JK_SHM_STR_SIZ); } else strncpy(p->lb_workers[i].route, worker_names[i], JK_SHM_STR_SIZ); if ((s = jk_get_worker_domain(props, worker_names[i], NULL))) { if (jk_check_attribute_length("domain", s, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } strncpy(p->lb_workers[i].domain, s, JK_SHM_STR_SIZ); } if ((s = jk_get_worker_redirect(props, worker_names[i], NULL))) { if (jk_check_attribute_length("redirect", s, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } strncpy(p->lb_workers[i].redirect, s, JK_SHM_STR_SIZ); } p->lb_workers[i].s->lb_value = 0; p->lb_workers[i].s->state = JK_LB_STATE_IDLE; p->lb_workers[i].s->first_error_time = 0; p->lb_workers[i].s->last_error_time = 0; p->lb_workers[i].s->elected_snapshot = 0; p->lb_workers[i].s->sessions = 0; p->lb_workers[i].activation = jk_get_worker_activation(props, worker_names[i]); if (!wc_create_worker(p->lb_workers[i].name, 0, props, &(p->lb_workers[i].worker), we, l) || !p->lb_workers[i].worker) { break; } if (secret && (p->lb_workers[i].worker->type == JK_AJP13_WORKER_TYPE || p->lb_workers[i].worker->type == JK_AJP14_WORKER_TYPE)) { ajp_worker_t *aw = (ajp_worker_t *)p->lb_workers[i].worker->worker_private; if (!aw->secret) aw->secret = secret; } if (p->lb_workers[i].worker->type == JK_AJP13_WORKER_TYPE || p->lb_workers[i].worker->type == JK_AJP14_WORKER_TYPE) { ajp_worker_t *aw = (ajp_worker_t *)p->lb_workers[i].worker->worker_private; if (aw->port == 0) { p->lb_workers[i].activation = JK_LB_ACTIVATION_STOPPED; } } } if (i != num_of_workers) { jk_log(l, JK_LOG_ERROR, "Failed creating worker %s", p->lb_workers[i].name); close_workers(p, i, l); } else { /* Update domain names if route contains period '.' */ for (i = 0; i < num_of_workers; i++) { if (!p->lb_workers[i].domain[0]) { char *id_domain = strchr(p->lb_workers[i].route, '.'); if (id_domain) { *id_domain = '\0'; strcpy(p->lb_workers[i].domain, p->lb_workers[i].route); *id_domain = '.'; } } if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "Balanced worker %d has name %s and route %s in domain %s", i, p->lb_workers[i].name, p->lb_workers[i].route, p->lb_workers[i].domain); } } p->num_of_workers = num_of_workers; update_mult(p, l); for (i = 0; i < num_of_workers; i++) { for (j = 0; j < i; j++) { if (strcmp(p->lb_workers[i].route, p->lb_workers[j].route) == 0) { jk_log(l, JK_LOG_ERROR, "Balanced workers number %d (%s) and %d (%s) share the same route %s - aborting configuration!", i, p->lb_workers[i].name, j, p->lb_workers[j].name, p->lb_workers[i].route); JK_TRACE_EXIT(l); return JK_FALSE; } } } JK_TRACE_EXIT(l); return JK_TRUE; } } } JK_LOG_NULL_PARAMS(l); JK_TRACE_EXIT(l); return JK_FALSE; } static int JK_METHOD init(jk_worker_t *pThis, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *log) { int i; const char *s; lb_worker_t *p = (lb_worker_t *)pThis->worker_private; JK_TRACE_ENTER(log); p->worker.we = we; p->retries = jk_get_worker_retries(props, p->name, JK_RETRIES); p->retry_interval = jk_get_worker_retry_interval(props, p->name, JK_SLEEP_DEF); p->recover_wait_time = jk_get_worker_recover_timeout(props, p->name, WAIT_BEFORE_RECOVER); if (p->recover_wait_time < 1) p->recover_wait_time = 1; p->error_escalation_time = jk_get_worker_error_escalation_time(props, p->name, p->recover_wait_time / 2); p->max_reply_timeouts = jk_get_worker_max_reply_timeouts(props, p->name, 0); p->maintain_time = jk_get_worker_maintain_time(props); if(p->maintain_time < 0) p->maintain_time = 0; p->s->last_maintain_time = time(NULL); p->s->last_reset = p->s->last_maintain_time; p->lbmethod = jk_get_lb_method(props, p->name); #ifdef JK_ATOMIC_MISSING if (p->lbmethod == JK_LB_METHOD_BUSYNESS) { jk_log(log, JK_LOG_WARNING, "Missing support for atomics: " "LB method 'busyness' not recommended"); } #endif p->lblock = jk_get_lb_lock(props, p->name); s = jk_get_lb_session_cookie(props, p->name, JK_SESSION_IDENTIFIER); if (jk_check_attribute_length("session_cookie", s, log) == JK_FALSE) { JK_TRACE_EXIT(log); return JK_FALSE; } strncpy(p->session_cookie, s, JK_SHM_STR_SIZ); s = jk_get_lb_session_path(props, p->name, JK_PATH_SESSION_IDENTIFIER); if (jk_check_attribute_length("session_path", s, log) == JK_FALSE) { JK_TRACE_EXIT(log); return JK_FALSE; } strncpy(p->session_path, s, JK_SHM_STR_SIZ); p->set_session_cookie = jk_get_lb_set_session_cookie(props, p->name, JK_FALSE); s = jk_get_lb_session_cookie_path(props, p->name, "/"); if (jk_check_attribute_length("session_cookie_path", s, log) == JK_FALSE) { JK_TRACE_EXIT(log); return JK_FALSE; } strncpy(p->session_cookie_path, s, JK_SHM_STR_SIZ); JK_INIT_CS(&(p->cs), i); if (i == JK_FALSE) { jk_log(log, JK_LOG_ERROR, "creating thread lock (errno=%d)", errno); JK_TRACE_EXIT(log); return JK_FALSE; } if (p->s->h.sequence == 0) { /* Set configuration data to shared memory */ jk_lb_push(p, JK_TRUE, log); } else { /* Shared memory for this worker is already configured. * Update with runtime data */ jk_lb_pull(p, JK_TRUE, log); } JK_TRACE_EXIT(log); return JK_TRUE; } static int JK_METHOD get_endpoint(jk_worker_t *pThis, jk_endpoint_t **pend, jk_logger_t *l) { JK_TRACE_ENTER(l); if (pThis && pThis->worker_private && pend) { lb_endpoint_t *p = (lb_endpoint_t *) malloc(sizeof(lb_endpoint_t)); p->worker = pThis->worker_private; p->endpoint.endpoint_private = p; p->endpoint.service = service; p->endpoint.done = done; p->states = (int *)malloc((p->worker->num_of_workers + 1) * sizeof(int)); if (!p->states) { free(p); jk_log(l, JK_LOG_ERROR, "Failed allocating private worker state memory"); JK_TRACE_EXIT(l); return JK_FALSE; } *pend = &p->endpoint; JK_TRACE_EXIT(l); return JK_TRUE; } else { JK_LOG_NULL_PARAMS(l); } JK_TRACE_EXIT(l); return JK_FALSE; } static int JK_METHOD destroy(jk_worker_t **pThis, jk_logger_t *l) { JK_TRACE_ENTER(l); if (pThis && *pThis && (*pThis)->worker_private) { lb_worker_t *private_data = (*pThis)->worker_private; close_workers(private_data, private_data->num_of_workers, l); JK_DELETE_CS(&private_data->cs); jk_close_pool(&private_data->p); free(private_data); JK_TRACE_EXIT(l); return JK_TRUE; } JK_LOG_NULL_PARAMS(l); JK_TRACE_EXIT(l); return JK_FALSE; } int JK_METHOD lb_worker_factory(jk_worker_t **w, const char *name, jk_logger_t *l) { JK_TRACE_ENTER(l); if (NULL != name && NULL != w) { lb_worker_t *private_data = (lb_worker_t *) calloc(1, sizeof(lb_worker_t)); jk_open_pool(&private_data->p, private_data->buf, sizeof(jk_pool_atom_t) * TINY_POOL_SIZE); private_data->s = jk_shm_alloc_lb_worker(&private_data->p, name, l); if (!private_data->s) { free(private_data); JK_TRACE_EXIT(l); return 0; } strncpy(private_data->name, name, JK_SHM_STR_SIZ); private_data->lb_workers = NULL; private_data->num_of_workers = 0; private_data->worker.worker_private = private_data; private_data->worker.validate = validate; private_data->worker.init = init; private_data->worker.get_endpoint = get_endpoint; private_data->worker.destroy = destroy; private_data->worker.maintain = maintain_workers; private_data->worker.shutdown = shutdown_workers; private_data->recover_wait_time = WAIT_BEFORE_RECOVER; private_data->error_escalation_time = private_data->recover_wait_time / 2; private_data->max_reply_timeouts = 0; private_data->max_packet_size = AJP13_DEF_PACKET_SIZE; private_data->sequence = 0; private_data->next_offset = 0; *w = &private_data->worker; JK_TRACE_EXIT(l); return JK_LB_WORKER_TYPE; } else { JK_LOG_NULL_PARAMS(l); } JK_TRACE_EXIT(l); return 0; } tomcat-connectors-1.2.41-src/native/common/jk_ajp13.h0000644000000000000020000000743312453255640020661 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Experimental bi-directionl protocol handler. * * Author: Gal Shachor * * Version: $Revision: 1650098 $ * ***************************************************************************/ #ifndef JK_AJP13_H #define JK_AJP13_H #include "jk_ajp_common.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define AJP13_PROTO 13 #define AJP13_WS_HEADER 0x1234 #define AJP13_SW_HEADER 0x4142 /* 'AB' */ #define AJP13_DEF_HOST ("localhost") #define AJP13_DEF_PORT (8009) #define AJP13_DEF_PACKET_SIZE (8*1024) #define AJP13_MAX_PACKET_SIZE (64*1024) #define AJP13_PACKET_SIZE_ALIGN (1024) #define AJP13_DEF_CACHE_SZ (1) #define JK_INTERNAL_ERROR (-2) #define JK_FATAL_ERROR (-3) #define JK_CLIENT_ERROR (-4) #define JK_SERVER_ERROR (-5) #define JK_CLIENT_RD_ERROR (-6) #define JK_CLIENT_WR_ERROR (-7) #define JK_STATUS_ERROR (-8) #define JK_STATUS_FATAL_ERROR (-9) #define JK_REPLY_TIMEOUT (-10) #define JK_AJP_PROTOCOL_ERROR (-11) #define JK_BUSY_ERROR (-12) #define AJP13_DEF_TIMEOUT (0) /* Idle timout for pooled connections */ /* * Message does not have a response (for example, JK_AJP13_END_RESPONSE) */ #define JK_AJP13_ERROR -1 /* * Message does not have a response (for example, JK_AJP13_END_RESPONSE) */ #define JK_AJP13_NO_RESPONSE 0 /* * Message have a response. */ #define JK_AJP13_HAS_RESPONSE 1 /* * Forward a request from the web server to the servlet container. */ #define JK_AJP13_FORWARD_REQUEST (unsigned char)2 /* * Write a body chunk from the servlet container to the web server */ #define JK_AJP13_SEND_BODY_CHUNK (unsigned char)3 /* * Send response headers from the servlet container to the web server. */ #define JK_AJP13_SEND_HEADERS (unsigned char)4 /* * Marks the end of response. */ #define JK_AJP13_END_RESPONSE (unsigned char)5 /* * Marks the end of response. */ #define JK_AJP13_GET_BODY_CHUNK (unsigned char)6 /* * Asks the container to shutdown */ #define JK_AJP13_SHUTDOWN (unsigned char)7 /* * Told container to take control (secure login phase) */ #define AJP13_PING_REQUEST (unsigned char)8 /* * Check if the container is alive */ #define AJP13_CPING_REQUEST (unsigned char)10 /* * Reply from the container to alive request */ #define AJP13_CPONG_REPLY (unsigned char)9 /* * Functions */ int ajp13_marshal_shutdown_into_msgb(jk_msg_buf_t *msg, jk_pool_t *p, jk_logger_t *l); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_AJP13_H */ tomcat-connectors-1.2.41-src/native/common/jk_pool.c0000644000000000000020000001110311734272245020675 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Simple memory pool * * Author: Gal Shachor * * Version: $Revision: 1305768 $ * ***************************************************************************/ #include "jk_pool.h" #define DEFAULT_DYNAMIC 10 void jk_open_pool(jk_pool_t *p, jk_pool_atom_t *buf, size_t size) { p->pos = 0; p->size = size; p->buf = (char *)buf; p->dyn_pos = 0; p->dynamic = NULL; p->dyn_size = 0; } void jk_close_pool(jk_pool_t *p) { jk_reset_pool(p); if (p->dynamic) { free(p->dynamic); } } void jk_reset_pool(jk_pool_t *p) { if (p->dyn_pos && p->dynamic) { size_t i; for (i = 0; i < p->dyn_pos; i++) { if (p->dynamic[i]) { free(p->dynamic[i]); } } } p->dyn_pos = 0; p->pos = 0; } void *jk_pool_alloc(jk_pool_t *p, size_t size) { void *rc = NULL; if (size == 0) return NULL; size = JK_ALIGN_DEFAULT(size); if ((p->size - p->pos) >= size) { rc = &(p->buf[p->pos]); p->pos += size; } else { if (p->dyn_size == p->dyn_pos) { size_t new_dyn_size = p->dyn_size * 2 + DEFAULT_DYNAMIC; void **new_dynamic = (void **)realloc(p->dynamic, new_dyn_size * sizeof(void *)); if (new_dynamic) { p->dynamic = new_dynamic; p->dyn_size = new_dyn_size; } else { return NULL; } } rc = p->dynamic[p->dyn_pos] = malloc(size); if (p->dynamic[p->dyn_pos]) { p->dyn_pos++; } } return rc; } void *jk_pool_calloc(jk_pool_t *p, size_t size) { void *rc = jk_pool_alloc(p, size); if (rc) memset(rc, 0, size); return rc; } void *jk_pool_realloc(jk_pool_t *p, size_t sz, const void *old, size_t old_sz) { char *rc; if (!p || (sz < old_sz)) { return NULL; } if (!old) return jk_pool_calloc(p, sz); rc = (char *)jk_pool_alloc(p, sz); if (rc) { memcpy(rc, old, old_sz); memset(rc + old_sz, 0, sz - old_sz); } return rc; } char *jk_pool_strdup(jk_pool_t *p, const char *s) { char *rc = NULL; if (s && p) { size_t size = strlen(s); if (!size) { return ""; } size++; rc = jk_pool_alloc(p, size); if (rc) { memcpy(rc, s, size); } } return rc; } char *jk_pool_strcat(jk_pool_t *p, const char *s, const char *a) { char *rc = NULL; if (s && a && p) { size_t szs = strlen(s); size_t sza = strlen(a); if ((szs + sza) == 0) { return ""; } rc = jk_pool_alloc(p, szs + sza + 1); if (rc) { memcpy(rc, s, szs); memcpy(rc + szs, a, sza + 1); } } return rc; } char *jk_pool_strcatv(jk_pool_t *p, ...) { char *cp; char *rc = NULL; va_list ap; if (p) { char *str; size_t size = 0; va_start(ap, p); while ((str = va_arg(ap, char *)) != 0) { size += strlen(str); } va_end(ap); if (size == 0) { return ""; } size++; cp = rc = jk_pool_alloc(p, size); if (rc) { size_t len = 0; va_start(ap, p); while ((str = va_arg(ap, char *)) != 0) { len = strlen(str); memcpy(cp, str, len); cp += len; } va_end(ap); *cp = '\0'; } } return rc; } tomcat-connectors-1.2.41-src/native/common/jk.rc0000644000000000000020000000553711460033176020036 0ustar rootbin/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "jk_version.h" #define ASF_COPYRIGHT "Licensed to the Apache Software Foundation " \ "(ASF) under one or more contributor license " \ "agreements. See the NOTICE file distributed " \ "with this work for additional information " \ "regarding copyright ownership." #define ASF_LICENSE "The ASF licenses this file to You under the " \ "Apache License, Version 2.0 (the ""License""); " \ "you may not use this file except in compliance " \ "with the License. You may obtain a copy of " \ "the License at\r\n\r\n" \ "http://www.apache.org/licenses/LICENSE-2.0\r\n\r\n" \ "Unless required by applicable law or agreed to in " \ "writing, software distributed under the License is " \ "distributed on an ""AS IS"" BASIS, WITHOUT " \ "WARRANTIES OR CONDITIONS OF ANY KIND, either " \ "express or implied. See the License for the " \ "specific language governing permissions and " \ "limitations under the License." 1 VERSIONINFO FILEVERSION JK_VERSIONCSV PRODUCTVERSION JK_VERSIONCSV FILEFLAGSMASK 0x3fL #if defined(_DEBUG) FILEFLAGS 0x01L #else FILEFLAGS 0x00L #endif FILEOS 0x40004L FILETYPE 0x1L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", ASF_LICENSE "\0" VALUE "CompanyName", "Apache Software Foundation\0" VALUE "FileDescription", "Apache Tomcat Connector\0" VALUE "FileVersion", JK_VERSTRING "\0" VALUE "InternalName", PACKAGE "\0" VALUE "LegalCopyright", ASF_COPYRIGHT "\0" VALUE "OriginalFilename", PACKAGE "." JK_DLL_SUFFIX "\0" VALUE "ProductName", "Apache Tomcat " PACKAGE " Connector\0" VALUE "ProductVersion", JK_VERSTRING "\0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END tomcat-connectors-1.2.41-src/native/common/jk_ajp13_worker.c0000644000000000000020000000564010742434763022247 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Bi-directional protocol. * * Author: Costin * * Author: Gal Shachor * * Author: Henri Gomez * * Version: $Revision: 611589 $ * ***************************************************************************/ #include "jk_ajp13_worker.h" /* -------------------- Method -------------------- */ static int JK_METHOD validate(jk_worker_t *pThis, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l) { int rc; JK_TRACE_ENTER(l); rc = ajp_validate(pThis, props, we, l, AJP13_PROTO); JK_TRACE_EXIT(l); return rc; } static int JK_METHOD init(jk_worker_t *pThis, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l) { int rc; JK_TRACE_ENTER(l); rc = ajp_init(pThis, props, we, l, AJP13_PROTO); JK_TRACE_EXIT(l); return rc; } static int JK_METHOD destroy(jk_worker_t **pThis, jk_logger_t *l) { int rc; JK_TRACE_ENTER(l); rc = ajp_destroy(pThis, l, AJP13_PROTO); JK_TRACE_EXIT(l); return rc; } static int JK_METHOD get_endpoint(jk_worker_t *pThis, jk_endpoint_t **pend, jk_logger_t *l) { int rc; JK_TRACE_ENTER(l); rc = ajp_get_endpoint(pThis, pend, l, AJP13_PROTO); JK_TRACE_EXIT(l); return rc; } int JK_METHOD ajp13_worker_factory(jk_worker_t **w, const char *name, jk_logger_t *l) { ajp_worker_t *aw; JK_TRACE_ENTER(l); if (ajp_worker_factory(w, name, l) == JK_FALSE) return 0; aw = (*w)->worker_private; aw->proto = AJP13_PROTO; aw->worker.validate = validate; aw->worker.init = init; aw->worker.get_endpoint = get_endpoint; aw->worker.destroy = destroy; JK_TRACE_EXIT(l); return JK_AJP13_WORKER_TYPE; } tomcat-connectors-1.2.41-src/native/common/jk_worker.h0000644000000000000020000000400212452471775021251 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Workers controller header file * * Author: Gal Shachor * * Version: $Revision: 1649503 $ * ***************************************************************************/ #ifndef JK_WORKER_H #define JK_WORKER_H #include "jk_logger.h" #include "jk_service.h" #include "jk_map.h" #include "jk_uri_worker_map.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ int wc_open(jk_map_t *init_data, jk_worker_env_t *we, jk_logger_t *l); void wc_close(jk_logger_t *l); jk_worker_t *wc_get_worker_for_name(const char *name, jk_logger_t *l); const char *wc_get_name_for_type(int type, jk_logger_t *l); int wc_create_worker(const char *name, int use_map, jk_map_t *init_data, jk_worker_t **rc, jk_worker_env_t *we, jk_logger_t *l); void wc_maintain(jk_logger_t *l); void wc_shutdown(jk_logger_t *l); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_WORKER_H */ tomcat-connectors-1.2.41-src/native/common/jk_ajp14.c0000644000000000000020000004430112447333010020637 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Next generation bi-directional protocol handler. * * Author: Henri Gomez * * Version: $Revision: 1648014 $ * ***************************************************************************/ #include "jk_global.h" #include "jk_util.h" #include "jk_map.h" #include "jk_ajp_common.h" #include "jk_ajp14.h" #include "jk_md5.h" /* * Compute the MD5 with ENTROPY / SECRET KEY */ void ajp14_compute_md5(jk_login_service_t *s, jk_logger_t *l) { JK_TRACE_ENTER(l); jk_md5((const unsigned char *)s->entropy, (const unsigned char *)s->secret_key, s->computed_key); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s/%s) -> (%s)", s->entropy, s->secret_key, s->computed_key); JK_TRACE_EXIT(l); } /* * Build the Login Init Command * * +-------------------------+---------------------------+---------------------------+ * | LOGIN INIT CMD (1 byte) | NEGOTIATION DATA (32bits) | WEB SERVER INFO (CString) | * +-------------------------+---------------------------+---------------------------+ * */ int ajp14_marshal_login_init_into_msgb(jk_msg_buf_t *msg, jk_login_service_t *s, jk_logger_t *l) { JK_TRACE_ENTER(l); /* To be on the safe side */ jk_b_reset(msg); /* * LOGIN */ if (jk_b_append_byte(msg, AJP14_LOGINIT_CMD)) { JK_TRACE_EXIT(l); return JK_FALSE; } /* * NEGOTIATION FLAGS */ if (jk_b_append_long(msg, s->negotiation)) { JK_TRACE_EXIT(l); return JK_FALSE; } /* * WEB-SERVER NAME */ if (jk_b_append_string(msg, s->web_server_name)) { jk_log(l, JK_LOG_ERROR, "failed appending the web_server_name string"); JK_TRACE_EXIT(l); return JK_FALSE; } JK_TRACE_EXIT(l); return JK_TRUE; } /* * Decode the Login Seed Command * * +-------------------------+---------------------------+ * | LOGIN SEED CMD (1 byte) | MD5 of entropy (32 chars) | * +-------------------------+---------------------------+ * */ int ajp14_unmarshal_login_seed(jk_msg_buf_t *msg, jk_login_service_t *s, jk_logger_t *l) { JK_TRACE_ENTER(l); if (jk_b_get_bytes (msg, (unsigned char *)s->entropy, AJP14_ENTROPY_SEED_LEN) < 0) { jk_log(l, JK_LOG_ERROR, "can't get seed"); JK_TRACE_EXIT(l); return JK_FALSE; } s->entropy[AJP14_ENTROPY_SEED_LEN] = 0; /* Just to have a CString */ JK_TRACE_EXIT(l); return JK_TRUE; } /* * Build the Login Computed Command * * +-------------------------+---------------------------------------+ * | LOGIN COMP CMD (1 byte) | MD5 of RANDOM + SECRET KEY (32 chars) | * +-------------------------+---------------------------------------+ * */ int ajp14_marshal_login_comp_into_msgb(jk_msg_buf_t *msg, jk_login_service_t *s, jk_logger_t *l) { JK_TRACE_ENTER(l); /* To be on the safe side */ jk_b_reset(msg); /* * LOGIN */ if (jk_b_append_byte(msg, AJP14_LOGCOMP_CMD)) { JK_TRACE_EXIT(l); return JK_FALSE; } /* * COMPUTED-SEED */ if (jk_b_append_bytes (msg, (const unsigned char *)s->computed_key, AJP14_COMPUTED_KEY_LEN)) { jk_log(l, JK_LOG_ERROR, "failed appending the COMPUTED MD5 bytes"); JK_TRACE_EXIT(l); return JK_FALSE; } JK_TRACE_EXIT(l); return JK_TRUE; } /* * Decode the LogOk Command * * +--------------------+------------------------+-------------------------------+ * | LOGOK CMD (1 byte) | NEGOCIED DATA (32bits) | SERVLET ENGINE INFO (CString) | * +--------------------+------------------------+-------------------------------+ * */ int ajp14_unmarshal_log_ok(jk_msg_buf_t *msg, jk_login_service_t *s, jk_logger_t *l) { unsigned long nego; char *sname; JK_TRACE_ENTER(l); nego = jk_b_get_long(msg); if (nego == 0xFFFFFFFF) { jk_log(l, JK_LOG_ERROR, "can't get negociated data"); JK_TRACE_EXIT(l); return JK_FALSE; } sname = jk_b_get_string(msg); if (!sname) { jk_log(l, JK_LOG_ERROR, "can't get servlet engine name"); JK_TRACE_EXIT(l); return JK_FALSE; } if (s->servlet_engine_name) /* take care of removing previously allocated data */ free(s->servlet_engine_name); s->servlet_engine_name = strdup(sname); if (!s->servlet_engine_name) { jk_log(l, JK_LOG_ERROR, "can't malloc servlet engine name"); JK_TRACE_EXIT(l); return JK_FALSE; } JK_TRACE_EXIT(l); return JK_TRUE; } /* * Decode the Log Nok Command * * +---------------------+-----------------------+ * | LOGNOK CMD (1 byte) | FAILURE CODE (32bits) | * +---------------------+-----------------------+ * */ int ajp14_unmarshal_log_nok(jk_msg_buf_t *msg, jk_logger_t *l) { unsigned long status; JK_TRACE_ENTER(l); status = jk_b_get_long(msg); if (status == 0xFFFFFFFF) { jk_log(l, JK_LOG_ERROR, "can't get failure code"); JK_TRACE_EXIT(l); return JK_FALSE; } jk_log(l, JK_LOG_INFO, "Can't Log with servlet engine - code %08lx", status); JK_TRACE_EXIT(l); return JK_TRUE; } /* * Build the Shutdown Cmd * * +-----------------------+---------------------------------------+ * | SHUTDOWN CMD (1 byte) | MD5 of RANDOM + SECRET KEY (32 chars) | * +-----------------------+---------------------------------------+ * */ int ajp14_marshal_shutdown_into_msgb(jk_msg_buf_t *msg, jk_login_service_t *s, jk_logger_t *l) { JK_TRACE_ENTER(l); /* To be on the safe side */ jk_b_reset(msg); /* * SHUTDOWN CMD */ if (jk_b_append_byte(msg, AJP14_SHUTDOWN_CMD)) { JK_TRACE_EXIT(l); return JK_FALSE; } /* * COMPUTED-SEED */ if (jk_b_append_bytes (msg, (const unsigned char *)s->computed_key, AJP14_COMPUTED_KEY_LEN)) { jk_log(l, JK_LOG_ERROR, "failed appending the COMPUTED MD5 bytes"); JK_TRACE_EXIT(l); return JK_FALSE; } JK_TRACE_EXIT(l); return JK_TRUE; } /* * Decode the Shutdown Nok Command * * +----------------------+-----------------------+ * | SHUTNOK CMD (1 byte) | FAILURE CODE (32bits) | * +----------------------+-----------------------+ * */ int ajp14_unmarshal_shutdown_nok(jk_msg_buf_t *msg, jk_logger_t *l) { unsigned long status; JK_TRACE_ENTER(l); status = jk_b_get_long(msg); if (status == 0xFFFFFFFF) { jk_log(l, JK_LOG_ERROR, "can't get failure code"); JK_TRACE_EXIT(l); return JK_FALSE; } jk_log(l, JK_LOG_INFO, "Can't shutdown servlet engine - code %08lx", status); JK_TRACE_EXIT(l); return JK_TRUE; } /* * Build the Unknown Packet * * +-----------------------------+---------------------------------+------------------------------+ * | UNKNOWN PACKET CMD (1 byte) | UNHANDLED MESSAGE SIZE (16bits) | UNHANDLED MESSAGE (bytes...) | * +-----------------------------+---------------------------------+------------------------------+ * */ int ajp14_marshal_unknown_packet_into_msgb(jk_msg_buf_t *msg, jk_msg_buf_t *unk, jk_logger_t *l) { JK_TRACE_ENTER(l); /* To be on the safe side */ jk_b_reset(msg); /* * UNKNOWN PACKET CMD */ if (jk_b_append_byte(msg, AJP14_UNKNOW_PACKET_CMD)) { JK_TRACE_EXIT(l); return JK_FALSE; } /* * UNHANDLED MESSAGE SIZE */ if (jk_b_append_int(msg, (unsigned short)unk->len)) { JK_TRACE_EXIT(l); return JK_FALSE; } /* * UNHANDLED MESSAGE (Question : Did we have to send all the message or only part of) * ( ie: only 1k max ) */ if (jk_b_append_bytes(msg, unk->buf, unk->len)) { jk_log(l, JK_LOG_ERROR, "failed appending the UNHANDLED MESSAGE"); JK_TRACE_EXIT(l); return JK_FALSE; } JK_TRACE_EXIT(l); return JK_TRUE; } /* * Build the Context Query Cmd (autoconf) * * +--------------------------+---------------------------------+ * | CONTEXT QRY CMD (1 byte) | VIRTUAL HOST NAME (CString (*)) | * +--------------------------+---------------------------------+ * */ int ajp14_marshal_context_query_into_msgb(jk_msg_buf_t *msg, char *virtual, jk_logger_t *l) { JK_TRACE_ENTER(l); /* To be on the safe side */ jk_b_reset(msg); /* * CONTEXT QUERY CMD */ if (jk_b_append_byte(msg, AJP14_CONTEXT_QRY_CMD)) { JK_TRACE_EXIT(l); return JK_FALSE; } /* * VIRTUAL HOST CSTRING */ if (jk_b_append_string(msg, virtual)) { jk_log(l, JK_LOG_ERROR, "failed appending the virtual host string"); JK_TRACE_EXIT(l); return JK_FALSE; } JK_TRACE_EXIT(l); return JK_TRUE; } /* * Decode the Context Info Cmd (Autoconf) * * The Autoconf feature of AJP14, let us know which URL/URI could * be handled by the servlet-engine * * +---------------------------+---------------------------------+----------------------------+-------------------------------+-----------+ * | CONTEXT INFO CMD (1 byte) | VIRTUAL HOST NAME (CString (*)) | CONTEXT NAME (CString (*)) | URL1 [\n] URL2 [\n] URL3 [\n] | NEXT CTX. | * +---------------------------+---------------------------------+----------------------------+-------------------------------+-----------+ */ int ajp14_unmarshal_context_info(jk_msg_buf_t *msg, jk_context_t *c, jk_logger_t *l) { char *vname; char *cname; char *uri; vname = jk_b_get_string(msg); JK_TRACE_ENTER(l); jk_log(l, JK_LOG_DEBUG, "get virtual %s for virtual %s", vname, c->virt); if (!vname) { jk_log(l, JK_LOG_ERROR, "can't get virtual hostname"); JK_TRACE_EXIT(l); return JK_FALSE; } /* Check if we get the correct virtual host */ if (c->virt != NULL && vname != NULL && strcmp(c->virt, vname)) { /* set the virtual name, better to add to a virtual list ? */ if (context_set_virtual(c, vname) == JK_FALSE) { jk_log(l, JK_LOG_ERROR, "can't malloc virtual hostname"); JK_TRACE_EXIT(l); return JK_FALSE; } } for (;;) { cname = jk_b_get_string(msg); if (!cname) { jk_log(l, JK_LOG_ERROR, "can't get context"); JK_TRACE_EXIT(l); return JK_FALSE; } jk_log(l, JK_LOG_DEBUG, "get context %s for virtual %s", cname, vname); /* grab all contexts up to empty one which indicate end of contexts */ if (!strlen(cname)) break; /* create new context base (if needed) */ if (context_add_base(c, cname) == JK_FALSE) { jk_log(l, JK_LOG_ERROR, "can't add/set context %s", cname); JK_TRACE_EXIT(l); return JK_FALSE; } for (;;) { uri = jk_b_get_string(msg); if (!uri) { jk_log(l, JK_LOG_ERROR, "can't get URI"); JK_TRACE_EXIT(l); return JK_FALSE; } if (!strlen(uri)) { jk_log(l, JK_LOG_DEBUG, "No more URI for context %s", cname); break; } jk_log(l, JK_LOG_INFO, "Got URI (%s) for virtualhost %s and context %s", uri, vname, cname); if (context_add_uri(c, cname, uri) == JK_FALSE) { jk_log(l, JK_LOG_ERROR, "can't add/set uri (%s) for context %s", uri, cname); JK_TRACE_EXIT(l); return JK_FALSE; } } } JK_TRACE_EXIT(l); return JK_TRUE; } /* * Build the Context State Query Cmd * * We send the list of contexts where we want to know state, empty string end context list* * If cname is set, only ask about THIS context * * +----------------------------+----------------------------------+----------------------------+----+ * | CONTEXT STATE CMD (1 byte) | VIRTUAL HOST NAME (CString (*)) | CONTEXT NAME (CString (*)) | .. | * +----------------------------+----------------------------------+----------------------------+----+ * */ int ajp14_marshal_context_state_into_msgb(jk_msg_buf_t *msg, jk_context_t *c, char *cname, jk_logger_t *l) { jk_context_item_t *ci; int i; JK_TRACE_ENTER(l); /* To be on the safe side */ jk_b_reset(msg); /* * CONTEXT STATE CMD */ if (jk_b_append_byte(msg, AJP14_CONTEXT_STATE_CMD)) { JK_TRACE_EXIT(l); return JK_FALSE; } /* * VIRTUAL HOST CSTRING */ if (jk_b_append_string(msg, c->virt)) { jk_log(l, JK_LOG_ERROR, "failed appending the virtual host string"); JK_TRACE_EXIT(l); return JK_FALSE; } if (cname) { ci = context_find_base(c, cname); if (!ci) { jk_log(l, JK_LOG_ERROR, "unknown context %s", cname); JK_TRACE_EXIT(l); return JK_FALSE; } /* * CONTEXT CSTRING */ if (jk_b_append_string(msg, cname)) { jk_log(l, JK_LOG_ERROR, "failed appending the context string %s", cname); JK_TRACE_EXIT(l); return JK_FALSE; } } else { /* Grab all contexts name */ for (i = 0; i < c->size; i++) { /* * CONTEXT CSTRING */ if (jk_b_append_string(msg, c->contexts[i]->cbase)) { jk_log(l, JK_LOG_ERROR, "failed appending the context string %s", c->contexts[i]->cbase); JK_TRACE_EXIT(l); return JK_FALSE; } } } /* End of context list, an empty string */ if (jk_b_append_string(msg, "")) { jk_log(l, JK_LOG_ERROR, "failed appending end of contexts"); JK_TRACE_EXIT(l); return JK_FALSE; } JK_TRACE_EXIT(l); return JK_TRUE; } /* * Decode the Context State Reply Cmd * * We get update of contexts list, empty string end context list* * * +----------------------------------+---------------------------------+----------------------------+------------------+----+ * | CONTEXT STATE REPLY CMD (1 byte) | VIRTUAL HOST NAME (CString (*)) | CONTEXT NAME (CString (*)) | UP/DOWN (1 byte) | .. | * +----------------------------------+---------------------------------+----------------------------+------------------+----+ * */ int ajp14_unmarshal_context_state_reply(jk_msg_buf_t *msg, jk_context_t *c, jk_logger_t *l) { char *vname; char *cname; jk_context_item_t *ci; JK_TRACE_ENTER(l); /* get virtual name */ vname = jk_b_get_string(msg); if (!vname) { jk_log(l, JK_LOG_ERROR, "can't get virtual hostname"); JK_TRACE_EXIT(l); return JK_FALSE; } /* Check if we speak about the correct virtual */ if (strcmp(c->virt, vname)) { jk_log(l, JK_LOG_ERROR, "incorrect virtual %s instead of %s", vname, c->virt); JK_TRACE_EXIT(l); return JK_FALSE; } for (;;) { /* get context name */ cname = jk_b_get_string(msg); if (!cname) { jk_log(l, JK_LOG_ERROR, "can't get context"); JK_TRACE_EXIT(l); return JK_FALSE; } if (!strlen(cname)) break; ci = context_find_base(c, cname); if (!ci) { jk_log(l, JK_LOG_ERROR, "unknow context %s for virtual %s", cname, vname); JK_TRACE_EXIT(l); return JK_FALSE; } ci->status = jk_b_get_int(msg); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "updated context %s to state %d", cname, ci->status); } JK_TRACE_EXIT(l); return JK_TRUE; } /* * Decode the Context Update Cmd * * +-----------------------------+---------------------------------+----------------------------+------------------+ * | CONTEXT UPDATE CMD (1 byte) | VIRTUAL HOST NAME (CString (*)) | CONTEXT NAME (CString (*)) | UP/DOWN (1 byte) | * +-----------------------------+---------------------------------+----------------------------+------------------+ * */ int ajp14_unmarshal_context_update_cmd(jk_msg_buf_t *msg, jk_context_t *c, jk_logger_t *l) { int rc; JK_TRACE_ENTER(l); rc = ajp14_unmarshal_context_state_reply(msg, c, l); JK_TRACE_EXIT(l); return rc; } tomcat-connectors-1.2.41-src/native/common/jk_ajp_common.c0000644000000000000020000037111012477544555022070 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: common stuff for bi-directional protocols ajp13/ajp14. * * Author: Gal Shachor * * Author: Henri Gomez * * Version: $Revision: 1665454 $ * ***************************************************************************/ #include "jk_global.h" #include "jk_util.h" #include "jk_ajp13.h" #include "jk_ajp14.h" #include "jk_ajp_common.h" #include "jk_connect.h" #if defined(AS400) && !defined(AS400_UTF8) #include "util_ebcdic.h" #endif #if defined(NETWARE) && defined(__NOVELL_LIBC__) #include "novsock2.h" #endif /* Macro for checking the availability of the cache slot */ #define IS_SLOT_AVAIL(s) ((s) != NULL && (s)->avail) const char *response_trans_headers[] = { "Content-Type", "Content-Language", "Content-Length", "Date", "Last-Modified", "Location", "Set-Cookie", "Set-Cookie2", "Servlet-Engine", "Status", "WWW-Authenticate" }; static const char *long_res_header_for_sc(int sc) { const char *rc = NULL; sc = sc & 0X00FF; if (sc <= SC_RES_HEADERS_NUM && sc > 0) { rc = response_trans_headers[sc - 1]; } return rc; } static const char *ajp_state_type[] = { JK_AJP_STATE_TEXT_IDLE, JK_AJP_STATE_TEXT_OK, JK_AJP_STATE_TEXT_ERROR, JK_AJP_STATE_TEXT_PROBE, "unknown", NULL }; static char ajp_cping_mode[] = { AJP_CPING_CONNECT_TEXT, AJP_CPING_PREPOST_TEXT, AJP_CPING_INTERVAL_TEXT, }; #define UNKNOWN_METHOD (-1) static int sc_for_req_method(const char *method, size_t len) { /* Note: the following code was generated by the "shilka" tool from the "cocom" parsing/compilation toolkit. It is an optimized lookup based on analysis of the input keywords. Postprocessing was done on the shilka output, but the basic structure and analysis is from there. Should new HTTP methods be added, then manual insertion into this code is fine, or simply re-running the shilka tool on the appropriate input. */ /* Note: it is also quite reasonable to just use our method_registry, but I'm assuming (probably incorrectly) we want more speed here (based on the optimizations the previous code was doing). */ switch (len) { case 3: switch (method[0]) { case 'A': return (method[1] == 'C' && method[2] == 'L' ? SC_M_ACL : UNKNOWN_METHOD); case 'P': return (method[1] == 'U' && method[2] == 'T' ? SC_M_PUT : UNKNOWN_METHOD); case 'G': return (method[1] == 'E' && method[2] == 'T' ? SC_M_GET : UNKNOWN_METHOD); default: return UNKNOWN_METHOD; } case 4: switch (method[0]) { case 'H': return (method[1] == 'E' && method[2] == 'A' && method[3] == 'D' ? SC_M_HEAD : UNKNOWN_METHOD); case 'P': return (method[1] == 'O' && method[2] == 'S' && method[3] == 'T' ? SC_M_POST : UNKNOWN_METHOD); case 'M': return (method[1] == 'O' && method[2] == 'V' && method[3] == 'E' ? SC_M_MOVE : UNKNOWN_METHOD); case 'L': return (method[1] == 'O' && method[2] == 'C' && method[3] == 'K' ? SC_M_LOCK : UNKNOWN_METHOD); case 'C': return (method[1] == 'O' && method[2] == 'P' && method[3] == 'Y' ? SC_M_COPY : UNKNOWN_METHOD); default: return UNKNOWN_METHOD; } case 5: switch (method[2]) { case 'R': return (memcmp(method, "MERGE", 5) == 0 ? SC_M_MERGE : UNKNOWN_METHOD); case 'C': return (memcmp(method, "MKCOL", 5) == 0 ? SC_M_MKCOL : UNKNOWN_METHOD); case 'B': return (memcmp(method, "LABEL", 5) == 0 ? SC_M_LABEL : UNKNOWN_METHOD); case 'A': return (memcmp(method, "TRACE", 5) == 0 ? SC_M_TRACE : UNKNOWN_METHOD); default: return UNKNOWN_METHOD; } case 6: switch (method[0]) { case 'U': switch (method[5]) { case 'K': return (memcmp(method, "UNLOCK", 6) == 0 ? SC_M_UNLOCK : UNKNOWN_METHOD); case 'E': return (memcmp(method, "UPDATE", 6) == 0 ? SC_M_UPDATE : UNKNOWN_METHOD); default: return UNKNOWN_METHOD; } case 'R': return (memcmp(method, "REPORT", 6) == 0 ? SC_M_REPORT : UNKNOWN_METHOD); case 'S': return (memcmp(method, "SEARCH", 6) == 0 ? SC_M_SEARCH : UNKNOWN_METHOD); case 'D': return (memcmp(method, "DELETE", 6) == 0 ? SC_M_DELETE : UNKNOWN_METHOD); default: return UNKNOWN_METHOD; } case 7: switch (method[1]) { case 'P': return (memcmp(method, "OPTIONS", 7) == 0 ? SC_M_OPTIONS : UNKNOWN_METHOD); case 'H': return (memcmp(method, "CHECKIN", 7) == 0 ? SC_M_CHECKIN : UNKNOWN_METHOD); default: return UNKNOWN_METHOD; } case 8: switch (method[0]) { case 'P': return (memcmp(method, "PROPFIND", 8) == 0 ? SC_M_PROPFIND : UNKNOWN_METHOD); case 'C': return (memcmp(method, "CHECKOUT", 8) == 0 ? SC_M_CHECKOUT : UNKNOWN_METHOD); default: return UNKNOWN_METHOD; } case 9: return (memcmp(method, "PROPPATCH", 9) == 0 ? SC_M_PROPPATCH : UNKNOWN_METHOD); case 10: switch (method[0]) { case 'U': return (memcmp(method, "UNCHECKOUT", 10) == 0 ? SC_M_UNCHECKOUT : UNKNOWN_METHOD); case 'M': return (memcmp(method, "MKACTIVITY", 10) == 0 ? SC_M_MKACTIVITY : UNKNOWN_METHOD); default: return UNKNOWN_METHOD; } case 11: return (memcmp(method, "MKWORKSPACE", 11) == 0 ? SC_M_MKWORKSPACE : UNKNOWN_METHOD); case 15: return (memcmp(method, "VERSION-CONTROL", 15) == 0 ? SC_M_VERSION_CONTROL : UNKNOWN_METHOD); case 16: return (memcmp(method, "BASELINE-CONTROL", 16) == 0 ? SC_M_BASELINE_CONTROL : UNKNOWN_METHOD); default: return UNKNOWN_METHOD; } /* NOTREACHED */ } static int sc_for_req_header(const char *header_name) { char header[16]; size_t len = strlen(header_name); const char *p = header_name; int i = 0; /* ACCEPT-LANGUAGE is the longest header * that is of interest. */ if (len < 4 || len > 15) return UNKNOWN_METHOD; while (*p) { header[i++] = toupper((unsigned char)*p); p++; } header[i] = '\0'; p = &header[1]; /* Always do memcmp including the final \0-termination character. */ switch (header[0]) { case 'A': if (memcmp(p, "CCEPT", 6) == 0) { if (!header[6]) return SC_ACCEPT; if (header[6] == '-') { p += 6; if (memcmp(p, "CHARSET", 8) == 0) return SC_ACCEPT_CHARSET; if (memcmp(p, "ENCODING", 9) == 0) return SC_ACCEPT_ENCODING; if (memcmp(p, "LANGUAGE", 9) == 0) return SC_ACCEPT_LANGUAGE; } return UNKNOWN_METHOD; } if (memcmp(p, "UTHORIZATION", 13) == 0) return SC_AUTHORIZATION; break; case 'C': if(memcmp(p, "OOKIE2", 7) == 0) return SC_COOKIE2; if (memcmp(p, "OOKIE", 6) == 0) return SC_COOKIE; if(memcmp(p, "ONNECTION", 10) == 0) return SC_CONNECTION; if(memcmp(p, "ONTENT-TYPE", 12) == 0) return SC_CONTENT_TYPE; if(memcmp(p, "ONTENT-LENGTH", 14) == 0) return SC_CONTENT_LENGTH; break; case 'H': if(memcmp(p, "OST", 4) == 0) return SC_HOST; break; case 'P': if(memcmp(p, "RAGMA", 6) == 0) return SC_PRAGMA; break; case 'R': if(memcmp(p, "EFERER", 7) == 0) return SC_REFERER; break; case 'U': if(memcmp(p, "SER-AGENT", 10) == 0) return SC_USER_AGENT; break; default: break;; } return UNKNOWN_METHOD; } /* Return the string representation of the worker state */ const char *jk_ajp_get_state(ajp_worker_t *aw, jk_logger_t *l) { return ajp_state_type[aw->s->state]; } /* Return the int representation of the worker state */ int jk_ajp_get_state_code(const char *v) { if (!v) return JK_AJP_STATE_DEF; if (*v == 'i' || *v == 'I' || *v == 'n' || *v == 'N' || *v == '0') return JK_AJP_STATE_IDLE; if (*v == 'o' || *v == 'O' || *v == '1') return JK_AJP_STATE_OK; if (*v == 'e' || *v == 'E' || *v == '4') return JK_AJP_STATE_ERROR; if (*v == 'p' || *v == 'P' || *v == '6') return JK_AJP_STATE_PROBE; return JK_AJP_STATE_DEF; } void jk_ajp_get_cping_text(int mode, char *buf) { int bit = 1; int log2 = 0; int pos = 0; while (bit <= mode && bit <= AJP_CPING_MAX) { if (mode & bit) { buf[pos] = ajp_cping_mode[log2]; pos +=1; } bit *= 2; log2 += 1; } buf[pos] = '\0'; } int jk_ajp_get_cping_mode(const char *m, int def) { int mv = 0; if (!m) return def; while (*m != '\0') { if (*m == AJP_CPING_CONNECT_TEXT || *m == tolower(AJP_CPING_CONNECT_TEXT)) mv |= AJP_CPING_CONNECT; if (*m == AJP_CPING_PREPOST_TEXT || *m == tolower(AJP_CPING_PREPOST_TEXT)) mv |= AJP_CPING_PREPOST; if (*m == AJP_CPING_INTERVAL_TEXT || *m == tolower(AJP_CPING_INTERVAL_TEXT)) mv |= AJP_CPING_INTERVAL; if (*m == AJP_CPING_ALL_TEXT || *m == tolower(AJP_CPING_ALL_TEXT)) { mv = AJP_CPING_CONNECT | AJP_CPING_PREPOST | AJP_CPING_INTERVAL; break; } m++; } if (mv) return mv; return def; } /* * Message structure * * AJPV13_REQUEST/AJPV14_REQUEST= request_prefix (1) (byte) method (byte) protocol (string) req_uri (string) remote_addr (string) remote_host (string) server_name (string) server_port (short) is_ssl (boolean) num_headers (short) num_headers*(req_header_name header_value) ?context (byte)(string) ?servlet_path (byte)(string) ?remote_user (byte)(string) ?auth_type (byte)(string) ?query_string (byte)(string) ?route (byte)(string) ?ssl_cert (byte)(string) ?ssl_cipher (byte)(string) ?ssl_session (byte)(string) ?ssl_key_size (byte)(int) via JkOptions +ForwardKeySize request_terminator (byte) ?body content_length*(var binary) */ static int ajp_marshal_into_msgb(jk_msg_buf_t *msg, jk_ws_service_t *s, jk_logger_t *l, ajp_endpoint_t * ae) { int method; unsigned int i; JK_TRACE_ENTER(l); if ((method = sc_for_req_method(s->method, strlen(s->method))) == UNKNOWN_METHOD) method = SC_M_JK_STORED; if (jk_b_append_byte(msg, JK_AJP13_FORWARD_REQUEST) || jk_b_append_byte(msg, (unsigned char)method) || jk_b_append_string(msg, s->protocol) || jk_b_append_string(msg, s->req_uri) || jk_b_append_string(msg, s->remote_addr) || jk_b_append_string(msg, s->remote_host) || jk_b_append_string(msg, s->server_name) || jk_b_append_int(msg, (unsigned short)s->server_port) || jk_b_append_byte(msg, (unsigned char)(s->is_ssl)) || jk_b_append_int(msg, (unsigned short)(s->num_headers))) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the message begining", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } for (i = 0; i < s->num_headers; i++) { int sc; if ((sc = sc_for_req_header(s->headers_names[i])) != UNKNOWN_METHOD) { if (jk_b_append_int(msg, (unsigned short)sc)) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the header code for '%s'", ae->worker->name, s->headers_names[i]); JK_TRACE_EXIT(l); return JK_FALSE; } } else { if (jk_b_append_string(msg, s->headers_names[i])) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the header name '%s'", ae->worker->name, s->headers_names[i]); JK_TRACE_EXIT(l); return JK_FALSE; } } if (jk_b_append_string(msg, s->headers_values[i])) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the header value for header '%s' of length %u", ae->worker->name, s->headers_names[i], strlen(s->headers_names[i])); JK_TRACE_EXIT(l); return JK_FALSE; } } if (s->secret) { if (jk_b_append_byte(msg, SC_A_SECRET) || jk_b_append_string(msg, s->secret)) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending secret", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } } if (s->remote_user) { if (jk_b_append_byte(msg, SC_A_REMOTE_USER) || jk_b_append_string(msg, s->remote_user)) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the remote user", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } } if (s->auth_type) { if (jk_b_append_byte(msg, SC_A_AUTH_TYPE) || jk_b_append_string(msg, s->auth_type)) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the auth type", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } } if (s->query_string) { if (jk_b_append_byte(msg, SC_A_QUERY_STRING) || #if defined(AS400) && !defined(AS400_UTF8) jk_b_append_asciistring(msg, s->query_string)) { #else jk_b_append_string(msg, s->query_string)) { #endif jk_log(l, JK_LOG_ERROR, "(%s) failed appending the query string of length %u", ae->worker->name, strlen(s->query_string)); JK_TRACE_EXIT(l); return JK_FALSE; } } if (s->route) { if (jk_b_append_byte(msg, SC_A_ROUTE) || jk_b_append_string(msg, s->route)) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the route", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } } if (s->ssl_cert_len) { if (jk_b_append_byte(msg, SC_A_SSL_CERT) || jk_b_append_string(msg, s->ssl_cert)) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the SSL certificates", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } } if (s->ssl_cipher) { if (jk_b_append_byte(msg, SC_A_SSL_CIPHER) || jk_b_append_string(msg, s->ssl_cipher)) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the SSL ciphers", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } } if (s->ssl_session) { if (jk_b_append_byte(msg, SC_A_SSL_SESSION) || jk_b_append_string(msg, s->ssl_session)) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the SSL session", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } } /* * ssl_key_size is required by Servlet 2.3 API * added support only in ajp14 mode * JFC removed: ae->proto == AJP14_PROTO */ if (s->ssl_key_size != -1) { if (jk_b_append_byte(msg, SC_A_SSL_KEY_SIZE) || jk_b_append_int(msg, (unsigned short)s->ssl_key_size)) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the SSL key size of length %d", ae->worker->name, s->ssl_key_size); JK_TRACE_EXIT(l); return JK_FALSE; } } /* If the method was unrecognized, encode it as an attribute */ if (method == SC_M_JK_STORED) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) unknown method %s", ae->worker->name, s->method); if (jk_b_append_byte(msg, SC_A_STORED_METHOD) || jk_b_append_string(msg, s->method)) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the request method", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } } /* Forward the SSL protocol name. * Modern Tomcat versions know how to retrieve * the protocol name from this attribute. */ if (s->ssl_protocol && *s->ssl_protocol) { if (jk_b_append_byte(msg, SC_A_REQ_ATTRIBUTE) || jk_b_append_string(msg, SC_A_SSL_PROTOCOL) || jk_b_append_string(msg, s->ssl_protocol)) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the ssl protocol name %s", ae->worker->name, s->ssl_protocol); JK_TRACE_EXIT(l); return JK_FALSE; } } /* Forward the remote port information, which was forgotten * from the builtin data of the AJP 13 protocol. * Since the servlet spec allows to retrieve it via getRemotePort(), * we provide the port to the Tomcat connector as a request * attribute. Modern Tomcat versions know how to retrieve * the remote port from this attribute. */ if (jk_b_append_byte(msg, SC_A_REQ_ATTRIBUTE) || jk_b_append_string(msg, SC_A_REQ_REMOTE_PORT) || jk_b_append_string(msg, s->remote_port)) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the remote port %s", ae->worker->name, s->remote_port); JK_TRACE_EXIT(l); return JK_FALSE; } /* Forward the local ip address information, which was forgotten * from the builtin data of the AJP 13 protocol. * Since the servlet spec allows to retrieve it via getLocalAddr(), * we provide the address to the Tomcat connector as a request * attribute. Modern Tomcat versions know how to retrieve * the local address from this attribute. */ if (jk_b_append_byte(msg, SC_A_REQ_ATTRIBUTE) || jk_b_append_string(msg, SC_A_REQ_LOCAL_ADDR) || jk_b_append_string(msg, s->local_addr)) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the local address %s", ae->worker->name, s->local_addr); JK_TRACE_EXIT(l); return JK_FALSE; } /* Forward activation information from the load balancer. * It can be used by the backend to deny access by requests, * which come with a session id but for an invalid session. * Such requests get forwarded to backends even if they * are disabled" in the load balancer, because the balancer * does not know, which sessions are valid. * If the backend can check, that is was "disabled" it can * delete the session cookie and respond with a self-referential * redirect. The new request will then be balanced to some * other node that is not disabled. */ if (jk_b_append_byte(msg, SC_A_REQ_ATTRIBUTE) || jk_b_append_string(msg, SC_A_JK_LB_ACTIVATION) || jk_b_append_string(msg, s->activation)) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the activation state %s", ae->worker->name, s->activation); JK_TRACE_EXIT(l); return JK_FALSE; } if (s->num_attributes > 0) { for (i = 0; i < s->num_attributes; i++) { if (jk_b_append_byte(msg, SC_A_REQ_ATTRIBUTE) || jk_b_append_string(msg, s->attributes_names[i]) || jk_b_append_string(msg, s->attributes_values[i])) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending attribute %s=%s", ae->worker->name, s->attributes_names[i], s->attributes_values[i]); JK_TRACE_EXIT(l); return JK_FALSE; } } } if (jk_b_append_byte(msg, SC_A_ARE_DONE)) { jk_log(l, JK_LOG_ERROR, "(%s) failed appending the message end", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) ajp marshaling done", ae->worker->name); JK_TRACE_EXIT(l); return JK_TRUE; } /* AJPV13_RESPONSE/AJPV14_RESPONSE:= response_prefix (2) status (short) status_msg (short) num_headers (short) num_headers*(res_header_name header_value) *body_chunk terminator boolean req_header_name := sc_req_header_name | (string) res_header_name := sc_res_header_name | (string) header_value := (string) body_chunk := length (short) body length*(var binary) */ static int ajp_unmarshal_response(jk_msg_buf_t *msg, jk_res_data_t * d, ajp_endpoint_t * ae, jk_logger_t *l) { jk_pool_t *p = &ae->pool; JK_TRACE_ENTER(l); d->status = jk_b_get_int(msg); if (!d->status) { jk_log(l, JK_LOG_ERROR, "(%s) NULL status", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } d->msg = jk_b_get_string(msg); if (d->msg) { #if (defined(AS400) && !defined(AS400_UTF8)) || defined(_OSD_POSIX) jk_xlate_from_ascii(d->msg, strlen(d->msg)); #endif } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) status = %d", ae->worker->name, d->status); d->num_headers = jk_b_get_int(msg); d->header_names = d->header_values = NULL; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Number of headers is = %d", d->num_headers); if (d->num_headers) { d->header_names = jk_pool_alloc(p, sizeof(char *) * d->num_headers); d->header_values = jk_pool_alloc(p, sizeof(char *) * d->num_headers); if (d->header_names && d->header_values) { unsigned int i; for (i = 0; i < d->num_headers; i++) { unsigned short name = jk_b_pget_int(msg, msg->pos); if ((name & 0XFF00) == 0XA000) { jk_b_get_int(msg); name = name & 0X00FF; if (name <= SC_RES_HEADERS_NUM) { d->header_names[i] = (char *)long_res_header_for_sc(name); } else { jk_log(l, JK_LOG_ERROR, "(%s) No such sc (%d)", ae->worker->name, name); JK_TRACE_EXIT(l); return JK_FALSE; } } else { d->header_names[i] = jk_b_get_string(msg); if (!d->header_names[i]) { jk_log(l, JK_LOG_ERROR, "(%s) NULL header name", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } #if (defined(AS400) && !defined(AS400_UTF8)) || defined(_OSD_POSIX) jk_xlate_from_ascii(d->header_names[i], strlen(d->header_names[i])); #endif } d->header_values[i] = jk_b_get_string(msg); if (!d->header_values[i]) { jk_log(l, JK_LOG_ERROR, "(%s) NULL header value", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } #if (defined(AS400) && !defined(AS400_UTF8)) || defined(_OSD_POSIX) jk_xlate_from_ascii(d->header_values[i], strlen(d->header_values[i])); #endif if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) Header[%d] [%s] = [%s]", ae->worker->name, i, d->header_names[i], d->header_values[i]); } } } JK_TRACE_EXIT(l); return JK_TRUE; } /* * Abort endpoint use */ static void ajp_abort_endpoint(ajp_endpoint_t * ae, int shutdown, jk_logger_t *l) { JK_TRACE_ENTER(l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) aborting endpoint with socket %d", ae->worker->name, ae->sd); if (IS_VALID_SOCKET(ae->sd)) { if (shutdown == JK_TRUE) { if (ae->hard_close) { /* Force unclean connection close to communicate client write errors * back to Tomcat by aborting AJP response writes. */ jk_close_socket(ae->sd, l); } else { jk_shutdown_socket(ae->sd, l); } } JK_ATOMIC_DECREMENT(&(ae->worker->s->connected)); ae->sd = JK_INVALID_SOCKET; } ae->last_op = JK_AJP13_END_RESPONSE; JK_TRACE_EXIT(l); } /* * Reset the endpoint (clean buf and close socket) */ static void ajp_reset_endpoint(ajp_endpoint_t * ae, jk_logger_t *l) { JK_TRACE_ENTER(l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) resetting endpoint with socket %d%s", ae->worker->name, ae->sd, ae->reuse? "" : " (socket shutdown)"); if (!ae->reuse) { ajp_abort_endpoint(ae, JK_TRUE, l); } jk_reset_pool(&(ae->pool)); JK_TRACE_EXIT(l); } /* * Close the endpoint (close pool and close socket) */ void ajp_close_endpoint(ajp_endpoint_t * ae, jk_logger_t *l) { JK_TRACE_ENTER(l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) closing endpoint with socket %d%s", ae->worker->name, ae->sd, ae->reuse ? "" : " (socket shutdown)"); if (IS_VALID_SOCKET(ae->sd)) { jk_shutdown_socket(ae->sd, l); JK_ATOMIC_DECREMENT(&(ae->worker->s->connected)); ae->sd = JK_INVALID_SOCKET; } jk_close_pool(&(ae->pool)); free(ae); JK_TRACE_EXIT(l); } /** Steal a connection from an idle cache endpoint * @param ae endpoint that needs a new connection * @param l logger * @return JK_FALSE: failure * JK_TRUE: success * @remark Always closes old socket endpoint */ static int ajp_next_connection(ajp_endpoint_t *ae, jk_logger_t *l) { unsigned int i; int ret = JK_FALSE; ajp_worker_t *aw = ae->worker; JK_TRACE_ENTER(l); /* Close previous socket */ if (IS_VALID_SOCKET(ae->sd)) { jk_shutdown_socket(ae->sd, l); JK_ATOMIC_DECREMENT(&(ae->worker->s->connected)); ae->sd = JK_INVALID_SOCKET; } JK_ENTER_CS(&aw->cs); for (i = 0; i < aw->ep_cache_sz; i++) { /* Find cache slot with usable socket */ if (IS_SLOT_AVAIL(aw->ep_cache[i]) && IS_VALID_SOCKET(aw->ep_cache[i]->sd)) { ae->sd = aw->ep_cache[i]->sd; aw->ep_cache[i]->sd = JK_INVALID_SOCKET; break; } } JK_LEAVE_CS(&aw->cs); if (IS_VALID_SOCKET(ae->sd)) { ret = JK_TRUE; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) Will try pooled connection socket %d from slot %d", ae->worker->name, ae->sd, i); } JK_TRACE_EXIT(l); return ret; } /** Handle the cping/cpong query * @param ae endpoint * @param timeout wait timeout in milliseconds * @param l logger * @return JK_FALSE: failure * JK_TRUE: success * @remark Always closes socket in case of * a socket error */ static int ajp_handle_cping_cpong(ajp_endpoint_t * ae, int timeout, jk_logger_t *l) { int i; int cmd; jk_msg_buf_t *msg; JK_TRACE_ENTER(l); ae->last_errno = 0; msg = jk_b_new(&ae->pool); if (!msg) { jk_log(l, JK_LOG_ERROR, "(%s) Failed allocating AJP message", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } if (jk_b_set_buffer_size(msg, 16)) { jk_log(l, JK_LOG_ERROR, "(%s) Failed allocating AJP message buffer", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } jk_b_reset(msg); jk_b_append_byte(msg, AJP13_CPING_REQUEST); /* Send CPing query */ if (ajp_connection_tcp_send_message(ae, msg, l) != JK_TRUE) { jk_log(l, JK_LOG_INFO, "(%s) can't send cping query", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } for (i = 0; i < 2; i++) { /* wait for Pong reply for timeout milliseconds */ if (jk_is_input_event(ae->sd, timeout, l) == JK_FALSE) { ae->last_errno = errno; jk_log(l, JK_LOG_INFO, "(%s) timeout in reply cpong after %d ms. " "Socket = %d (event=%d)", ae->worker->name, timeout, ae->sd, errno); /* We can't trust this connection any more. */ ajp_abort_endpoint(ae, JK_TRUE, l); JK_TRACE_EXIT(l); return JK_FALSE; } /* Read and check for Pong reply */ if (ajp_connection_tcp_get_message(ae, msg, l) != JK_TRUE) { jk_log(l, JK_LOG_INFO, "(%s) awaited reply cpong, not received", ae->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } if ((cmd = jk_b_get_byte(msg)) != AJP13_CPONG_REPLY) { /* If the respose was not CPONG it means that * the previous response was not consumed by the * client but the AJP messages was already in * the network buffer. * silently drop this single extra packet instead * recycling the connection */ if (i || ae->last_op == JK_AJP13_END_RESPONSE || cmd < JK_AJP13_SEND_BODY_CHUNK || cmd > AJP13_CPONG_REPLY) { jk_log(l, JK_LOG_WARNING, "(%s) awaited reply cpong, received %d instead. " "Closing connection", ae->worker->name, cmd); /* We can't trust this connection any more. */ ajp_abort_endpoint(ae, JK_TRUE, l); JK_TRACE_EXIT(l); return JK_FALSE; } else { jk_log(l, JK_LOG_INFO, "(%s) awaited reply cpong, received %d instead. " "Retrying next packet", ae->worker->name, cmd); } } else { ae->last_op = AJP13_CPONG_REPLY; /* We have received Pong reply */ break; } } JK_TRACE_EXIT(l); return JK_TRUE; } /** Connect an endpoint to a backend * @param ae endpoint * @param l logger * @return JK_FALSE: failure * JK_TRUE: success * @remark Always closes socket in case of * a socket error * @remark Cares about ae->last_errno */ int ajp_connect_to_endpoint(ajp_endpoint_t * ae, jk_logger_t *l) { char buf[64]; int rc = JK_TRUE; int connected; JK_TRACE_ENTER(l); ae->last_errno = 0; ae->sd = jk_open_socket(&ae->worker->worker_inet_addr, ae->worker->worker_source_inet_addr.ipaddr_ptr != NULL ? &ae->worker->worker_source_inet_addr : NULL, ae->worker->keepalive, ae->worker->socket_timeout, ae->worker->socket_connect_timeout, ae->worker->socket_buf, l); if (!IS_VALID_SOCKET(ae->sd)) { ae->last_errno = errno; jk_log(l, JK_LOG_INFO, "(%s) Failed opening socket to (%s) (errno=%d)", ae->worker->name, jk_dump_hinfo(&ae->worker->worker_inet_addr, buf, sizeof(buf)), ae->last_errno); JK_TRACE_EXIT(l); return JK_FALSE; } connected = JK_ATOMIC_INCREMENT(&(ae->worker->s->connected)); /* Update maximum number of connections */ if (connected > ae->worker->s->max_connected) ae->worker->s->max_connected = connected; /* set last_access only if needed */ if (ae->worker->cache_timeout > 0) ae->last_access = time(NULL); /* Check if we must execute a logon after the physical connect * XXX: Not sure, if we really should do logon before cping/cpong * and if no cping/cpong is allowed before or after logon. */ if (ae->worker->logon != NULL) { rc = ae->worker->logon(ae, l); if (rc == JK_FALSE) { jk_log(l, JK_LOG_ERROR, "(%s) ajp14 worker logon to the backend server failed", ae->worker->name); /* Close the socket if unable to logon */ ajp_abort_endpoint(ae, JK_TRUE, l); } } /* XXX: Should we send a cping also after logon to validate the connection? */ else if (ae->worker->connect_timeout > 0) { rc = ajp_handle_cping_cpong(ae, ae->worker->connect_timeout, l); if (rc == JK_FALSE) jk_log(l, JK_LOG_ERROR, "(%s) cping/cpong after connecting to the backend server failed " "(errno=%d)", ae->worker->name, ae->last_errno); } JK_TRACE_EXIT(l); return rc; } /* Syncing config values from shm */ void jk_ajp_pull(ajp_worker_t * aw, int locked, jk_logger_t *l) { int address_change = JK_FALSE; int port = 0; char host[JK_SHM_STR_SIZ]; jk_sockaddr_t inet_addr; JK_TRACE_ENTER(l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "syncing mem for ajp worker '%s' from shm (%d->%d) [%d->%d]", aw->name, aw->sequence, aw->s->h.sequence, aw->addr_sequence, aw->s->addr_sequence); if (locked == JK_FALSE) jk_shm_lock(); aw->cache_timeout = aw->s->cache_timeout; aw->connect_timeout = aw->s->connect_timeout; aw->ping_timeout = aw->s->ping_timeout; aw->reply_timeout = aw->s->reply_timeout; aw->prepost_timeout = aw->s->prepost_timeout; aw->recovery_opts = aw->s->recovery_opts; aw->retries = aw->s->retries; aw->retry_interval = aw->s->retry_interval; aw->busy_limit = aw->s->busy_limit; aw->max_packet_size = aw->s->max_packet_size; aw->sequence = aw->s->h.sequence; if (aw->addr_sequence != aw->s->addr_sequence) { address_change = JK_TRUE; aw->addr_sequence = aw->s->addr_sequence; strncpy(host, aw->s->host, JK_SHM_STR_SIZ); port = aw->s->port; } if (locked == JK_FALSE) jk_shm_unlock(); if (address_change == JK_TRUE && port != 0) { aw->port = port; strncpy(aw->host, host, JK_SHM_STR_SIZ); if (!jk_resolve(host, port, &inet_addr, aw->worker.we->pool, aw->prefer_ipv6, l)) { jk_log(l, JK_LOG_ERROR, "Failed resolving address '%s:%d' for worker '%s'.", host, port, aw->name); /* Disable contact */ aw->port = 0; } else { unsigned int i; JK_ENTER_CS(&aw->cs); for (i = 0; i < aw->ep_cache_sz; i++) { /* Close all avail connections in the cache * Note that this won't change active connections. */ if (IS_SLOT_AVAIL(aw->ep_cache[i]) && IS_VALID_SOCKET(aw->ep_cache[i]->sd)) { jk_sock_t sd = aw->ep_cache[i]->sd; aw->ep_cache[i]->sd = JK_INVALID_SOCKET; aw->ep_cache[i]->addr_sequence = aw->addr_sequence; jk_shutdown_socket(sd, l); JK_ATOMIC_DECREMENT(&(aw->s->connected)); } } jk_clone_sockaddr(&(aw->worker_inet_addr), &inet_addr); JK_LEAVE_CS(&aw->cs); } } JK_TRACE_EXIT(l); } /* Syncing config values to shm */ void jk_ajp_push(ajp_worker_t * aw, int locked, jk_logger_t *l) { int address_change = JK_FALSE; JK_TRACE_ENTER(l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "syncing shm for ajp worker '%s' from mem (%d->%d) [%d->%d]", aw->name, aw->s->h.sequence, aw->sequence, aw->s->addr_sequence, aw->addr_sequence); if (locked == JK_FALSE) jk_shm_lock(); aw->s->cache_timeout = aw->cache_timeout; aw->s->connect_timeout = aw->connect_timeout; aw->s->ping_timeout = aw->ping_timeout; aw->s->reply_timeout = aw->reply_timeout; aw->s->prepost_timeout = aw->prepost_timeout; aw->s->recovery_opts = aw->recovery_opts; aw->s->retries = aw->retries; aw->s->retry_interval = aw->retry_interval; aw->s->busy_limit = aw->busy_limit; aw->s->max_packet_size = aw->max_packet_size; /* Force squence update on push */ ++aw->s->h.sequence; aw->sequence = aw->s->h.sequence; if (aw->s->addr_sequence != aw->addr_sequence) { ++aw->s->addr_sequence; address_change = JK_TRUE; strncpy(aw->s->host, aw->host, JK_SHM_STR_SIZ); aw->s->port = aw->port; aw->addr_sequence = aw->s->addr_sequence; } if (locked == JK_FALSE) jk_shm_unlock(); if (address_change == JK_TRUE) { unsigned int i; JK_ENTER_CS(&aw->cs); for (i = 0; i < aw->ep_cache_sz; i++) { /* Close all connections in the cache */ if (IS_SLOT_AVAIL(aw->ep_cache[i]) && IS_VALID_SOCKET(aw->ep_cache[i]->sd)) { jk_sock_t sd = aw->ep_cache[i]->sd; aw->ep_cache[i]->sd = JK_INVALID_SOCKET; aw->ep_cache[i]->addr_sequence = aw->addr_sequence; jk_shutdown_socket(sd, l); JK_ATOMIC_DECREMENT(&(aw->s->connected)); } } JK_LEAVE_CS(&aw->cs); } JK_TRACE_EXIT(l); } /** Send a message to an endpoint, using corresponding PROTO HEADER * @param ae endpoint * @param msg message to send * @param l logger * @return JK_FATAL_ERROR: endpoint contains unknown protocol * JK_FALSE: other failure * JK_TRUE: success * @remark Always closes socket in case of * a socket error, or JK_FATAL_ERROR * @remark Cares about ae->last_errno */ int ajp_connection_tcp_send_message(ajp_endpoint_t * ae, jk_msg_buf_t *msg, jk_logger_t *l) { int rc; JK_TRACE_ENTER(l); ae->last_errno = 0; if (ae->proto == AJP13_PROTO) { jk_b_end(msg, AJP13_WS_HEADER); if (JK_IS_DEBUG_LEVEL(l)) jk_dump_buff(l, JK_LOG_DEBUG, "sending to ajp13", msg); } else if (ae->proto == AJP14_PROTO) { jk_b_end(msg, AJP14_WS_HEADER); if (JK_IS_DEBUG_LEVEL(l)) jk_dump_buff(l, JK_LOG_DEBUG, "sending to ajp14", msg); } else { jk_log(l, JK_LOG_ERROR, "(%s) unknown protocol %d, supported are AJP13/AJP14", ae->worker->name, ae->proto); /* We've got a protocol error. * We can't trust this connection any more, * because we might have send already parts of the request. */ ajp_abort_endpoint(ae, JK_TRUE, l); JK_TRACE_EXIT(l); return JK_FATAL_ERROR; } /* This is the only place in this function where we use the socket. * If sendfull gets an error, it implicitely closes the socket. * So any socket error inside ajp_connection_tcp_send_message * results in a socket close and invalidated endpoint connection. */ if ((rc = jk_tcp_socket_sendfull(ae->sd, msg->buf, msg->len, l)) > 0) { ae->endpoint.wr += (jk_uint64_t)rc; JK_TRACE_EXIT(l); return JK_TRUE; } ae->last_errno = errno; jk_log(l, JK_LOG_INFO, "(%s) sendfull for socket %d returned %d (errno=%d)", ae->worker->name, ae->sd, rc, ae->last_errno); ajp_abort_endpoint(ae, JK_FALSE, l); JK_TRACE_EXIT(l); return JK_FALSE; } /** Receive a message from an endpoint, checking PROTO HEADER * @param ae endpoint * @param msg message to send * @param l logger * @return JK_TRUE: success * JK_FALSE: could not read the AJP packet header * JK_AJP_PROTOCOL_ERROR: failure after reading * the AJP packet header * @remark Always closes socket in case of * a socket error * @remark Cares about ae->last_errno */ int ajp_connection_tcp_get_message(ajp_endpoint_t * ae, jk_msg_buf_t *msg, jk_logger_t *l) { unsigned char head[AJP_HEADER_LEN]; int rc; int msglen; unsigned int header; char buf[64]; JK_TRACE_ENTER(l); ae->last_errno = 0; /* If recvfull gets an error, it implicitely closes the socket. * We will invalidate the endpoint connection. */ rc = jk_tcp_socket_recvfull(ae->sd, head, AJP_HEADER_LEN, l); /* If the return code is not negative * then we always get back the correct number of bytes. */ if (rc < 0) { if (rc == JK_SOCKET_EOF) { ae->last_errno = EPIPE; jk_log(l, JK_LOG_INFO, "(%s) can't receive the response header message from tomcat, " "tomcat (%s) has forced a connection close for socket %d", ae->worker->name, jk_dump_hinfo(&ae->worker->worker_inet_addr, buf, sizeof(buf)), ae->sd); } else { ae->last_errno = -rc; jk_log(l, JK_LOG_INFO, "(%s) can't receive the response header message from tomcat, " "network problems or tomcat (%s) is down (errno=%d)", ae->worker->name, jk_dump_hinfo(&ae->worker->worker_inet_addr, buf, sizeof(buf)), ae->last_errno); } ajp_abort_endpoint(ae, JK_FALSE, l); JK_TRACE_EXIT(l); return JK_FALSE; } ae->endpoint.rd += (jk_uint64_t)rc; header = ((unsigned int)head[0] << 8) | head[1]; if (ae->proto == AJP13_PROTO) { if (header != AJP13_SW_HEADER) { if (header == AJP14_SW_HEADER) { jk_log(l, JK_LOG_ERROR, "(%s) received AJP14 reply on an AJP13 connection from %s", ae->worker->name, jk_dump_hinfo(&ae->worker->worker_inet_addr, buf, sizeof(buf))); } else { jk_log(l, JK_LOG_ERROR, "(%s) wrong message format 0x%04x from %s", ae->worker->name, header, jk_dump_hinfo(&ae->worker->worker_inet_addr, buf, sizeof(buf))); } /* We've got a protocol error. * We can't trust this connection any more. */ ajp_abort_endpoint(ae, JK_TRUE, l); JK_TRACE_EXIT(l); return JK_AJP_PROTOCOL_ERROR; } } else if (ae->proto == AJP14_PROTO) { if (header != AJP14_SW_HEADER) { if (header == AJP13_SW_HEADER) { jk_log(l, JK_LOG_ERROR, "(%s) received AJP13 reply on an AJP14 connection from %s", ae->worker->name, jk_dump_hinfo(&ae->worker->worker_inet_addr, buf, sizeof(buf))); } else { jk_log(l, JK_LOG_ERROR, "(%s) wrong message format 0x%04x from %s", ae->worker->name, header, jk_dump_hinfo(&ae->worker->worker_inet_addr, buf, sizeof(buf))); } /* We've got a protocol error. * We can't trust this connection any more. */ ajp_abort_endpoint(ae, JK_TRUE, l); JK_TRACE_EXIT(l); return JK_AJP_PROTOCOL_ERROR; } } msglen = ((head[2] & 0xff) << 8); msglen += (head[3] & 0xFF); if (msglen > msg->maxlen) { jk_log(l, JK_LOG_ERROR, "(%s) wrong message size %d %d from %s", ae->worker->name, msglen, msg->maxlen, jk_dump_hinfo(&ae->worker->worker_inet_addr, buf, sizeof(buf))); /* We've got a protocol error. * We can't trust this connection any more. */ ajp_abort_endpoint(ae, JK_TRUE, l); JK_TRACE_EXIT(l); return JK_AJP_PROTOCOL_ERROR; } msg->len = msglen; msg->pos = 0; /* If recvfull gets an error, it implicitely closes the socket. * We will invalidate the endpoint connection. */ rc = jk_tcp_socket_recvfull(ae->sd, msg->buf, msglen, l); /* If the return code is not negative * then we always get back the correct number of bytes. */ if (rc < 0) { if (rc == JK_SOCKET_EOF) { ae->last_errno = EPIPE; jk_log(l, JK_LOG_ERROR, "(%s) can't receive the response body message from tomcat, " "tomcat (%s) has forced a connection close for socket %d", ae->worker->name, jk_dump_hinfo(&ae->worker->worker_inet_addr, buf, sizeof(buf)), ae->sd); } else { ae->last_errno = -rc; jk_log(l, JK_LOG_ERROR, "(%s) can't receive the response body message from tomcat, " "network problems or tomcat (%s) is down (errno=%d)", ae->worker->name, jk_dump_hinfo(&ae->worker->worker_inet_addr, buf, sizeof(buf)), ae->last_errno); } ajp_abort_endpoint(ae, JK_FALSE, l); JK_TRACE_EXIT(l); /* Although we have a connection, this is effectively a protocol error. * We received the AJP header packet, but not the packet payload */ return JK_AJP_PROTOCOL_ERROR; } ae->endpoint.rd += (jk_uint64_t)rc; if (JK_IS_DEBUG_LEVEL(l)) { if (ae->proto == AJP13_PROTO) jk_dump_buff(l, JK_LOG_DEBUG, "received from ajp13", msg); else if (ae->proto == AJP14_PROTO) jk_dump_buff(l, JK_LOG_DEBUG, "received from ajp14", msg); } JK_TRACE_EXIT(l); return JK_TRUE; } /* * Read all the data from the socket. * * Socket API doesn't guaranty that all the data will be kept in a * single read, so we must loop until all awaited data is received */ static int ajp_read_fully_from_server(jk_ws_service_t *s, jk_logger_t *l, unsigned char *buf, unsigned int len) { unsigned int rdlen = 0; unsigned int padded_len = len; JK_TRACE_ENTER(l); if (s->is_chunked && s->no_more_chunks) { JK_TRACE_EXIT(l); return 0; } if (s->is_chunked) { /* Corner case: buf must be large enough to hold next * chunk size (if we're on or near a chunk border). * Pad the length to a reasonable value, otherwise the * read fails and the remaining chunks are tossed. */ padded_len = (len < CHUNK_BUFFER_PAD) ? len : len - CHUNK_BUFFER_PAD; } while (rdlen < padded_len) { unsigned int this_time = 0; if (!s->read(s, buf + rdlen, len - rdlen, &this_time)) { /* Remote Client read failed. */ JK_TRACE_EXIT(l); return JK_CLIENT_RD_ERROR; } if (0 == this_time) { if (s->is_chunked) { s->no_more_chunks = 1; /* read no more */ } break; } rdlen += this_time; } JK_TRACE_EXIT(l); return (int)rdlen; } /* * Read data from AJP13/AJP14 protocol * Returns -1 on error, else number of bytes read */ static int ajp_read_into_msg_buff(ajp_endpoint_t * ae, jk_ws_service_t *r, jk_msg_buf_t *msg, int len, jk_logger_t *l) { unsigned char *read_buf = msg->buf; int maxlen; JK_TRACE_ENTER(l); jk_b_reset(msg); read_buf += AJP_HEADER_LEN; /* leave some space for the buffer headers */ read_buf += AJP_HEADER_SZ_LEN; /* leave some space for the read length */ maxlen = ae->worker->max_packet_size - AJP_HEADER_LEN - AJP_HEADER_SZ_LEN; /* Pick the max size since we don't know the content_length */ if (r->is_chunked && ae->left_bytes_to_send == 0) { len = maxlen; } else { if ((jk_uint64_t)maxlen > ae->left_bytes_to_send) { maxlen = (int)ae->left_bytes_to_send; } if (len < 0 || len > maxlen) { len = maxlen; } } if ((len = ajp_read_fully_from_server(r, l, read_buf, len)) < 0) { jk_log(l, JK_LOG_INFO, "(%s) receiving data from client failed. " "Connection aborted or network problems", ae->worker->name); JK_TRACE_EXIT(l); return JK_CLIENT_RD_ERROR; } if (!r->is_chunked) { ae->left_bytes_to_send -= len; } if (len > 0) { /* Recipient recognizes empty packet as end of stream, not * an empty body packet */ if (0 != jk_b_append_int(msg, (unsigned short)len)) { jk_log(l, JK_LOG_INFO, "(%s) Failed appending message length", ae->worker->name); JK_TRACE_EXIT(l); return JK_CLIENT_RD_ERROR; } } msg->len += len; JK_TRACE_EXIT(l); return len; } /* * send request to Tomcat via Ajp13 * - first try to find reuseable socket * - if no such available, try to connect * - send request, but send must be seen as asynchronous, * since send() call will return noerror about 95% of time * Hopefully we'll get more information on next read. * * nb: op->request is the original request msg buffer * op->reply is the reply msg buffer which could be scratched * * Return values of ajp_send_request() function: * return value op->recoverable reason * JK_FATAL_ERROR JK_FALSE ajp_connection_tcp_send_message() returns JK_FATAL_ERROR * Endpoint belongs to unknown protocol. * JK_FATAL_ERROR JK_TRUE ajp_connection_tcp_send_message() returns JK_FALSE * Sending request or request body in jk_tcp_socket_sendfull() returns with error. * JK_FATAL_ERROR JK_TRUE Could not connect to backend * JK_CLIENT_RD_ERROR JK_FALSE Error during reading parts of POST body from client * JK_TRUE JK_TRUE All other cases (OK) */ static int ajp_send_request(jk_endpoint_t *e, jk_ws_service_t *s, jk_logger_t *l, ajp_endpoint_t * ae, ajp_operation_t * op) { int err_conn = 0; int err_cping = 0; int err_send = 0; int rc; int postlen; JK_TRACE_ENTER(l); ae->last_errno = 0; /* Up to now, we can recover */ op->recoverable = JK_TRUE; /* Check if the previous request really ended */ if (ae->last_op != JK_AJP13_END_RESPONSE && ae->last_op != AJP13_CPONG_REPLY) { jk_log(l, JK_LOG_INFO, "(%s) did not receive END_RESPONSE, " "closing socket %d", ae->worker->name, ae->sd); ajp_abort_endpoint(ae, JK_TRUE, l); } /* First try to check open connections... */ while (IS_VALID_SOCKET(ae->sd)) { int err = JK_FALSE; if (jk_is_socket_connected(ae->sd, l) == JK_FALSE) { ae->last_errno = errno; jk_log(l, JK_LOG_DEBUG, "(%s) failed sending request, " "socket %d is not connected any more (errno=%d)", ae->worker->name, ae->sd, ae->last_errno); ajp_abort_endpoint(ae, JK_FALSE, l); err = JK_TRUE; err_conn++; } if (ae->worker->prepost_timeout > 0 && !err) { /* handle cping/cpong if prepost_timeout is set * If the socket is disconnected no need to handle * the cping/cpong */ if (ajp_handle_cping_cpong(ae, ae->worker->prepost_timeout, l) == JK_FALSE) { jk_log(l, JK_LOG_INFO, "(%s) failed sending request, " "socket %d prepost cping/cpong failure (errno=%d)", ae->worker->name, ae->sd, ae->last_errno); /* XXX: Is there any reason to try other * connections to the node if one of them fails * the cping/cpong heartbeat? * Tomcat can be either too busy or simply dead, so * there is a chance that all other connections would * fail as well. */ err = JK_TRUE; err_cping++; } } /* We've got a connected socket and the optional * cping/cpong worked, so let's send the request now. */ if (err == JK_FALSE) { rc = ajp_connection_tcp_send_message(ae, op->request, l); /* If this worked, we can break out of the loop * and proceed with the request. */ if (rc == JK_TRUE) { ae->last_op = JK_AJP13_FORWARD_REQUEST; break; } /* Error during sending the request. */ err_send++; if (rc == JK_FATAL_ERROR) op->recoverable = JK_FALSE; jk_log(l, JK_LOG_INFO, "(%s) failed sending request (%srecoverable) " "(errno=%d)", ae->worker->name, op->recoverable ? "" : "un", ae->last_errno); JK_TRACE_EXIT(l); return JK_FATAL_ERROR; } /* If we got an error or can't send data, then try to steal another pooled * connection and try again. If we are not successful, break out of this * loop and try to open a new connection after the loop. */ if (ajp_next_connection(ae, l) == JK_FALSE) break; } /* If we failed to reuse a connection, try to reconnect. */ if (!IS_VALID_SOCKET(ae->sd)) { /* Could not steal any connection from an endpoint - backend * is disconnected or all connections are in use */ if (err_conn + err_cping + err_send > 0) if (err_cping + err_send > 0) jk_log(l, JK_LOG_INFO, "(%s) no usable connection found, will create a new one, " "detected by connect check (%d), cping (%d), send (%d).", ae->worker->name, err_conn, err_cping, err_send); else jk_log(l, JK_LOG_DEBUG, "(%s) no usable connection found, will create a new one, " "detected by connect check (%d), cping (%d), send (%d).", ae->worker->name, err_conn, err_cping, err_send); else if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) no usable connection found, will create a new one.", ae->worker->name); /* Connect to the backend. */ if (ajp_connect_to_endpoint(ae, l) != JK_TRUE) { jk_log(l, JK_LOG_ERROR, "(%s) connecting to backend failed. Tomcat is probably not started " "or is listening on the wrong port (errno=%d)", ae->worker->name, ae->last_errno); JK_TRACE_EXIT(l); return JK_FATAL_ERROR; } if (ae->worker->connect_timeout <= 0 && ae->worker->prepost_timeout > 0) { /* handle cping/cpong if prepost_timeout is set * and we didn't already do a connect cping/cpong. */ if (ajp_handle_cping_cpong(ae, ae->worker->prepost_timeout, l) == JK_FALSE) { jk_log(l, JK_LOG_INFO, "(%s) failed sending request, " "socket %d prepost cping/cpong failure (errno=%d)", ae->worker->name, ae->sd, ae->last_errno); JK_TRACE_EXIT(l); return JK_FATAL_ERROR; } } /* We've got a connected socket and the optional * cping/cpong worked, so let's send the request now. */ rc = ajp_connection_tcp_send_message(ae, op->request, l); /* Error during sending the request. */ if (rc != JK_TRUE) { if (rc == JK_FATAL_ERROR) op->recoverable = JK_FALSE; jk_log(l, JK_LOG_ERROR, "(%s) failed sending request on a fresh connection (%srecoverable), " "socket %d (errno=%d)", ae->worker->name, op->recoverable ? "" : "un", ae->sd, ae->last_errno); JK_TRACE_EXIT(l); return JK_FATAL_ERROR; } ae->last_op = JK_AJP13_FORWARD_REQUEST; } else if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) Statistics about invalid connections: " "connect check (%d), cping (%d), send (%d)", ae->worker->name, err_conn, err_cping, err_send); /* * From now on an error means that we have an internal server error * or Tomcat crashed. */ if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) request body to send %" JK_UINT64_T_FMT " - request body to resend %d", ae->worker->name, ae->left_bytes_to_send, op->post->len > AJP_HEADER_LEN ? op->post->len - AJP_HEADER_LEN : 0); /* * POST recovery job is done here and will work when data to * POST are less than 8k, since it's the maximum size of op-post buffer. * We send here the first part of data which was sent previously to the * remote Tomcat * * Did we have something to resend (ie the op-post has been feeded previously */ postlen = op->post->len; if (postlen > AJP_HEADER_LEN) { rc = ajp_connection_tcp_send_message(ae, op->post, l); /* Error during sending the request body. */ if (rc != JK_TRUE) { if (rc == JK_FATAL_ERROR) op->recoverable = JK_FALSE; jk_log(l, JK_LOG_ERROR, "(%s) failed sending request body of size %d " "(%srecoverable), socket %d (errno=%d)", ae->worker->name, postlen, op->recoverable ? "" : "un", ae->sd, ae->last_errno); JK_TRACE_EXIT(l); return JK_FATAL_ERROR; } else { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) Resent the request body (%d)", ae->worker->name, postlen); } } else if (s->reco_status == RECO_FILLED) { /* Recovery in LB MODE */ postlen = s->reco_buf->len; if (postlen > AJP_HEADER_LEN) { rc = ajp_connection_tcp_send_message(ae, s->reco_buf, l); /* Error during sending the request body. */ if (rc != JK_TRUE) { if (rc == JK_FATAL_ERROR) op->recoverable = JK_FALSE; jk_log(l, JK_LOG_ERROR, "(%s) failed sending request body of size %d (lb mode) " "(%srecoverable), socket %d (errno=%d)", ae->worker->name, postlen, op->recoverable ? "" : "un", ae->sd, ae->last_errno); JK_TRACE_EXIT(l); return JK_FATAL_ERROR; } } else { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) Resent the request body (lb mode) (%d)", ae->worker->name, postlen); } } else { /* We never sent any POST data and we check if we have to send at * least one block of data (max 8k). These data will be kept in reply * for resend if the remote Tomcat is down, a fact we will learn only * doing a read (not yet) * * || s->is_chunked - this can't be done here. The original protocol * sends the first chunk of post data ( based on Content-Length ), * and that's what the java side expects. * Sending this data for chunked would break other ajp13 servers. * * Note that chunking will continue to work - using the normal read. */ if (ae->left_bytes_to_send > 0) { int len; if ((len = ajp_read_into_msg_buff(ae, s, op->post, -1, l)) <= 0) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) browser stop sending data, no need to recover", ae->worker->name); op->recoverable = JK_FALSE; /* Send an empty POST message since per AJP protocol * spec whenever we have content length the message * packet must be followed with initial POST packet. * Size zero will be handled as error in container. */ jk_b_reset(op->post); jk_b_append_int(op->post, 0); ajp_connection_tcp_send_message(ae, op->post, l); JK_TRACE_EXIT(l); return JK_CLIENT_RD_ERROR; } /* If a RECOVERY buffer is available in LB mode, fill it */ if (s->reco_status == RECO_INITED) { jk_b_copy(op->post, s->reco_buf); s->reco_status = RECO_FILLED; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) sending %d bytes of request body", ae->worker->name, len); s->content_read = (jk_uint64_t)len; rc = ajp_connection_tcp_send_message(ae, op->post, l); /* Error during sending the request body. */ if (rc != JK_TRUE) { if (rc == JK_FATAL_ERROR) op->recoverable = JK_FALSE; jk_log(l, JK_LOG_ERROR, "(%s) failed sending request body of size %d " "(%srecoverable), socket %d (errno=%d)", ae->worker->name, len, op->recoverable ? "" : "un", ae->sd, ae->last_errno); JK_TRACE_EXIT(l); return JK_FATAL_ERROR; } } } JK_TRACE_EXIT(l); return JK_TRUE; } /* * What to do with incoming data (dispatcher) */ static int ajp_process_callback(jk_msg_buf_t *msg, jk_msg_buf_t *pmsg, ajp_endpoint_t * ae, jk_ws_service_t *r, jk_logger_t *l) { int code = (int)jk_b_get_byte(msg); JK_TRACE_ENTER(l); switch (code) { case JK_AJP13_SEND_HEADERS: { int rc; jk_res_data_t res; if (ae->last_op == JK_AJP13_SEND_HEADERS) { /* Do not send anything to the client. * Backend already send us the headers. */ if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "(%s) Already received AJP13_SEND HEADERS", ae->worker->name); } JK_TRACE_EXIT(l); return JK_AJP13_ERROR; } if (!ajp_unmarshal_response(msg, &res, ae, l)) { jk_log(l, JK_LOG_ERROR, "(%s) ajp_unmarshal_response failed", ae->worker->name); JK_TRACE_EXIT(l); return JK_AJP13_ERROR; } if (r->num_resp_headers > 0) { char **old_names = res.header_names; char **old_values = res.header_values; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) Adding %d response headers to %d " "headers received from tomcat", ae->worker->name, r->num_resp_headers, res.num_headers); res.header_names = jk_pool_alloc(r->pool, (r->num_resp_headers + res.num_headers) * sizeof(char *)); res.header_values = jk_pool_alloc(r->pool, (r->num_resp_headers + res.num_headers) * sizeof(char *)); if (!res.header_names || !res.header_values) { jk_log(l, JK_LOG_ERROR, "(%s) Failed allocating one %d response headers.", ae->worker->name, r->num_resp_headers + res.num_headers); res.header_names = old_names; res.header_values = old_values; } else { if (res.num_headers) { memcpy(res.header_names, old_names, res.num_headers * sizeof(char *)); memcpy(res.header_values, old_values, res.num_headers * sizeof(char *)); } if (r->num_resp_headers) { memcpy(res.header_names + res.num_headers, r->resp_headers_names, r->num_resp_headers * sizeof(char *)); memcpy(res.header_values + res.num_headers, r->resp_headers_values, r->num_resp_headers * sizeof(char *)); } res.num_headers = res.num_headers + r->num_resp_headers; } } r->http_response_status = res.status; if (r->extension.fail_on_status_size > 0) rc = is_http_status_fail(r->extension.fail_on_status_size, r->extension.fail_on_status, res.status); else rc = is_http_status_fail(ae->worker->http_status_fail_num, ae->worker->http_status_fail, res.status); if (rc > 0) { JK_TRACE_EXIT(l); return JK_STATUS_FATAL_ERROR; } if (rc < 0) { JK_TRACE_EXIT(l); return JK_STATUS_ERROR; } if (r->extension.use_server_error_pages && r->http_response_status >= r->extension.use_server_error_pages) r->response_blocked = JK_TRUE; /* * Call even if response is blocked, since it also handles * forwarding some headers for special http status codes * even if the server uses an own error page. * Example: The WWW-Authenticate header in case of * HTTP_UNAUTHORIZED (401). */ r->start_response(r, res.status, res.msg, (const char *const *)res.header_names, (const char *const *)res.header_values, res.num_headers); if (!r->response_blocked) { if (r->flush && r->flush_header) r->flush(r); } } return JK_AJP13_SEND_HEADERS; case JK_AJP13_SEND_BODY_CHUNK: if (ae->last_op == JK_AJP13_FORWARD_REQUEST) { /* AJP13_SEND_BODY_CHUNK with length 0 is * explicit flush packet message. * Ignore those if they are left over from previous responses. * Reportedly some versions of JBoss suffer from that problem. */ if (jk_b_get_int(msg) == 0) { jk_log(l, JK_LOG_DEBUG, "(%s) Ignoring flush message received while sending the request", ae->worker->name); return ae->last_op; } /* We have just send a request but received something * that probably originates from buffered response. */ if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "(%s) Unexpected AJP13_SEND_BODY_CHUNK", ae->worker->name); } JK_TRACE_EXIT(l); return JK_AJP13_ERROR; } if (!r->response_blocked) { unsigned int len = (unsigned int)jk_b_get_int(msg); /* * Do a sanity check on len to prevent write reading beyond buffer * boundaries and thus revealing possible sensitive memory * contents to the client. * len cannot be larger than msg->len - 3 because the ajp message * contains the magic byte for JK_AJP13_SEND_BODY_CHUNK (1 byte) * and the length of the chunk (2 bytes). The remaining part of * the message is the chunk. */ if (len > (unsigned int)(msg->len - 3)) { jk_log(l, JK_LOG_ERROR, "(%s) Chunk length too large. Length of AJP message is %d," " chunk length is %d.", ae->worker->name, msg->len, len); JK_TRACE_EXIT(l); return JK_INTERNAL_ERROR; } if (len == 0) { /* AJP13_SEND_BODY_CHUNK with length 0 is * explicit flush packet message. */ if (r->response_started) { if (r->flush) { r->flush(r); } } else { jk_log(l, JK_LOG_DEBUG, "(%s) Ignoring flush message received before headers", ae->worker->name); } } else { if (!r->write(r, msg->buf + msg->pos, len)) { jk_log(l, JK_LOG_INFO, "(%s) Writing to client aborted or client network problems", ae->worker->name); JK_TRACE_EXIT(l); return JK_CLIENT_WR_ERROR; } if (r->flush && r->flush_packets) r->flush(r); } } break; case JK_AJP13_GET_BODY_CHUNK: { int len = (int)jk_b_get_int(msg); if (len < 0) { len = 0; } /* the right place to add file storage for upload */ if ((len = ajp_read_into_msg_buff(ae, r, pmsg, len, l)) >= 0) { r->content_read += (jk_uint64_t)len; JK_TRACE_EXIT(l); return JK_AJP13_HAS_RESPONSE; } jk_log(l, JK_LOG_INFO, "(%s) Reading from client aborted or client network problems", ae->worker->name); JK_TRACE_EXIT(l); return JK_CLIENT_RD_ERROR; } break; case JK_AJP13_END_RESPONSE: ae->reuse = (int)jk_b_get_byte(msg); if (!ae->reuse) { /* * AJP13 protocol reuse flag set to false. * Tomcat will close its side of the connection. */ jk_log(l, JK_LOG_WARNING, "(%s) AJP13 protocol: Reuse is set to false", ae->worker->name); } else if (r->disable_reuse) { if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "(%s) AJP13 protocol: Reuse is disabled", ae->worker->name); } ae->reuse = JK_FALSE; } else { /* Reuse in all cases */ if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "(%s) AJP13 protocol: Reuse is OK", ae->worker->name); } ae->reuse = JK_TRUE; } if (!r->response_blocked) { if (r->done) { /* Done with response */ r->done(r); } else if (r->flush && !r->flush_packets) { /* Flush after the last write */ r->flush(r); } } JK_TRACE_EXIT(l); return JK_AJP13_END_RESPONSE; break; default: jk_log(l, JK_LOG_ERROR, "(%s) Unknown AJP protocol code: %02X", ae->worker->name, code); JK_TRACE_EXIT(l); return JK_AJP13_ERROR; } JK_TRACE_EXIT(l); return JK_AJP13_NO_RESPONSE; } /* * get replies from Tomcat via Ajp13/Ajp14 * ajp13/ajp14 is async but handling read/send this way prevent nice recovery * In fact if tomcat link is broken during upload (browser -> apache -> tomcat) * we'll loose data and we'll have to abort the whole request. * * Return values of ajp_get_reply() function: * return value op->recoverable reason * JK_REPLY_TIMEOUT ?recovery_options Reply timeout while waiting for response packet * JK_FALSE ?recovery_options Error during ajp_connection_tcp_get_message() * Could not read the AJP packet header * JK_AJP_PROTOCOL_ERROR: ?recovery_options Error during ajp_connection_tcp_get_message() * Failure after reading the AJP packet header * JK_STATUS_ERROR mostly JK_TRUE ajp_process_callback() returns JK_STATUS_ERROR * Recoverable, if callback didn't return with a JK_HAS_RESPONSE before. * JK_HAS_RESPONSE: parts of the post buffer are consumed. * JK_STATUS_FATAL_ERROR mostly JK_TRUE ajp_process_callback() returns JK_STATUS_FATAL_ERROR * Recoverable, if callback didn't return with a JK_HAS_RESPONSE before. * JK_HAS_RESPONSE: parts of the post buffer are consumed. * JK_FATAL_ERROR ? ajp_process_callback() returns JK_AJP13_ERROR * JK_AJP13_ERROR: protocol error, or JK_INTERNAL_ERROR: chunk size to large * JK_CLIENT_RD_ERROR ? ajp_process_callback() returns JK_CLIENT_RD_ERROR * JK_CLIENT_RD_ERROR: could not read post from client. * JK_CLIENT_WR_ERROR ? ajp_process_callback() returns JK_CLIENT_WR_ERROR * JK_CLIENT_WR_ERROR: could not write back result to client * JK_TRUE ? ajp_process_callback() returns JK_AJP13_END_RESPONSE * JK_FALSE ? Other unhandled cases (unknown return codes) */ static int ajp_get_reply(jk_endpoint_t *e, jk_ws_service_t *s, jk_logger_t *l, ajp_endpoint_t * p, ajp_operation_t * op) { /* Don't get header from tomcat yet */ int headeratclient = JK_FALSE; JK_TRACE_ENTER(l); p->last_errno = 0; /* Start read all reply message */ while (1) { int rc = 0; /* Allow to overwrite reply_timeout on a per URL basis via service struct */ int reply_timeout = s->extension.reply_timeout; if (reply_timeout < 0) reply_timeout = p->worker->reply_timeout; /* If we set a reply timeout, check if something is available */ if (reply_timeout > 0) { if (jk_is_input_event(p->sd, reply_timeout, l) == JK_FALSE) { p->last_errno = errno; jk_log(l, JK_LOG_ERROR, "(%s) Timeout with waiting reply from tomcat. " "Tomcat is down, stopped or network problems (errno=%d)", p->worker->name, p->last_errno); /* We can't trust this connection any more. */ ajp_abort_endpoint(p, JK_TRUE, l); if (headeratclient == JK_FALSE) { if (p->worker->recovery_opts & RECOVER_ABORT_IF_TCGETREQUEST) op->recoverable = JK_FALSE; /* * We revert back to recoverable, if recovery_opts allow it * for GET or HEAD */ if (op->recoverable == JK_FALSE) { if (p->worker->recovery_opts & RECOVER_ALWAYS_HTTP_HEAD) { if (!strcmp(s->method, "HEAD")) op->recoverable = JK_TRUE; } else if (p->worker->recovery_opts & RECOVER_ALWAYS_HTTP_GET) { if (!strcmp(s->method, "GET")) op->recoverable = JK_TRUE; } } } else { if (p->worker->recovery_opts & RECOVER_ABORT_IF_TCSENDHEADER) op->recoverable = JK_FALSE; } JK_TRACE_EXIT(l); return JK_REPLY_TIMEOUT; } } if ((rc = ajp_connection_tcp_get_message(p, op->reply, l)) != JK_TRUE) { if (headeratclient == JK_FALSE) { jk_log(l, JK_LOG_ERROR, "(%s) Tomcat is down or refused connection. " "No response has been sent to the client (yet)", p->worker->name); /* * communication with tomcat has been interrupted BEFORE * headers have been sent to the client. * * We mark it unrecoverable if recovery_opts set to * RECOVER_ABORT_IF_TCGETREQUEST */ if (p->worker->recovery_opts & RECOVER_ABORT_IF_TCGETREQUEST) op->recoverable = JK_FALSE; /* * We revert back to recoverable, if recovery_opts allow it * for GET or HEAD */ if (op->recoverable == JK_FALSE) { if (p->worker->recovery_opts & RECOVER_ALWAYS_HTTP_HEAD) { if (!strcmp(s->method, "HEAD")) op->recoverable = JK_TRUE; } else if (p->worker->recovery_opts & RECOVER_ALWAYS_HTTP_GET) { if (!strcmp(s->method, "GET")) op->recoverable = JK_TRUE; } } } else { jk_log(l, JK_LOG_ERROR, "(%s) Tomcat is down or network problems. " "Part of the response has already been sent to the client", p->worker->name); /* communication with tomcat has been interrupted AFTER * headers have been sent to the client. * headers (and maybe parts of the body) have already been * sent, therefore the response is "complete" in a sense * that nobody should append any data, especially no 500 error * page of the webserver! * * We mark it unrecoverable if recovery_opts set to * RECOVER_ABORT_IF_TCSENDHEADER */ if (p->worker->recovery_opts & RECOVER_ABORT_IF_TCSENDHEADER) op->recoverable = JK_FALSE; } JK_TRACE_EXIT(l); return rc; } rc = ajp_process_callback(op->reply, op->post, p, s, l); p->last_op = rc; /* no more data to be sent, fine we have finish here */ if (JK_AJP13_END_RESPONSE == rc) { JK_TRACE_EXIT(l); return JK_TRUE; } if (JK_AJP13_SEND_HEADERS == rc) { if (headeratclient == JK_FALSE) { headeratclient = JK_TRUE; continue; } else { /* Backend send headers twice? * This is protocol violation */ jk_log(l, JK_LOG_ERROR, "(%s) Tomcat already send headers", p->worker->name); op->recoverable = JK_FALSE; JK_TRACE_EXIT(l); return JK_FALSE; } } if (JK_STATUS_ERROR == rc || JK_STATUS_FATAL_ERROR == rc) { jk_log(l, JK_LOG_INFO, "(%s) request failed%s, " "because of response status %d, ", p->worker->name, rc == JK_STATUS_FATAL_ERROR ? "" : " (soft)", s->http_response_status); JK_TRACE_EXIT(l); return rc; } if (JK_AJP13_HAS_RESPONSE == rc) { /* * in upload-mode there is no second chance since * we may have already sent part of the uploaded data * to Tomcat. * In this case if Tomcat connection is broken we must * abort request and indicate error. * A possible work-around could be to store the uploaded * data to file and replay for it */ op->recoverable = JK_FALSE; rc = ajp_connection_tcp_send_message(p, op->post, l); if (rc != JK_TRUE) { jk_log(l, JK_LOG_ERROR, "(%s) Tomcat is down or network problems", p->worker->name); JK_TRACE_EXIT(l); return JK_FALSE; } } if (JK_AJP13_ERROR == rc) { /* * Tomcat has send invalid AJP message. * Loadbalancer if present will decide if * failover is possible. */ JK_TRACE_EXIT(l); return JK_FATAL_ERROR; } if (JK_CLIENT_RD_ERROR == rc) { /* * Client has stop sending to us, so get out. * We assume this isn't our fault, so just a normal exit. */ JK_TRACE_EXIT(l); return JK_CLIENT_RD_ERROR; } if (JK_CLIENT_WR_ERROR == rc) { /* * Client has stop receiving to us, so get out. * We assume this isn't our fault, so just a normal exit. */ JK_TRACE_EXIT(l); return JK_CLIENT_WR_ERROR; } if (JK_INTERNAL_ERROR == rc) { /* * Internal error, like memory allocation or invalid packet lengths. */ JK_TRACE_EXIT(l); return JK_FATAL_ERROR; } if (JK_AJP13_NO_RESPONSE == rc) { /* * This is fine, loop again, more data to send. */ continue; } if (rc < 0) { op->recoverable = JK_FALSE; jk_log(l, JK_LOG_ERROR, "(%s) Callback returns with unknown value %d", p->worker->name, rc); JK_TRACE_EXIT(l); return JK_FALSE; } } /* XXX: Not reached? */ JK_TRACE_EXIT(l); return JK_FALSE; } static void ajp_update_stats(jk_endpoint_t *e, ajp_worker_t *aw, int rc, jk_logger_t *l) { aw->s->readed += e->rd; aw->s->transferred += e->wr; JK_ATOMIC_DECREMENT(&(aw->s->busy)); if (rc == JK_TRUE) { aw->s->state = JK_AJP_STATE_OK; } else if (rc == JK_CLIENT_ERROR) { aw->s->state = JK_AJP_STATE_OK; aw->s->client_errors++; } else { aw->s->state = JK_AJP_STATE_ERROR; aw->s->errors++; aw->s->error_time = time(NULL); } } /* * service is now splitted in ajp_send_request and ajp_get_reply * much more easier to do errors recovery * * We serve here the request, using AJP13/AJP14 (e->proto) * * Return values of service() method for ajp13/ajp14 worker: * return value is_error e->recoverable reason * JK_FALSE JK_HTTP_SERVER_ERROR TRUE Invalid Parameters (null values) * JK_SERVER_ERROR JK_HTTP_SERVER_ERROR TRUE Error during initializing empty request, response or post body objects * JK_CLIENT_ERROR JK_HTTP_REQUEST_TOO_LARGE JK_TRUE Request doesn't fit into buffer (error during ajp_marshal_into_msgb()) * JK_CLIENT_ERROR JK_HTTP_BAD_REQUEST JK_FALSE Error during reading parts of POST body from client * JK_FATAL_ERROR JK_HTTP_SERVER_ERROR JK_FALSE If ajp_send_request() returns JK_FATAL_ERROR and !op->recoverable. * JK_FATAL_ERROR JK_HTTP_SERVER_ERROR JK_FALSE If ajp_send_request() returns JK_TRUE but !op->recoverable. * This should never happen. * JK_CLIENT_ERROR JK_HTTP_BAD_REQUEST ? ajp_get_reply() returns JK_CLIENT_RD_ERROR * JK_CLIENT_ERROR JK_HTTP_OK ? ajp_get_reply() returns JK_CLIENT_WR_ERROR * JK_FATAL_ERROR JK_HTTP_SERVER_ERROR JK_TRUE ajp_get_reply() returns JK_FATAL_ERROR * JK_FATAL_ERROR: protocol error or internal error * JK_FATAL_ERROR JK_HTTP_SERVER_ERROR JK_FALSE ajp_get_reply() returns JK_FATAL_ERROR * JK_FATAL_ERROR: protocol error or internal error * JK_STATUS_ERROR JK_HTTP_SERVER_BUSY JK_TRUE ajp_get_reply() returns JK_STATUS_ERROR * Only if op->recoverable and no more ajp13/ajp14 direct retries * JK_STATUS_ERROR JK_HTTP_SERVER_BUSY JK_FALSE ajp_get_reply() returns JK_STATUS_ERROR * Only if !op->recoverable * JK_STATUS_FATAL_ERROR JK_HTTP_SERVER_BUSY JK_TRUE ajp_get_reply() returns JK_STATUS_ERROR * Only if op->recoverable and no more ajp13/ajp14 direct retries * JK_STATUS_FATAL_ERROR JK_HTTP_SERVER_BUSY JK_FALSE ajp_get_reply() returns JK_STATUS_FATAL_ERROR * Only if !op->recoverable * JK_REPLY_TIMEOUT JK_HTTP_GATEWAY_TIME_OUT JK_TRUE ajp_get_reply() returns JK_REPLY_TIMEOUT * JK_AJP_PROTOCOL_ERROR JK_HTTP_GATEWAY_TIME_OUT ? ajp_get_reply() returns JK_AJP_PROTOCOL_ERROR * ??? JK_FATAL_ERROR JK_HTTP_GATEWAY_TIME_OUT JK_FALSE ajp_get_reply() returns something else * Only if !op->recoverable * ??? JK_FALSE JK_HTTP_SERVER_BUSY JK_TRUE ajp_get_reply() returns JK_FALSE * Only if op->recoverable and no more ajp13/ajp14 direct retries * JK_TRUE JK_HTTP_OK ? OK */ static int JK_METHOD ajp_service(jk_endpoint_t *e, jk_ws_service_t *s, jk_logger_t *l, int *is_error) { int i; int err = JK_TRUE; ajp_operation_t oper; ajp_operation_t *op = &oper; ajp_endpoint_t *p; ajp_worker_t *aw; int log_error; int rc = JK_UNSET; char *msg = ""; int retry_interval; int busy; JK_TRACE_ENTER(l); if (!e || !e->endpoint_private || !s || !is_error) { JK_LOG_NULL_PARAMS(l); if (is_error) *is_error = JK_HTTP_SERVER_ERROR; JK_TRACE_EXIT(l); return JK_FALSE; } p = e->endpoint_private; aw = p->worker; if (aw->sequence != aw->s->h.sequence) jk_ajp_pull(aw, JK_FALSE, l); aw->s->used++; /* Set returned error to SERVER ERROR */ *is_error = JK_HTTP_SERVER_ERROR; op->request = jk_b_new(&(p->pool)); if (!op->request) { jk_log(l, JK_LOG_ERROR, "(%s) Failed allocating AJP message", aw->name); JK_TRACE_EXIT(l); return JK_SERVER_ERROR; } if (jk_b_set_buffer_size(op->request, aw->max_packet_size)) { jk_log(l, JK_LOG_ERROR, "(%s) Failed allocating AJP message buffer", aw->name); JK_TRACE_EXIT(l); return JK_SERVER_ERROR; } jk_b_reset(op->request); op->reply = jk_b_new(&(p->pool)); if (!op->reply) { jk_log(l, JK_LOG_ERROR, "(%s) Failed allocating AJP message", aw->name); JK_TRACE_EXIT(l); return JK_SERVER_ERROR; } if (jk_b_set_buffer_size(op->reply, aw->max_packet_size)) { jk_log(l, JK_LOG_ERROR, "(%s) Failed allocating AJP message buffer", aw->name); JK_TRACE_EXIT(l); return JK_SERVER_ERROR; } op->post = jk_b_new(&(p->pool)); if (!op->post) { jk_log(l, JK_LOG_ERROR, "(%s) Failed allocating AJP message", aw->name); JK_TRACE_EXIT(l); return JK_SERVER_ERROR; } if (jk_b_set_buffer_size(op->post, aw->max_packet_size)) { jk_log(l, JK_LOG_ERROR, "(%s) Failed allocating AJP message buffer", aw->name); JK_TRACE_EXIT(l); return JK_SERVER_ERROR; } jk_b_reset(op->post); /* Set returned error to OK */ *is_error = JK_HTTP_OK; op->recoverable = JK_TRUE; op->uploadfd = -1; /* not yet used, later ;) */ p->left_bytes_to_send = s->content_length; p->reuse = JK_FALSE; p->hard_close = JK_FALSE; s->secret = aw->secret; /* * We get here initial request (in op->request) */ if (!ajp_marshal_into_msgb(op->request, s, l, p)) { *is_error = JK_HTTP_REQUEST_TOO_LARGE; jk_log(l, JK_LOG_INFO, "(%s) Creating AJP message failed " "without recovery - check max_packet_size", aw->name); aw->s->client_errors++; JK_TRACE_EXIT(l); return JK_CLIENT_ERROR; } if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "processing %s with %d retries", aw->name, aw->retries); } busy = JK_ATOMIC_INCREMENT(&(aw->s->busy)); if (aw->busy_limit > 0 && busy > aw->busy_limit) { JK_ATOMIC_DECREMENT(&(aw->s->busy)); e->recoverable = JK_TRUE; aw->s->errors++; aw->s->error_time = time(NULL); *is_error = JK_HTTP_SERVER_BUSY; rc = JK_BUSY_ERROR; jk_log(l, JK_LOG_ERROR, "(%s) sending request to tomcat failed (recoverable), " "busy limit %d reached (rc=%d, errors=%d, client_errors=%d).", aw->name, aw->busy_limit, rc, aw->s->errors, aw->s->client_errors); JK_TRACE_EXIT(l); return rc; } if (aw->s->state == JK_AJP_STATE_ERROR) aw->s->state = JK_AJP_STATE_PROBE; if (busy > aw->s->max_busy) aw->s->max_busy = busy; retry_interval = p->worker->retry_interval; for (i = 0; i < aw->retries; i++) { /* Reset reply message buffer for each retry */ jk_b_reset(op->reply); /* * ajp_send_request() already locally handles * reconnecting and broken connection detection. * So if we already failed in it, wait a bit before * retrying the same backend. */ if (i > 0 && retry_interval >= 0) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) retry %d, sleeping for %d ms before retrying", aw->name, i, retry_interval); jk_sleep(retry_interval); /* Pull shared memory if something changed during sleep */ if (aw->sequence != aw->s->h.sequence) jk_ajp_pull(aw, JK_FALSE, l); } /* * We're using op->request which hold initial request * if Tomcat is stopped or restarted, we will pass op->request * to next valid tomcat. */ log_error = JK_TRUE; rc = JK_UNSET; msg = ""; err = ajp_send_request(e, s, l, p, op); e->recoverable = op->recoverable; if (err == JK_CLIENT_RD_ERROR) { *is_error = JK_HTTP_BAD_REQUEST; msg = "because of client read error"; aw->s->client_errors++; rc = JK_CLIENT_ERROR; log_error = JK_FALSE; e->recoverable = JK_FALSE; /* Ajp message set reuse to TRUE in END_REQUEST message * However due to client bad request if the recovery * RECOVER_ABORT_IF_CLIENTERROR is set the physical connection * will be closed and application in Tomcat can catch that * generated exception, knowing the client aborted the * connection. This AJP protocol limitation, where we * should actually send some packet informing the backend * that client broke the connection in a middle of * request/response cycle. */ if (aw->recovery_opts & RECOVER_ABORT_IF_CLIENTERROR) { /* Mark the endpoint for shutdown */ p->reuse = JK_FALSE; p->hard_close = JK_TRUE; } } else if (err == JK_FATAL_ERROR) { *is_error = JK_HTTP_SERVER_BUSY; msg = "because of error during request sending"; rc = err; if (!op->recoverable) { *is_error = JK_HTTP_SERVER_ERROR; msg = "because of protocol error during request sending"; } } else if (err == JK_TRUE && op->recoverable) { /* Up to there we can recover */ err = ajp_get_reply(e, s, l, p, op); e->recoverable = op->recoverable; if (err == JK_TRUE) { *is_error = JK_HTTP_OK; /* Done with the request */ ajp_update_stats(e, aw, JK_TRUE, l); JK_TRACE_EXIT(l); return JK_TRUE; } if (err == JK_CLIENT_RD_ERROR) { *is_error = JK_HTTP_BAD_REQUEST; msg = "because of client read error"; aw->s->client_errors++; rc = JK_CLIENT_ERROR; log_error = JK_FALSE; e->recoverable = JK_FALSE; op->recoverable = JK_FALSE; if (aw->recovery_opts & RECOVER_ABORT_IF_CLIENTERROR) { /* Mark the endpoint for shutdown */ p->reuse = JK_FALSE; p->hard_close = JK_TRUE; } } else if (err == JK_CLIENT_WR_ERROR) { /* XXX: Is this correct to log this as 200? */ *is_error = JK_HTTP_OK; msg = "because of client write error"; aw->s->client_errors++; rc = JK_CLIENT_ERROR; log_error = JK_FALSE; e->recoverable = JK_FALSE; op->recoverable = JK_FALSE; if (aw->recovery_opts & RECOVER_ABORT_IF_CLIENTERROR) { /* Mark the endpoint for shutdown */ p->reuse = JK_FALSE; p->hard_close = JK_TRUE; } } else if (err == JK_FATAL_ERROR) { *is_error = JK_HTTP_SERVER_ERROR; msg = "because of server error"; rc = err; } else if (err == JK_REPLY_TIMEOUT) { *is_error = JK_HTTP_GATEWAY_TIME_OUT; msg = "because of reply timeout"; aw->s->reply_timeouts++; rc = err; } else if (err == JK_STATUS_ERROR || err == JK_STATUS_FATAL_ERROR) { *is_error = JK_HTTP_SERVER_BUSY; msg = "because of response status"; rc = err; } else if (err == JK_AJP_PROTOCOL_ERROR) { *is_error = JK_HTTP_BAD_GATEWAY; msg = "because of protocol error"; rc = err; } /* This should only be the cases err == JK_FALSE */ else { /* if we can't get reply, check if unrecoverable flag was set * if is_recoverable_error is cleared, we have started * receiving upload data and we must consider that * operation is no more recoverable */ *is_error = JK_HTTP_BAD_GATEWAY; msg = ""; rc = JK_FALSE; } } else { /* XXX: this should never happen: * ajp_send_request() never returns JK_TRUE if !op->recoverable. * and all other return values have already been handled. */ e->recoverable = JK_FALSE; *is_error = JK_HTTP_SERVER_ERROR; msg = "because of an unknown reason"; rc = JK_FATAL_ERROR; jk_log(l, JK_LOG_ERROR, "(%s) unexpected condition err=%d (%srecoverable)", aw->name, err, op->recoverable ? "" : "un"); } if (!op->recoverable && log_error == JK_TRUE) { jk_log(l, JK_LOG_ERROR, "(%s) sending request to tomcat failed (unrecoverable), " "%s " "(attempt=%d)", aw->name, msg, i + 1); } else { jk_log(l, JK_LOG_INFO, "(%s) sending request to tomcat failed (%srecoverable), " "%s " "(attempt=%d)", aw->name, op->recoverable ? "" : "un", msg, i + 1); } if (!op->recoverable) { ajp_update_stats(e, aw, rc, l); JK_TRACE_EXIT(l); return rc; } /* Get another connection from the pool and try again. * Note: All sockets are probably closed already. */ ajp_next_connection(p, l); } ajp_update_stats(e, aw, rc, l); /* Log the error only once per failed request. */ jk_log(l, JK_LOG_ERROR, "(%s) connecting to tomcat failed (rc=%d, errors=%d, client_errors=%d).", aw->name, rc, aw->s->errors, aw->s->client_errors); JK_TRACE_EXIT(l); return rc; } /* * Validate the worker (ajp13/ajp14) */ int ajp_validate(jk_worker_t *pThis, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l, int proto) { int port; const char *host; JK_TRACE_ENTER(l); if (proto == AJP13_PROTO) { port = AJP13_DEF_PORT; host = AJP13_DEF_HOST; } else if (proto == AJP14_PROTO) { port = AJP14_DEF_PORT; host = AJP14_DEF_HOST; } else { if (pThis && pThis->worker_private) { ajp_worker_t *p = pThis->worker_private; jk_log(l, JK_LOG_ERROR, "(%s) unknown protocol %d", p->name, proto); } else { jk_log(l, JK_LOG_ERROR, "(unset worker) unknown protocol %d", proto); } JK_TRACE_EXIT(l); return JK_FALSE; } if (pThis && pThis->worker_private) { const char *tmp; ajp_worker_t *p = pThis->worker_private; p->worker.we = we; p->port = jk_get_worker_port(props, p->name, port); if (!host) { host = "undefined"; } tmp = jk_get_worker_host(props, p->name, host); if (jk_check_attribute_length("host name", tmp, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } strncpy(p->host, tmp, JK_SHM_STR_SIZ); p->prefer_ipv6 = jk_get_worker_prefer_ipv6(props, p->name, JK_FALSE); tmp = jk_get_worker_source(props, p->name, ""); if (jk_check_attribute_length("source address", tmp, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } strncpy(p->source, tmp, JK_SHM_STR_SIZ); if (p->s->h.sequence == 0) { /* Initial setup. */ if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "worker %s target is '%s:%d'", p->name, p->host, p->port); if (p->port > 0) { if (!jk_resolve(p->host, p->port, &p->worker_inet_addr, we->pool, p->prefer_ipv6, l)) { jk_log(l, JK_LOG_ERROR, "worker %s can't resolve tomcat address %s", p->name, p->host); p->s->port = p->port = 0; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "worker %s contact is disabled", p->name); } } if (p->source && *p->source) { if (!jk_resolve(p->source, 0, &p->worker_source_inet_addr, we->pool, p->prefer_ipv6, l)) { p->worker_source_inet_addr.ipaddr_ptr = NULL; jk_log(l, JK_LOG_WARNING, "worker %s can't resolve source address '%s'", p->name, p->source); } } p->addr_sequence = 0; p->s->addr_sequence = 0; p->s->last_maintain_time = time(NULL); p->s->last_reset = p->s->last_maintain_time; p->s->port = p->port; strncpy(p->s->host, p->host, JK_SHM_STR_SIZ); jk_ajp_push(p, JK_TRUE, l); } else { /* Somebody already setup this worker. */ if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "worker %s contact '%s:%d' already configured type=%d (%d) [%d]", p->name, p->host, p->port, p->s->h.type, p->s->h.sequence, p->s->addr_sequence); /* Force resolve */ p->addr_sequence = -1; jk_ajp_pull(p, JK_TRUE, l); } JK_TRACE_EXIT(l); return JK_TRUE; } else { JK_LOG_NULL_PARAMS(l); } JK_TRACE_EXIT(l); return JK_FALSE; } static int ajp_create_endpoint_cache(ajp_worker_t *p, int proto, jk_logger_t *l) { unsigned int i; time_t now = time(NULL); JK_TRACE_ENTER(l); p->ep_cache = (ajp_endpoint_t **)calloc(1, sizeof(ajp_endpoint_t *) * p->ep_cache_sz); if (!p->ep_cache) { JK_TRACE_EXIT(l); return JK_FALSE; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) setting connection pool size to %u with min %u " "and acquire timeout %d", p->name, p->ep_cache_sz, p->ep_mincache_sz, p->cache_acquire_timeout); for (i = 0; i < p->ep_cache_sz; i++) { p->ep_cache[i] = (ajp_endpoint_t *)calloc(1, sizeof(ajp_endpoint_t)); if (!p->ep_cache[i]) { jk_log(l, JK_LOG_ERROR, "(%s) allocating endpoint slot %d (errno=%d)", p->name, i, errno); JK_TRACE_EXIT(l); return JK_FALSE; } p->ep_cache[i]->sd = JK_INVALID_SOCKET; p->ep_cache[i]->reuse = JK_FALSE; p->ep_cache[i]->avail = JK_TRUE; p->ep_cache[i]->hard_close = JK_FALSE; p->ep_cache[i]->last_access = now; jk_open_pool(&(p->ep_cache[i]->pool), p->ep_cache[i]->buf, sizeof(p->ep_cache[i]->buf)); p->ep_cache[i]->worker = p; p->ep_cache[i]->endpoint.endpoint_private = p->ep_cache[i]; p->ep_cache[i]->proto = proto; p->ep_cache[i]->endpoint.service = ajp_service; p->ep_cache[i]->endpoint.done = ajp_done; p->ep_cache[i]->last_op = JK_AJP13_END_RESPONSE; p->ep_cache[i]->addr_sequence = 0; } JK_TRACE_EXIT(l); return JK_TRUE; } int ajp_init(jk_worker_t *pThis, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l, int proto) { int rc = JK_FALSE; int cache; /* * start the connection cache */ JK_TRACE_ENTER(l); cache = jk_get_worker_def_cache_size(proto); if (pThis && pThis->worker_private) { ajp_worker_t *p = pThis->worker_private; p->worker.we = we; p->ep_cache_sz = jk_get_worker_cache_size(props, p->name, cache); p->ep_mincache_sz = jk_get_worker_cache_size_min(props, p->name, (p->ep_cache_sz+1) / 2); p->socket_timeout = jk_get_worker_socket_timeout(props, p->name, AJP_DEF_SOCKET_TIMEOUT); p->socket_connect_timeout = jk_get_worker_socket_connect_timeout(props, p->name, p->socket_timeout * 1000); p->keepalive = jk_get_worker_socket_keepalive(props, p->name, JK_FALSE); p->cache_timeout = jk_get_worker_cache_timeout(props, p->name, AJP_DEF_CACHE_TIMEOUT); p->ping_timeout = jk_get_worker_ping_timeout(props, p->name, AJP_DEF_PING_TIMEOUT); p->ping_mode = jk_get_worker_ping_mode(props, p->name, AJP_CPING_NONE); p->connect_timeout = jk_get_worker_connect_timeout(props, p->name, AJP_DEF_CONNECT_TIMEOUT); p->prepost_timeout = jk_get_worker_prepost_timeout(props, p->name, AJP_DEF_PREPOST_TIMEOUT); if ((p->ping_mode & AJP_CPING_CONNECT) && p->connect_timeout == AJP_DEF_CONNECT_TIMEOUT) p->connect_timeout = p->ping_timeout; if ((p->ping_mode & AJP_CPING_PREPOST) && p->prepost_timeout == AJP_DEF_PREPOST_TIMEOUT) p->prepost_timeout = p->ping_timeout; p->conn_ping_interval = jk_get_worker_conn_ping_interval(props, p->name, 0); if ((p->ping_mode & AJP_CPING_INTERVAL) && p->conn_ping_interval == 0) { /* XXX: Ping timeout is in miliseconds * and ping_interval is in seconds. * Use 10 times larger value for ping interval * (ping_timeout / 1000) * 10 */ p->conn_ping_interval = p->ping_timeout / 100; } p->reply_timeout = jk_get_worker_reply_timeout(props, p->name, AJP_DEF_REPLY_TIMEOUT); p->recovery_opts = jk_get_worker_recovery_opts(props, p->name, AJP_DEF_RECOVERY_OPTS); p->retries = jk_get_worker_retries(props, p->name, JK_RETRIES); p->max_packet_size = jk_get_max_packet_size(props, p->name); p->socket_buf = jk_get_worker_socket_buffer(props, p->name, p->max_packet_size); p->retry_interval = jk_get_worker_retry_interval(props, p->name, JK_SLEEP_DEF); p->cache_acquire_timeout = jk_get_worker_cache_acquire_timeout(props, p->name, p->retries * p->retry_interval); p->busy_limit = jk_get_worker_busy_limit(props, p->name, 0); jk_get_worker_fail_on_status(props, p->name, &(p->http_status_fail), &(p->http_status_fail_num)); if (p->retries < 1) { jk_log(l, JK_LOG_INFO, "(%s) number of retries must be greater then 1. Setting to default=%d", p->name, JK_RETRIES); p->retries = JK_RETRIES; } p->maintain_time = jk_get_worker_maintain_time(props); if(p->maintain_time < 0) p->maintain_time = 0; if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "(%s) setting endpoint options:", p->name); jk_log(l, JK_LOG_DEBUG, "keepalive: %d", p->keepalive); jk_log(l, JK_LOG_DEBUG, "socket timeout: %d", p->socket_timeout); jk_log(l, JK_LOG_DEBUG, "socket connect timeout: %d", p->socket_connect_timeout); jk_log(l, JK_LOG_DEBUG, "buffer size: %d", p->socket_buf); jk_log(l, JK_LOG_DEBUG, "pool timeout: %d", p->cache_timeout); jk_log(l, JK_LOG_DEBUG, "ping timeout: %d", p->ping_timeout); jk_log(l, JK_LOG_DEBUG, "connect timeout: %d", p->connect_timeout); jk_log(l, JK_LOG_DEBUG, "reply timeout: %d", p->reply_timeout); jk_log(l, JK_LOG_DEBUG, "prepost timeout: %d", p->prepost_timeout); jk_log(l, JK_LOG_DEBUG, "recovery options: %d", p->recovery_opts); jk_log(l, JK_LOG_DEBUG, "retries: %d", p->retries); jk_log(l, JK_LOG_DEBUG, "max packet size: %d", p->max_packet_size); jk_log(l, JK_LOG_DEBUG, "retry interval: %d", p->retry_interval); jk_log(l, JK_LOG_DEBUG, "busy limit: %d", p->busy_limit); } /* * Need to initialize secret here since we could return from inside * of the following loop */ p->secret = jk_get_worker_secret(props, p->name); if (!ajp_create_endpoint_cache(p, proto, l)) { jk_log(l, JK_LOG_ERROR, "(%s) allocating connection pool of size %u", p->name, p->ep_cache_sz); JK_TRACE_EXIT(l); return JK_FALSE; } rc = JK_TRUE; } else { JK_LOG_NULL_PARAMS(l); } JK_TRACE_EXIT(l); return rc; } int JK_METHOD ajp_worker_factory(jk_worker_t **w, const char *name, jk_logger_t *l) { int rc; ajp_worker_t *aw; JK_TRACE_ENTER(l); if (name == NULL || w == NULL) { JK_LOG_NULL_PARAMS(l); JK_TRACE_EXIT(l); return JK_FALSE; } aw = (ajp_worker_t *) calloc(1, sizeof(ajp_worker_t)); if (!aw) { jk_log(l, JK_LOG_ERROR, "(%s) malloc of private_data failed", name); JK_TRACE_EXIT(l); return JK_FALSE; } jk_open_pool(&aw->p, aw->buf, sizeof(jk_pool_atom_t) * TINY_POOL_SIZE); strncpy(aw->name, name, JK_SHM_STR_SIZ); aw->login = NULL; aw->ep_cache_sz = 0; aw->ep_cache = NULL; aw->connect_retry_attempts = AJP_DEF_RETRY_ATTEMPTS; aw->worker.worker_private = aw; aw->worker.maintain = ajp_maintain; aw->worker.shutdown = ajp_shutdown; aw->logon = NULL; *w = &aw->worker; aw->s = jk_shm_alloc_ajp_worker(&aw->p, name, l); if (!aw->s) { jk_close_pool(&aw->p); free(aw); jk_log(l, JK_LOG_ERROR, "(%s) allocating ajp worker record from shared memory", aw->name); JK_TRACE_EXIT(l); return JK_FALSE; } JK_INIT_CS(&aw->cs, rc); if (!rc) { jk_log(l, JK_LOG_ERROR, "(%s) creating thread lock (errno=%d)", aw->name, errno); jk_close_pool(&aw->p); free(aw); JK_TRACE_EXIT(l); return JK_FALSE; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "ajp worker '%s' type=%d created", aw->name, aw->s->h.type); JK_TRACE_EXIT(l); return JK_TRUE; } int ajp_destroy(jk_worker_t **pThis, jk_logger_t *l, int proto) { JK_TRACE_ENTER(l); if (pThis && *pThis && (*pThis)->worker_private) { unsigned int i; ajp_worker_t *aw = (*pThis)->worker_private; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) up to %u endpoints to close", aw->name, aw->ep_cache_sz); for (i = 0; i < aw->ep_cache_sz; i++) { if (aw->ep_cache[i]) ajp_close_endpoint(aw->ep_cache[i], l); } free(aw->ep_cache); JK_DELETE_CS(&aw->cs); if (aw->login) { /* take care of removing previously allocated data */ if (aw->login->servlet_engine_name) free(aw->login->servlet_engine_name); free(aw->login); aw->login = NULL; } jk_close_pool(&aw->p); free(aw); JK_TRACE_EXIT(l); return JK_TRUE; } JK_LOG_NULL_PARAMS(l); JK_TRACE_EXIT(l); return JK_FALSE; } int JK_METHOD ajp_done(jk_endpoint_t **e, jk_logger_t *l) { JK_TRACE_ENTER(l); if (e && *e && (*e)->endpoint_private) { ajp_endpoint_t *p = (*e)->endpoint_private; ajp_worker_t *w = p->worker; /* set last_access only if needed */ if (w->cache_timeout > 0) p->last_access = time(NULL); if (w->s->addr_sequence != p->addr_sequence) { p->reuse = JK_FALSE; p->addr_sequence = w->s->addr_sequence; } ajp_reset_endpoint(p, l); *e = NULL; JK_ENTER_CS(&w->cs); p->avail = JK_TRUE; JK_LEAVE_CS(&w->cs); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "recycling connection pool for worker %s and socket %d", p->worker->name, (int)p->sd); JK_TRACE_EXIT(l); return JK_TRUE; } JK_LOG_NULL_PARAMS(l); JK_TRACE_EXIT(l); return JK_FALSE; } int ajp_get_endpoint(jk_worker_t *pThis, jk_endpoint_t **je, jk_logger_t *l, int proto) { JK_TRACE_ENTER(l); if (pThis && pThis->worker_private && je) { ajp_worker_t *aw = pThis->worker_private; ajp_endpoint_t *ae = NULL; int retry = 0; *je = NULL; /* Loop until cache_acquire_timeout interval elapses */ while ((retry * JK_SLEEP_DEF) < aw->cache_acquire_timeout) { unsigned int slot; JK_ENTER_CS(&aw->cs); /* Try to find connected socket cache entry */ for (slot = 0; slot < aw->ep_cache_sz; slot++) { if (IS_SLOT_AVAIL(aw->ep_cache[slot]) && IS_VALID_SOCKET(aw->ep_cache[slot]->sd)) { ae = aw->ep_cache[slot]; if (ae->reuse) { aw->ep_cache[slot]->avail = JK_FALSE; break; } else { /* XXX: We shouldn't have non reusable * opened socket in the cache */ ajp_reset_endpoint(ae, l); ae->avail = JK_TRUE; ae = NULL; jk_log(l, JK_LOG_WARNING, "(%s) closing non reusable pool slot=%d", aw->name, slot); } } } if (!ae) { /* No connected cache entry found. * Use the first free one. */ for (slot = 0; slot < aw->ep_cache_sz; slot++) { if (IS_SLOT_AVAIL(aw->ep_cache[slot])) { ae = aw->ep_cache[slot]; aw->ep_cache[slot]->avail = JK_FALSE; break; } } } JK_LEAVE_CS(&aw->cs); if (ae) { if (aw->cache_timeout > 0) ae->last_access = time(NULL); *je = &ae->endpoint; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) acquired connection pool slot=%u after %d retries", aw->name, slot, retry); JK_TRACE_EXIT(l); return JK_TRUE; } else { retry++; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "could not get free endpoint for worker %s" " (retry %d, sleeping for %d ms)", aw->name, retry, JK_SLEEP_DEF); jk_sleep(JK_SLEEP_DEF); } } jk_log(l, JK_LOG_WARNING, "Unable to get the free endpoint for worker %s from %u slots", aw->name, aw->ep_cache_sz); } else { JK_LOG_NULL_PARAMS(l); } JK_TRACE_EXIT(l); return JK_FALSE; } int JK_METHOD ajp_maintain(jk_worker_t *pThis, time_t mstarted, int global, jk_logger_t *l) { JK_TRACE_ENTER(l); if (pThis && pThis->worker_private) { ajp_worker_t *aw = pThis->worker_private; int i; unsigned int n = 0, k = 0, cnt = 0; unsigned int m, m_count = 0; jk_sock_t *m_sock; /* Do connection pool maintenance only if timeouts or keepalives are set */ if (aw->cache_timeout <= 0 && aw->conn_ping_interval <= 0) { /* Nothing to do. */ JK_TRACE_EXIT(l); return JK_TRUE; } JK_ENTER_CS(&aw->cs); /* Count open slots */ for (i = (int)aw->ep_cache_sz - 1; i >= 0; i--) { if (aw->ep_cache[i] && IS_VALID_SOCKET(aw->ep_cache[i]->sd)) cnt++; } m_sock = (jk_sock_t *)malloc((cnt + 1) * sizeof(jk_sock_t)); /* Handle worker cache timeouts */ if (aw->cache_timeout > 0) { for (i = (int)aw->ep_cache_sz - 1; i >= 0; i--) { /* Skip the closed sockets */ if (IS_SLOT_AVAIL(aw->ep_cache[i]) && IS_VALID_SOCKET(aw->ep_cache[i]->sd)) { int elapsed = (int)difftime(mstarted, aw->ep_cache[i]->last_access); if (elapsed > aw->cache_timeout) { time_t rt = 0; n++; if (JK_IS_DEBUG_LEVEL(l)) rt = time(NULL); aw->ep_cache[i]->reuse = JK_FALSE; m_sock[m_count++] = aw->ep_cache[i]->sd; aw->ep_cache[i]->sd = JK_INVALID_SOCKET; ajp_reset_endpoint(aw->ep_cache[i], l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) cleaning pool slot=%d elapsed %d in %d", aw->name, i, elapsed, (int)(difftime(time(NULL), rt))); } } if (cnt <= aw->ep_mincache_sz + n) { if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "(%s) reached pool min size %u from %u cache slots", aw->name, aw->ep_mincache_sz, aw->ep_cache_sz); } break; } } } /* Handle worker connection keepalive */ if (aw->conn_ping_interval > 0 && aw->ping_timeout > 0) { for (i = (int)aw->ep_cache_sz - 1; i >= 0; i--) { /* Skip the closed sockets */ if (IS_SLOT_AVAIL(aw->ep_cache[i]) && IS_VALID_SOCKET(aw->ep_cache[i]->sd)) { int elapsed = (int)difftime(mstarted, aw->ep_cache[i]->last_access); if (elapsed > aw->conn_ping_interval) { k++; /* handle cping/cpong. */ if (ajp_handle_cping_cpong(aw->ep_cache[i], aw->ping_timeout, l) == JK_FALSE) { jk_log(l, JK_LOG_INFO, "(%s) failed sending request, " "socket %d keepalive cping/cpong " "failure (errno=%d)", aw->name, aw->ep_cache[i]->sd, aw->ep_cache[i]->last_errno); aw->ep_cache[i]->reuse = JK_FALSE; m_sock[m_count++] = aw->ep_cache[i]->sd; aw->ep_cache[i]->sd = JK_INVALID_SOCKET; ajp_reset_endpoint(aw->ep_cache[i], l); } } } } } JK_LEAVE_CS(&aw->cs); /* Shutdown sockets outside of the lock. * This has benefits only if maintain was * called from the watchdog thread. */ for (m = 0; m < m_count; m++) { if (IS_VALID_SOCKET(m_sock[m])) { jk_shutdown_socket(m_sock[m], l); JK_ATOMIC_DECREMENT(&(aw->s->connected)); } } free(m_sock); if ((k + n) && JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) pinged %u and recycled %u sockets in %d seconds from %u pool slots", aw->name, k, n, (int)(difftime(time(NULL), mstarted)), aw->ep_cache_sz); JK_TRACE_EXIT(l); return JK_TRUE; } else { JK_LOG_NULL_PARAMS(l); } JK_TRACE_EXIT(l); return JK_FALSE; } int JK_METHOD ajp_shutdown(jk_worker_t *pThis, jk_logger_t *l) { JK_TRACE_ENTER(l); if (pThis && pThis->worker_private) { ajp_worker_t *aw = pThis->worker_private; int i; unsigned int n = 0; JK_ENTER_CS(&aw->cs); for (i = (int)aw->ep_cache_sz - 1; i >= 0; i--) { /* Skip the closed sockets */ if (IS_SLOT_AVAIL(aw->ep_cache[i]) && IS_VALID_SOCKET(aw->ep_cache[i]->sd)) { n++; aw->ep_cache[i]->reuse = JK_FALSE; aw->ep_cache[i]->hard_close = JK_TRUE; ajp_reset_endpoint(aw->ep_cache[i], l); aw->ep_cache[i]->sd = JK_INVALID_SOCKET; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) shut down pool slot=%d", aw->name, i); } } JK_LEAVE_CS(&aw->cs); if (n && JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "(%s) shut down %u sockets from %u pool slots", aw->name, n, aw->ep_cache_sz); JK_TRACE_EXIT(l); return JK_TRUE; } else { JK_LOG_NULL_PARAMS(l); } JK_TRACE_EXIT(l); return JK_FALSE; } int ajp_has_endpoint(jk_worker_t *pThis, jk_logger_t *l) { JK_TRACE_ENTER(l); if (pThis && pThis->worker_private) { ajp_worker_t *aw = pThis->worker_private; unsigned int slot; JK_ENTER_CS(&aw->cs); /* Try to find connected socket cache entry */ for (slot = 0; slot < aw->ep_cache_sz; slot++) { if (IS_SLOT_AVAIL(aw->ep_cache[slot])) { JK_LEAVE_CS(&aw->cs); return JK_TRUE; } } JK_LEAVE_CS(&aw->cs); } else { JK_LOG_NULL_PARAMS(l); } JK_TRACE_EXIT(l); return JK_FALSE; } tomcat-connectors-1.2.41-src/native/common/jk_status.c0000644000000000000020000067464612477544555021315 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Status worker, display and manages JK workers * * Author: Mladen Turk * * Author: Rainer Jung * * Version: $Revision: 1665454 $ * ***************************************************************************/ #include "jk_pool.h" #include "jk_service.h" #include "jk_util.h" #include "jk_worker.h" #include "jk_status.h" #include "jk_mt.h" #include "jk_shm.h" #include "jk_ajp_common.h" #include "jk_lb_worker.h" #include "jk_ajp13_worker.h" #include "jk_ajp14_worker.h" #include "jk_connect.h" #include "jk_uri_worker_map.h" #include "jk_url.h" #define HUGE_BUFFER_SIZE (8*1024) /** * Command line reference: * cmd=list (default) display configuration * cmd=show display detailed configuration * cmd=edit form to change configuration * cmd=update commit update configuration * cmd=reset reset lb runtime states, or lb member runtime states * cmd=version show only software version * Query arguments: * re=n (refresh time in seconds, n=0: disabled) * w=worker (cmd should be executed for worker "worker") * sw=sub_worker (cmd should be executed for "sub_worker" of worker "worker") * from=lastcmd (the last viewing command was "lastcmd") * opt=option (changes meaning of edit and list/show) */ #define JK_STATUS_ARG_CMD "cmd" #define JK_STATUS_ARG_MIME "mime" #define JK_STATUS_ARG_FROM "from" #define JK_STATUS_ARG_REFRESH "re" #define JK_STATUS_ARG_WORKER "w" #define JK_STATUS_ARG_SUB_WORKER "sw" #define JK_STATUS_ARG_PREV_SUB_WORKER "psw" #define JK_STATUS_ARG_ATTRIBUTE "att" #define JK_STATUS_ARG_MULT_VALUE_BASE "val" #define JK_STATUS_ARG_OPTIONS "opt" #define JK_STATUS_ARG_OPTION_NO_MEMBERS 0x0001 #define JK_STATUS_ARG_OPTION_NO_MAPS 0x0002 #define JK_STATUS_ARG_OPTION_NO_LEGEND 0x0004 #define JK_STATUS_ARG_OPTION_NO_LB 0x0008 #define JK_STATUS_ARG_OPTION_NO_AJP 0x0010 #define JK_STATUS_ARG_OPTION_READ_ONLY 0x0020 #define JK_STATUS_ARG_OPTION_NO_LB_CONF 0x0040 #define JK_STATUS_ARG_OPTION_NO_LB_SUMMARY 0x0080 #define JK_STATUS_ARG_OPTION_NO_AJP_CONF 0x0100 #define JK_STATUS_ARG_LB_RETRIES ("vlr") #define JK_STATUS_ARG_LB_RETRY_INT ("vlri") #define JK_STATUS_ARG_LB_RECOVER_TIME ("vlt") #define JK_STATUS_ARG_LB_ERROR_ESCALATION_TIME ("vlee") #define JK_STATUS_ARG_LB_MAX_REPLY_TIMEOUTS ("vlx") #define JK_STATUS_ARG_LB_STICKY ("vls") #define JK_STATUS_ARG_LB_STICKY_FORCE ("vlf") #define JK_STATUS_ARG_LB_METHOD ("vlm") #define JK_STATUS_ARG_LB_LOCK ("vll") #define JK_STATUS_ARG_LB_TEXT_RETRIES "Retries" #define JK_STATUS_ARG_LB_TEXT_RETRY_INT "Retry Interval" #define JK_STATUS_ARG_LB_TEXT_RECOVER_TIME "Recover Wait Time" #define JK_STATUS_ARG_LB_TEXT_ERROR_ESCALATION_TIME "Error Escalation Time" #define JK_STATUS_ARG_LB_TEXT_MAX_REPLY_TIMEOUTS "Max Reply Timeouts" #define JK_STATUS_ARG_LB_TEXT_STICKY "Sticky Sessions" #define JK_STATUS_ARG_LB_TEXT_STICKY_FORCE "Force Sticky Sessions" #define JK_STATUS_ARG_LB_TEXT_METHOD "LB Method" #define JK_STATUS_ARG_LB_TEXT_LOCK "Locking" #define JK_STATUS_ARG_LB_HEAD_RETRIES "Retries" #define JK_STATUS_ARG_LB_HEAD_RETRY_INT "Retry
Interval" #define JK_STATUS_ARG_LB_HEAD_RECOVER_TIME "Recover
Wait Time" #define JK_STATUS_ARG_LB_HEAD_ERROR_ESCALATION_TIME "Error
Escalation Time" #define JK_STATUS_ARG_LB_HEAD_MAX_REPLY_TIMEOUTS "Max Reply
Timeouts" #define JK_STATUS_ARG_LB_HEAD_STICKY "Sticky
Sessions" #define JK_STATUS_ARG_LB_HEAD_STICKY_FORCE "Force Sticky
Sessions" #define JK_STATUS_ARG_LB_HEAD_METHOD "LB
Method" #define JK_STATUS_ARG_LB_HEAD_LOCK "Locking" #define JK_STATUS_ARG_LBM_ACTIVATION ("vwa") #define JK_STATUS_ARG_LBM_FACTOR ("vwf") #define JK_STATUS_ARG_LBM_ROUTE ("vwn") #define JK_STATUS_ARG_LBM_REDIRECT ("vwr") #define JK_STATUS_ARG_LBM_DOMAIN ("vwc") #define JK_STATUS_ARG_LBM_DISTANCE ("vwd") #define JK_STATUS_ARG_LBM_TEXT_ACTIVATION "Activation" #define JK_STATUS_ARG_LBM_TEXT_FACTOR "LB Factor" #define JK_STATUS_ARG_LBM_TEXT_ROUTE "Route" #define JK_STATUS_ARG_LBM_TEXT_REDIRECT "Redirect Route" #define JK_STATUS_ARG_LBM_TEXT_DOMAIN "Cluster Domain" #define JK_STATUS_ARG_LBM_TEXT_DISTANCE "Distance" #define JK_STATUS_ARG_LBM_HEAD_ACTIVATION "Activation" #define JK_STATUS_ARG_LBM_HEAD_FACTOR "LB
Factor" #define JK_STATUS_ARG_LBM_HEAD_ROUTE "Route" #define JK_STATUS_ARG_LBM_HEAD_REDIRECT "Redirect
Route" #define JK_STATUS_ARG_LBM_HEAD_DOMAIN "Cluster
Domain" #define JK_STATUS_ARG_LBM_HEAD_DISTANCE "Distance" #define JK_STATUS_ARG_AJP_CACHE_TO "vacpt" #define JK_STATUS_ARG_AJP_PING_TO "vapng" #define JK_STATUS_ARG_AJP_CONNECT_TO "vact" #define JK_STATUS_ARG_AJP_PREPOST_TO "vapt" #define JK_STATUS_ARG_AJP_REPLY_TO "vart" #define JK_STATUS_ARG_AJP_RETRIES "var" #define JK_STATUS_ARG_AJP_RETRY_INT "vari" #define JK_STATUS_ARG_AJP_REC_OPTS "varo" #define JK_STATUS_ARG_AJP_BUSY_LIMIT "vabl" #define JK_STATUS_ARG_AJP_MAX_PK_SZ "vamps" #define JK_STATUS_ARG_AJP_CPING_INT "vacpi" #define JK_STATUS_ARG_AJP_HOST_STR "vahst" #define JK_STATUS_ARG_AJP_PORT "vaprt" #define JK_STATUS_ARG_AJP_TEXT_CACHE_TO "Connection Pool Timeout" #define JK_STATUS_ARG_AJP_TEXT_PING_TO "Ping Timeout" #define JK_STATUS_ARG_AJP_TEXT_CONNECT_TO "Connect Timeout" #define JK_STATUS_ARG_AJP_TEXT_PREPOST_TO "Prepost Timeout" #define JK_STATUS_ARG_AJP_TEXT_REPLY_TO "Reply Timeout" #define JK_STATUS_ARG_AJP_TEXT_RETRIES "Retries" #define JK_STATUS_ARG_AJP_TEXT_RETRY_INT "Retry Interval" #define JK_STATUS_ARG_AJP_TEXT_REC_OPTS "Recovery Options" #define JK_STATUS_ARG_AJP_TEXT_BUSY_LIMIT "Busy Limit" #define JK_STATUS_ARG_AJP_TEXT_MAX_PK_SZ "Max Packet Size" #define JK_STATUS_ARG_AJP_TEXT_CPING_INT "Connection Ping Interval" #define JK_STATUS_ARG_AJP_TEXT_HOST_STR "Hostname" #define JK_STATUS_ARG_AJP_TEXT_PORT "Port" #define JK_STATUS_ARG_AJP_TEXT_ADDR_STR "Address:Port" #define JK_STATUS_ARG_AJP_TEXT_SOURCE_STR "Source" #define JK_STATUS_ARG_AJP_HEAD_CACHE_TO "Connection
Pool Timeout" #define JK_STATUS_ARG_AJP_HEAD_PING_TO "Ping
Timeout" #define JK_STATUS_ARG_AJP_HEAD_CONNECT_TO "Connect
Timeout" #define JK_STATUS_ARG_AJP_HEAD_PREPOST_TO "Prepost
Timeout" #define JK_STATUS_ARG_AJP_HEAD_REPLY_TO "Reply
Timeout" #define JK_STATUS_ARG_AJP_HEAD_RETRIES "Retries" #define JK_STATUS_ARG_AJP_HEAD_RETRY_INT "Retry
Interval" #define JK_STATUS_ARG_AJP_HEAD_REC_OPTS "Recovery
Options" #define JK_STATUS_ARG_AJP_HEAD_BUSY_LIMIT "Busy
Limit" #define JK_STATUS_ARG_AJP_HEAD_MAX_PK_SZ "Max Packet
Size" #define JK_STATUS_ARG_AJP_HEAD_CPING_INT "Connection
Ping Interval" #define JK_STATUS_ARG_AJP_HEAD_HOST_STR "Hostname" #define JK_STATUS_ARG_AJP_HEAD_PORT "Port" #define JK_STATUS_ARG_AJP_HEAD_ADDR_STR "Address:Port" #define JK_STATUS_ARG_AJP_HEAD_SOURCE_STR "Source" #define JK_STATUS_CMD_UNKNOWN (0) #define JK_STATUS_CMD_LIST (1) #define JK_STATUS_CMD_SHOW (2) #define JK_STATUS_CMD_EDIT (3) #define JK_STATUS_CMD_UPDATE (4) #define JK_STATUS_CMD_RESET (5) #define JK_STATUS_CMD_VERSION (6) #define JK_STATUS_CMD_RECOVER (7) #define JK_STATUS_CMD_DUMP (8) #define JK_STATUS_CMD_DEF (JK_STATUS_CMD_LIST) #define JK_STATUS_CMD_MAX (JK_STATUS_CMD_DUMP) #define JK_STATUS_CMD_TEXT_UNKNOWN ("unknown") #define JK_STATUS_CMD_TEXT_LIST ("list") #define JK_STATUS_CMD_TEXT_SHOW ("show") #define JK_STATUS_CMD_TEXT_EDIT ("edit") #define JK_STATUS_CMD_TEXT_UPDATE ("update") #define JK_STATUS_CMD_TEXT_RESET ("reset") #define JK_STATUS_CMD_TEXT_VERSION ("version") #define JK_STATUS_CMD_TEXT_RECOVER ("recover") #define JK_STATUS_CMD_TEXT_DUMP ("dump") #define JK_STATUS_CMD_TEXT_DEF (JK_STATUS_CMD_TEXT_LIST) #define JK_STATUS_CMD_PROP_CHECK_WORKER 0x00000001 #define JK_STATUS_CMD_PROP_READONLY 0x00000002 #define JK_STATUS_CMD_PROP_HEAD 0x00000004 #define JK_STATUS_CMD_PROP_REFRESH 0x00000008 #define JK_STATUS_CMD_PROP_BACK_LINK 0x00000010 #define JK_STATUS_CMD_PROP_BACK_LIST 0x00000020 #define JK_STATUS_CMD_PROP_FMT 0x00000040 #define JK_STATUS_CMD_PROP_SWITCH_RO 0x00000080 #define JK_STATUS_CMD_PROP_DUMP_LINK 0x00000100 #define JK_STATUS_CMD_PROP_LINK_HELP 0x00000200 #define JK_STATUS_CMD_PROP_LEGEND 0x00000400 #define JK_STATUS_CMD_PROP_WILDCARD 0x00000800 #define JK_STATUS_MIME_UNKNOWN (0) #define JK_STATUS_MIME_HTML (1) #define JK_STATUS_MIME_XML (2) #define JK_STATUS_MIME_TXT (3) #define JK_STATUS_MIME_PROP (4) #define JK_STATUS_MIME_DEF (JK_STATUS_MIME_HTML) #define JK_STATUS_MIME_MAX (JK_STATUS_MIME_PROP) #define JK_STATUS_MIME_TEXT_UNKNOWN ("unknown") #define JK_STATUS_MIME_TEXT_HTML ("html") #define JK_STATUS_MIME_TEXT_XML ("xml") #define JK_STATUS_MIME_TEXT_TXT ("txt") #define JK_STATUS_MIME_TEXT_PROP ("prop") #define JK_STATUS_MIME_TEXT_DEF (JK_STATUS_MIME_TEXT_HTML) #define JK_STATUS_MASK_ACTIVE 0x000000FF #define JK_STATUS_MASK_DISABLED 0x0000FF00 #define JK_STATUS_MASK_STOPPED 0x00FF0000 #define JK_STATUS_MASK_OK 0x00010101 #define JK_STATUS_MASK_IDLE 0x00020202 #define JK_STATUS_MASK_BUSY 0x00040404 #define JK_STATUS_MASK_RECOVER 0x00080808 #define JK_STATUS_MASK_ERROR 0x00101010 #define JK_STATUS_MASK_GOOD_DEF 0x0000000F #define JK_STATUS_MASK_BAD_DEF 0x00FF1010 #define JK_STATUS_NEEDS_PUSH 0x00000001 #define JK_STATUS_NEEDS_RESET_LB_VALUES 0x00000002 #define JK_STATUS_NEEDS_UPDATE_MULT 0x00000004 #define JK_STATUS_NEEDS_ADDR_PUSH 0x00000008 #define JK_STATUS_WAIT_AFTER_UPDATE "3" #define JK_STATUS_REFRESH_DEF "10" #define JK_STATUS_ESC_CHARS ("<>?\"") #define JK_STATUS_TIME_FMT_HTML "%Y-%m-%d %H:%M:%S %z" #define JK_STATUS_TIME_FMT_TEXT "%Y%m%d%H%M%S" #define JK_STATUS_TIME_FMT_TZ "%z" #define JK_STATUS_TIME_BUF_SZ (30) #define JK_STATUS_HEAD "\n" \ "\n" \ "" \ "JK Status Manager" #define JK_STATUS_COPYRIGHT "Copyright © 1999-2015, The Apache Software Foundation
" \ "Licensed under the
" \ "Apache License, Version 2.0." #define JK_STATUS_HEND "\n\n" #define JK_STATUS_BEND "\n\n" #define JK_STATUS_XMLH "\n" #define JK_STATUS_NS_DEF "jk:" #define JK_STATUS_XMLNS_DEF "xmlns:jk=\"http://tomcat.apache.org\"" #define JK_STATUS_PREFIX_DEF "worker" #define JK_STATUS_FORM_START "
\n" #define JK_STATUS_FORM_HIDDEN_INT "\n" #define JK_STATUS_FORM_HIDDEN_STRING "\n" #define JK_STATUS_URI_MAP_TABLE_HEAD "%s%s%s%s%s%s%s%s%s%s%s\n" #define JK_STATUS_URI_MAP_TABLE_ROW "%s%s%s%d%d%d%s%s%s%s%d\n" #define JK_STATUS_URI_MAP_TABLE_HEAD2 "%s%s%s%s%s%s%s%s%s%s%s%s\n" #define JK_STATUS_URI_MAP_TABLE_ROW2 "%s%s%s%s%d%d%d%s%s%s%s%d\n" #define JK_STATUS_SHOW_AJP_CONF_HEAD "" \ "Type" \ "" JK_STATUS_ARG_AJP_HEAD_HOST_STR "" \ "" JK_STATUS_ARG_AJP_HEAD_ADDR_STR "" \ "" JK_STATUS_ARG_AJP_HEAD_SOURCE_STR "" \ "" JK_STATUS_ARG_AJP_HEAD_CACHE_TO "" \ "" JK_STATUS_ARG_AJP_HEAD_CONNECT_TO "" \ "" JK_STATUS_ARG_AJP_HEAD_PREPOST_TO "" \ "" JK_STATUS_ARG_AJP_HEAD_REPLY_TO "" \ "" JK_STATUS_ARG_AJP_HEAD_RETRIES "" \ "" JK_STATUS_ARG_AJP_HEAD_REC_OPTS "" \ "" JK_STATUS_ARG_AJP_HEAD_BUSY_LIMIT "" \ "" JK_STATUS_ARG_AJP_HEAD_MAX_PK_SZ "" \ "\n" #define JK_STATUS_SHOW_AJP_CONF_ROW "" \ "%s" \ "%s" \ "%s" \ "%s" \ "%d" \ "%d" \ "%d" \ "%d" \ "%u" \ "%d" \ "%u" \ "" \ "\n" #define JK_STATUS_SHOW_AJP_HEAD "" \ "State" \ "Acc" \ "ErrCERE" \ "WrRdBusyMaxBusyConMaxConLRLE" \ "\n" #define JK_STATUS_SHOW_AJP_ROW "" \ "%s" \ "%" JK_UINT64_T_FMT " (%d/sec)" \ "%" JK_UINT32_T_FMT "" \ "%" JK_UINT32_T_FMT "" \ "%" JK_UINT32_T_FMT "" \ "%s (%s/sec)" \ "%s (%s/sec)" \ "%d" \ "%d" \ "%d" \ "%d" \ "%d" \ "%s" \ "\n" #define JK_STATUS_SHOW_LB_HEAD "" \ "Type" \ "" JK_STATUS_ARG_LB_HEAD_STICKY "" \ "" JK_STATUS_ARG_LB_HEAD_STICKY_FORCE "" \ "" JK_STATUS_ARG_LB_HEAD_RETRIES "" \ "" JK_STATUS_ARG_LB_HEAD_METHOD "" \ "" JK_STATUS_ARG_LB_HEAD_LOCK "" \ "" JK_STATUS_ARG_LB_HEAD_RECOVER_TIME "" \ "" JK_STATUS_ARG_LB_HEAD_ERROR_ESCALATION_TIME "" \ "" JK_STATUS_ARG_LB_HEAD_MAX_REPLY_TIMEOUTS "" \ "\n" #define JK_STATUS_SHOW_LB_ROW "" \ "%s" \ "%s" \ "%s" \ "%d" \ "%s" \ "%s" \ "%d" \ "%d" \ "%d" \ "" \ "\n" #define JK_STATUS_SHOW_MEMBER_HEAD "" \ " Name" \ "ActState" \ "DFM" \ "VAccSess" \ "ErrCERE" \ "WrRdBusyMaxBusyConMaxCon" \ "" JK_STATUS_ARG_LBM_HEAD_ROUTE "" \ "RRCdRsLRLE" \ "\n" #define JK_STATUS_SHOW_MEMBER_ROW "%s" \ "%s" \ "%s" \ "%d" \ "%d" \ "%" JK_UINT64_T_FMT "" \ "%" JK_UINT64_T_FMT "" \ "%" JK_UINT64_T_FMT " (%d/sec)" \ "%" JK_UINT64_T_FMT " (%d/sec)" \ "%" JK_UINT32_T_FMT "" \ "%" JK_UINT32_T_FMT "" \ "%" JK_UINT32_T_FMT "" \ "%s (%s/sec)" \ "%s (%s/sec)" \ "%d" \ "%d" \ "%d" \ "%d" \ "%s" \ "%s" \ "%s" \ "%d/%d" \ "%d" \ "%s" \ "\n" #define JK_STATUS_SHOW_MEMBER_CONF_HEAD "" \ "NameType" \ "" JK_STATUS_ARG_AJP_HEAD_HOST_STR "" \ "" JK_STATUS_ARG_AJP_HEAD_ADDR_STR "" \ "" JK_STATUS_ARG_AJP_HEAD_SOURCE_STR "" \ "" JK_STATUS_ARG_AJP_HEAD_CACHE_TO "" \ "" JK_STATUS_ARG_AJP_HEAD_CONNECT_TO "" \ "" JK_STATUS_ARG_AJP_HEAD_PREPOST_TO "" \ "" JK_STATUS_ARG_AJP_HEAD_REPLY_TO "" \ "" JK_STATUS_ARG_AJP_HEAD_RETRIES "" \ "" JK_STATUS_ARG_AJP_HEAD_REC_OPTS "" \ "" JK_STATUS_ARG_AJP_HEAD_BUSY_LIMIT "" \ "" JK_STATUS_ARG_AJP_HEAD_MAX_PK_SZ "" \ "\n" #define JK_STATUS_SHOW_MEMBER_CONF_ROW "" \ "%s" \ "%s" \ "%s" \ "%s" \ "%s" \ "%d" \ "%d" \ "%d" \ "%d" \ "%d" \ "%u" \ "%d" \ "%u" \ "" \ "\n" typedef struct status_worker status_worker_t; struct status_endpoint { status_worker_t *worker; char *query_string; jk_map_t *req_params; char *msg; jk_endpoint_t endpoint; }; typedef struct status_endpoint status_endpoint_t; struct status_worker { jk_pool_t p; jk_pool_atom_t buf[TINY_POOL_SIZE]; const char *name; const char *css; const char *ns; const char *xmlns; const char *doctype; const char *prefix; int read_only; char **user_names; unsigned int num_of_users; int user_case_insensitive; jk_uint32_t good_mask; jk_uint32_t bad_mask; jk_worker_t worker; jk_worker_env_t *we; }; static const char *worker_type[] = { "unknown", "ajp12", "ajp13", "ajp14", "jni", "lb", "status", NULL }; static const char *headers_names[] = { "Content-Type", "Cache-Control", "Pragma", NULL }; static const char *cmd_type[] = { JK_STATUS_CMD_TEXT_UNKNOWN, JK_STATUS_CMD_TEXT_LIST, JK_STATUS_CMD_TEXT_SHOW, JK_STATUS_CMD_TEXT_EDIT, JK_STATUS_CMD_TEXT_UPDATE, JK_STATUS_CMD_TEXT_RESET, JK_STATUS_CMD_TEXT_VERSION, JK_STATUS_CMD_TEXT_RECOVER, JK_STATUS_CMD_TEXT_DUMP, NULL }; static const char *mime_type[] = { JK_STATUS_MIME_TEXT_UNKNOWN, JK_STATUS_MIME_TEXT_HTML, JK_STATUS_MIME_TEXT_XML, JK_STATUS_MIME_TEXT_TXT, JK_STATUS_MIME_TEXT_PROP, NULL }; #define HEADERS_NO_CACHE "no-cache", "no-cache", NULL static const char *headers_vhtml[] = { "text/html", HEADERS_NO_CACHE }; static const char *headers_vxml[] = { "text/xml", HEADERS_NO_CACHE }; static const char *headers_vtxt[] = { "text/plain", HEADERS_NO_CACHE }; static void jk_puts(jk_ws_service_t *s, const char *str) { if (str) s->write(s, str, (unsigned int)strlen(str)); else s->write(s, "(null)", 6); } static void jk_putv(jk_ws_service_t *s, ...) { va_list va; const char *str; va_start(va, s); while (1) { str = va_arg(va, const char *); if (str == NULL) break; s->write(s, str, (unsigned int)strlen(str)); } va_end(va); } static int jk_printf(jk_ws_service_t *s, jk_logger_t *l, const char *fmt, ...) { int rc = 0; va_list args; #ifdef NETWARE /* On NetWare, this can get called on a thread that has a limited stack so */ /* we will allocate and free the temporary buffer in this function */ char *buf; #else char buf[HUGE_BUFFER_SIZE]; #endif if (!s || !fmt) { return -1; } va_start(args, fmt); #ifdef NETWARE buf = (char *)malloc(HUGE_BUFFER_SIZE); if (NULL == buf) return -1; #endif rc = vsnprintf(buf, HUGE_BUFFER_SIZE, fmt, args); va_end(args); if (rc > 0 && rc < HUGE_BUFFER_SIZE) s->write(s, buf, rc); else jk_log(l, JK_LOG_WARNING, "Insufficient buffer size %d in status worker, some output was dropped", HUGE_BUFFER_SIZE); #ifdef NETWARE free(buf); #endif return rc; } static void jk_print_xml_start_elt(jk_ws_service_t *s, jk_logger_t *l, status_worker_t *w, int indentation, int close_tag, const char *name) { if (close_tag) { jk_printf(s, l, "%*s<%s%s>\n", indentation, "", w->ns, name); } else { jk_printf(s, l, "%*s<%s%s\n", indentation, "", w->ns, name); } } static void jk_print_xml_close_elt(jk_ws_service_t *s, jk_logger_t *l, status_worker_t *w, int indentation, const char *name) { jk_printf(s, l, "%*s\n", indentation, "", w->ns, name); } static void jk_print_xml_stop_elt(jk_ws_service_t *s, jk_logger_t *l, int indentation, int close_tag) { if (close_tag) { jk_printf(s, l, "%*s/>\n", indentation, ""); } else { jk_printf(s, l, "%*s>\n", indentation, ""); } } static void jk_print_xml_att_string(jk_ws_service_t *s, jk_logger_t *l, int indentation, const char *key, const char *value) { jk_printf(s, l, "%*s%s=\"%s\"\n", indentation, "", key, value ? value : ""); } static void jk_print_xml_att_int(jk_ws_service_t *s, jk_logger_t *l, int indentation, const char *key, int value) { jk_printf(s, l, "%*s%s=\"%d\"\n", indentation, "", key, value); } static void jk_print_xml_att_uint(jk_ws_service_t *s, jk_logger_t *l, int indentation, const char *key, unsigned int value) { jk_printf(s, l, "%*s%s=\"%u\"\n", indentation, "", key, value); } static void jk_print_xml_att_long(jk_ws_service_t *s, jk_logger_t *l, int indentation, const char *key, long value) { jk_printf(s, l, "%*s%s=\"%ld\"\n", indentation, "", key, value); } static void jk_print_xml_att_uint32(jk_ws_service_t *s, jk_logger_t *l, int indentation, const char *key, jk_uint32_t value) { jk_printf(s, l, "%*s%s=\"%" JK_UINT32_T_FMT "\"\n", indentation, "", key, value); } static void jk_print_xml_att_uint64(jk_ws_service_t *s, jk_logger_t *l, int indentation, const char *key, jk_uint64_t value) { jk_printf(s, l, "%*s%s=\"%" JK_UINT64_T_FMT "\"\n", indentation, "", key, value); } static void jk_print_prop_att_string(jk_ws_service_t *s, jk_logger_t *l, status_worker_t *w, const char *name, const char *key, const char *value) { if (name) { jk_printf(s, l, "%s.%s.%s=%s\n", w->prefix, name, key, value ? value : ""); } else { jk_printf(s, l, "%s.%s=%s\n", w->prefix, key, value ? value : ""); } } static void jk_print_prop_att_int(jk_ws_service_t *s, jk_logger_t *l, status_worker_t *w, const char *name, const char *key, int value) { if (name) { jk_printf(s, l, "%s.%s.%s=%d\n", w->prefix, name, key, value); } else { jk_printf(s, l, "%s.%s=%d\n", w->prefix, key, value); } } static void jk_print_prop_att_uint(jk_ws_service_t *s, jk_logger_t *l, status_worker_t *w, const char *name, const char *key, unsigned int value) { if (name) { jk_printf(s, l, "%s.%s.%s=%u\n", w->prefix, name, key, value); } else { jk_printf(s, l, "%s.%s=%u\n", w->prefix, key, value); } } static void jk_print_prop_att_long(jk_ws_service_t *s, jk_logger_t *l, status_worker_t *w, const char *name, const char *key, long value) { if (name) { jk_printf(s, l, "%s.%s.%s=%ld\n", w->prefix, name, key, value); } else { jk_printf(s, l, "%s.%s=%ld\n", w->prefix, key, value); } } static void jk_print_prop_att_uint32(jk_ws_service_t *s, jk_logger_t *l, status_worker_t *w, const char *name, const char *key, jk_uint32_t value) { if (name) { jk_printf(s, l, "%s.%s.%s=%" JK_UINT32_T_FMT "\n", w->prefix, name, key, value); } else { jk_printf(s, l, "%s.%s=%" JK_UINT32_T_FMT "\n", w->prefix, key, value); } } static void jk_print_prop_att_uint64(jk_ws_service_t *s, jk_logger_t *l, status_worker_t *w, const char *name, const char *key, jk_uint64_t value) { if (name) { jk_printf(s, l, "%s.%s.%s=%" JK_UINT64_T_FMT "\n", w->prefix, name, key, value); } else { jk_printf(s, l, "%s.%s=%" JK_UINT64_T_FMT "\n", w->prefix, key, value); } } static void jk_print_prop_item_int(jk_ws_service_t *s, jk_logger_t *l, status_worker_t *w, const char *name, const char *list, int num, const char *key, int value) { if (name) { jk_printf(s, l, "%s.%s.%s.%d.%s=%d\n", w->prefix, name, list, num, key, value); } else { jk_printf(s, l, "%s.%s.%d.%s=%d\n", w->prefix, list, num, key, value); } } static void jk_print_prop_item_string(jk_ws_service_t *s, jk_logger_t *l, status_worker_t *w, const char *name, const char *list, int num, const char *key, const char *value) { if (name) { jk_printf(s, l, "%s.%s.%s.%d.%s=%s\n", w->prefix, name, list, num, key, value ? value : ""); } else { jk_printf(s, l, "%s.%s.%d.%s=%s\n", w->prefix, list, num, key, value ? value : ""); } } /* Actually APR's apr_strfsize */ static char *status_strfsize(jk_uint64_t size, char *buf) { const char ord[] = "KMGTPE"; const char *o = ord; unsigned int remain, siz; if (size < 973) { if (sprintf(buf, "%d ", (int) size) < 0) return strcpy(buf, "****"); return buf; } do { remain = (unsigned int)(size & 0x03FF); size >>= 10; if (size >= 973) { ++o; continue; } siz = (unsigned int)(size & 0xFFFF); if (siz < 9 || (siz == 9 && remain < 973)) { if ((remain = ((remain * 5) + 256) / 512) >= 10) ++siz, remain = 0; if (sprintf(buf, "%d.%d%c", siz, remain, *o) < 0) return strcpy(buf, "****"); return buf; } if (remain >= 512) ++siz; if (sprintf(buf, "%d%c", siz, *o) < 0) return strcpy(buf, "****"); return buf; } while (1); } static int status_strftime(time_t clock, int mime, char *buf_time, char *buf_tz, jk_logger_t *l) { size_t rc_time; #ifdef _MT_CODE_PTHREAD struct tm res; struct tm *tms = localtime_r(&clock, &res); #else struct tm *tms = localtime(&clock); #endif JK_TRACE_ENTER(l); if (mime == JK_STATUS_MIME_HTML) rc_time = strftime(buf_time, JK_STATUS_TIME_BUF_SZ, JK_STATUS_TIME_FMT_HTML, tms); else { rc_time = strftime(buf_time, JK_STATUS_TIME_BUF_SZ, JK_STATUS_TIME_FMT_TEXT, tms); } strftime(buf_tz, JK_STATUS_TIME_BUF_SZ, JK_STATUS_TIME_FMT_TZ, tms); JK_TRACE_EXIT(l); return (int)rc_time; } static int status_rate(lb_sub_worker_t *wr, status_worker_t *w, jk_logger_t *l) { jk_uint32_t mask = 0; int activation = wr->activation; int state = wr->s->state; jk_uint32_t good = w->good_mask; jk_uint32_t bad = w->bad_mask; int rv = 0; switch (activation) { case JK_LB_ACTIVATION_ACTIVE: mask = JK_STATUS_MASK_ACTIVE; break; case JK_LB_ACTIVATION_DISABLED: mask = JK_STATUS_MASK_DISABLED; break; case JK_LB_ACTIVATION_STOPPED: mask = JK_STATUS_MASK_STOPPED; break; default: jk_log(l, JK_LOG_WARNING, "Status worker '%s' unknown activation type '%d'", w->name, activation); } switch (state) { case JK_LB_STATE_IDLE: mask &= JK_STATUS_MASK_IDLE; break; case JK_LB_STATE_OK: mask &= JK_STATUS_MASK_OK; break; case JK_LB_STATE_RECOVER: mask &= JK_STATUS_MASK_RECOVER; break; case JK_LB_STATE_FORCE: mask &= JK_STATUS_MASK_RECOVER; break; case JK_LB_STATE_BUSY: mask &= JK_STATUS_MASK_BUSY; break; case JK_LB_STATE_ERROR: mask &= JK_STATUS_MASK_ERROR; break; case JK_LB_STATE_PROBE: mask &= JK_STATUS_MASK_RECOVER; break; default: jk_log(l, JK_LOG_WARNING, "Status worker '%s' unknown state type '%d'", w->name, state); } if (mask&bad) rv = -1; else if (mask&good) rv = 1; else rv = 0; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' rating of activation '%s' and state '%s' for good '%08" JK_UINT32_T_HEX_FMT "' and bad '%08" JK_UINT32_T_HEX_FMT "' is %d", w->name, jk_lb_get_activation(wr, l), jk_lb_get_state(wr, l), good, bad, rv); return rv; } static jk_uint32_t status_get_single_rating(const char rating, jk_logger_t *l) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "rating retrieval for '%c'", rating); switch (rating) { case 'A': case 'a': return JK_STATUS_MASK_ACTIVE; case 'D': case 'd': return JK_STATUS_MASK_DISABLED; case 'S': case 's': return JK_STATUS_MASK_STOPPED; case 'O': case 'o': return JK_STATUS_MASK_OK; case 'I': case 'i': case 'N': case 'n': return JK_STATUS_MASK_IDLE; case 'B': case 'b': return JK_STATUS_MASK_BUSY; case 'R': case 'r': return JK_STATUS_MASK_RECOVER; case 'E': case 'e': return JK_STATUS_MASK_ERROR; default: jk_log(l, JK_LOG_WARNING, "Unknown rating type '%c'", rating); return 0; } } static jk_uint32_t status_get_rating(const char *rating, jk_logger_t *l) { int off = 0; jk_uint32_t mask = 0; while (rating[off] == ' ' || rating[off] == '\t' || rating[off] == '.') { off++; } mask = status_get_single_rating(rating[off], l); while (rating[off] != '\0' && rating[off] != '.') { off++; } if (rating[off] == '.') { off++; } if (rating[off] != '\0') { mask &= status_get_single_rating(rating[off], l); } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "rating for '%s' is '%08" JK_UINT32_T_HEX_FMT "'", rating, mask); return mask; } static const char *status_worker_type(int t) { if (t < 0 || t > 6) t = 0; return worker_type[t]; } static int status_get_string(status_endpoint_t *p, const char *param, const char *def, const char **result, jk_logger_t *l) { int rv; *result = jk_map_get_string(p->req_params, param, NULL); if (*result) { rv = JK_TRUE; } else { *result = def; rv = JK_FALSE; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "retrieved string arg '%s' as '%s'%s", param, *result ? *result : "(null)", rv == JK_FALSE ? " (default)" : ""); return rv; } static int status_get_int(status_endpoint_t *p, const char *param, int def, jk_logger_t *l) { const char *arg; int rv = def; if (status_get_string(p, param, NULL, &arg, l) == JK_TRUE) { rv = atoi(arg); } return rv; } static int status_get_bool(status_endpoint_t *p, const char *param, int def, jk_logger_t *l) { const char *arg; if (status_get_string(p, param, NULL, &arg, l) == JK_TRUE) { return jk_get_bool_code(arg, def); } return def; } static const char *status_cmd_text(int cmd) { return cmd_type[cmd]; } static int status_cmd_int(const char *cmd) { if (!cmd) return JK_STATUS_CMD_DEF; if (!strcmp(cmd, JK_STATUS_CMD_TEXT_LIST)) return JK_STATUS_CMD_LIST; else if (!strcmp(cmd, JK_STATUS_CMD_TEXT_SHOW)) return JK_STATUS_CMD_SHOW; else if (!strcmp(cmd, JK_STATUS_CMD_TEXT_EDIT)) return JK_STATUS_CMD_EDIT; else if (!strcmp(cmd, JK_STATUS_CMD_TEXT_UPDATE)) return JK_STATUS_CMD_UPDATE; else if (!strcmp(cmd, JK_STATUS_CMD_TEXT_RESET)) return JK_STATUS_CMD_RESET; else if (!strcmp(cmd, JK_STATUS_CMD_TEXT_VERSION)) return JK_STATUS_CMD_VERSION; else if (!strcmp(cmd, JK_STATUS_CMD_TEXT_RECOVER)) return JK_STATUS_CMD_RECOVER; else if (!strcmp(cmd, JK_STATUS_CMD_TEXT_DUMP)) return JK_STATUS_CMD_DUMP; return JK_STATUS_CMD_UNKNOWN; } static const char *status_mime_text(int mime) { return mime_type[mime]; } static int status_mime_int(const char *mime) { if (!mime) return JK_STATUS_MIME_DEF; if (!strcmp(mime, JK_STATUS_MIME_TEXT_HTML)) return JK_STATUS_MIME_HTML; else if (!strcmp(mime, JK_STATUS_MIME_TEXT_XML)) return JK_STATUS_MIME_XML; else if (!strcmp(mime, JK_STATUS_MIME_TEXT_TXT)) return JK_STATUS_MIME_TXT; else if (!strcmp(mime, JK_STATUS_MIME_TEXT_PROP)) return JK_STATUS_MIME_PROP; return JK_STATUS_MIME_UNKNOWN; } static jk_uint32_t status_cmd_props(int cmd) { jk_uint32_t props = 0; if (cmd == JK_STATUS_CMD_LIST || cmd == JK_STATUS_CMD_SHOW) props |= JK_STATUS_CMD_PROP_REFRESH | JK_STATUS_CMD_PROP_SWITCH_RO | JK_STATUS_CMD_PROP_LINK_HELP | JK_STATUS_CMD_PROP_LEGEND; if (cmd == JK_STATUS_CMD_LIST || cmd == JK_STATUS_CMD_SHOW || cmd == JK_STATUS_CMD_VERSION) props |= JK_STATUS_CMD_PROP_DUMP_LINK; if (cmd == JK_STATUS_CMD_LIST || cmd == JK_STATUS_CMD_SHOW || cmd == JK_STATUS_CMD_VERSION || cmd == JK_STATUS_CMD_DUMP) props |= JK_STATUS_CMD_PROP_HEAD | JK_STATUS_CMD_PROP_FMT; if (cmd == JK_STATUS_CMD_SHOW || cmd == JK_STATUS_CMD_VERSION || cmd == JK_STATUS_CMD_DUMP) props |= JK_STATUS_CMD_PROP_BACK_LIST; if (cmd == JK_STATUS_CMD_SHOW || cmd == JK_STATUS_CMD_EDIT || cmd == JK_STATUS_CMD_VERSION || cmd == JK_STATUS_CMD_DUMP) props |= JK_STATUS_CMD_PROP_BACK_LINK; if (cmd == JK_STATUS_CMD_UPDATE) props |= JK_STATUS_CMD_PROP_WILDCARD; if (cmd != JK_STATUS_CMD_EDIT && cmd != JK_STATUS_CMD_UPDATE && cmd != JK_STATUS_CMD_RESET && cmd != JK_STATUS_CMD_RECOVER) props |= JK_STATUS_CMD_PROP_READONLY; if (cmd != JK_STATUS_CMD_LIST && cmd != JK_STATUS_CMD_VERSION && cmd != JK_STATUS_CMD_DUMP) props |= JK_STATUS_CMD_PROP_CHECK_WORKER; return props; } static void status_start_form(jk_ws_service_t *s, status_endpoint_t *p, const char *method, int cmd, const char *overwrite, jk_logger_t *l) { int i; int sz; jk_map_t *m = p->req_params; if (method) jk_printf(s, l, JK_STATUS_FORM_START, method, s->req_uri); else return; if (cmd != JK_STATUS_CMD_UNKNOWN) { jk_printf(s, l, JK_STATUS_FORM_HIDDEN_STRING, JK_STATUS_ARG_CMD, status_cmd_text(cmd)); } sz = jk_map_size(m); for (i = 0; i < sz; i++) { const char *k = jk_map_name_at(m, i); const char *v = jk_map_value_at(m, i); if ((strcmp(k, JK_STATUS_ARG_CMD) || cmd == JK_STATUS_CMD_UNKNOWN) && (!overwrite || strcmp(k, overwrite))) { jk_printf(s, l, JK_STATUS_FORM_HIDDEN_STRING, k, v); } } } static void status_write_uri(jk_ws_service_t *s, status_endpoint_t *p, const char *text, int cmd, int mime, const char *worker, const char *sub_worker, unsigned int add_options, unsigned int rm_options, const char *attribute, jk_logger_t *l) { int i; int sz; int started = 0; int from; int restore_sub_worker = JK_FALSE; int save_sub_worker = JK_FALSE; int prev; unsigned int opt = 0; const char *arg; jk_map_t *m = p->req_params; if (text) jk_puts(s, "req_uri); status_get_string(p, JK_STATUS_ARG_FROM, NULL, &arg, l); from = status_cmd_int(arg); status_get_string(p, JK_STATUS_ARG_CMD, NULL, &arg, l); prev = status_cmd_int(arg); if (cmd == JK_STATUS_CMD_SHOW && prev == JK_STATUS_CMD_EDIT) { restore_sub_worker = JK_TRUE; } if (cmd == JK_STATUS_CMD_UNKNOWN) { if (prev == JK_STATUS_CMD_UPDATE || prev == JK_STATUS_CMD_RESET || prev == JK_STATUS_CMD_RECOVER) { cmd = from; restore_sub_worker = JK_TRUE; } } if (cmd != JK_STATUS_CMD_UNKNOWN) { jk_printf(s, l, "%s%s=%s", started ? "&" : "?", JK_STATUS_ARG_CMD, status_cmd_text(cmd)); if (cmd == JK_STATUS_CMD_EDIT || cmd == JK_STATUS_CMD_RESET || cmd == JK_STATUS_CMD_RECOVER) { jk_printf(s, l, "%s%s=%s", "&", JK_STATUS_ARG_FROM, status_cmd_text(prev)); save_sub_worker = JK_TRUE; } started=1; } if (mime != JK_STATUS_MIME_UNKNOWN) { jk_printf(s, l, "%s%s=%s", started ? "&" : "?", JK_STATUS_ARG_MIME, status_mime_text(mime)); started=1; } if (worker && worker[0]) { jk_printf(s, l, "%s%s=%s", started ? "&" : "?", JK_STATUS_ARG_WORKER, worker); started=1; } if (sub_worker && sub_worker[0] && cmd != JK_STATUS_CMD_LIST) { jk_printf(s, l, "%s%s=%s", started ? "&" : "?", JK_STATUS_ARG_SUB_WORKER, sub_worker); started=1; } if (attribute && attribute[0]) { jk_printf(s, l, "%s%s=%s", started ? "&" : "?", JK_STATUS_ARG_ATTRIBUTE, attribute); started=1; } sz = jk_map_size(m); for (i = 0; i < sz; i++) { const char *k = jk_map_name_at(m, i); const char *v = jk_map_value_at(m, i); if (!strcmp(k, JK_STATUS_ARG_CMD) && cmd != JK_STATUS_CMD_UNKNOWN) { continue; } if (!strcmp(k, JK_STATUS_ARG_MIME) && mime != JK_STATUS_MIME_UNKNOWN) { continue; } if (!strcmp(k, JK_STATUS_ARG_FROM)) { continue; } if (!strcmp(k, JK_STATUS_ARG_WORKER) && worker) { continue; } if (!strcmp(k, JK_STATUS_ARG_SUB_WORKER)) { if (save_sub_worker == JK_TRUE) { jk_printf(s, l, "%s%s=%s", started ? "&" : "?", JK_STATUS_ARG_PREV_SUB_WORKER, v); started=1; continue; } else if (sub_worker || cmd == JK_STATUS_CMD_LIST) { continue; } else if (restore_sub_worker == JK_TRUE) { continue; } } if (!strcmp(k, JK_STATUS_ARG_PREV_SUB_WORKER) && restore_sub_worker == JK_TRUE && cmd != JK_STATUS_CMD_LIST) { jk_printf(s, l, "%s%s=%s", started ? "&" : "?", JK_STATUS_ARG_SUB_WORKER, v); started=1; continue; } if (!strcmp(k, JK_STATUS_ARG_ATTRIBUTE) && attribute) { continue; } if (!strcmp(k, JK_STATUS_ARG_ATTRIBUTE) && cmd != JK_STATUS_CMD_UPDATE && cmd != JK_STATUS_CMD_EDIT) { continue; } if (!strncmp(k, JK_STATUS_ARG_MULT_VALUE_BASE, 3) && cmd != JK_STATUS_CMD_UPDATE) { continue; } if (k[0] == 'v' && cmd != JK_STATUS_CMD_UPDATE) { continue; } if (!strcmp(k, JK_STATUS_ARG_OPTIONS)) { opt = atoi(v); continue; } jk_printf(s, l, "%s%s=%s", started ? "&" : "?", k, v); started=1; } if (opt | add_options | rm_options) jk_printf(s, l, "%s%s=%u", started ? "&" : "?", JK_STATUS_ARG_OPTIONS, (opt | add_options) & ~rm_options); if (text) jk_putv(s, "\">", text, "", NULL); } static int status_parse_uri(jk_ws_service_t *s, status_endpoint_t *p, jk_logger_t *l) { jk_map_t *m; status_worker_t *w = p->worker; #ifdef _MT_CODE_PTHREAD char *lasts; #endif char *param; char *query; JK_TRACE_ENTER(l); if (!s->query_string) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' query string is empty", w->name); JK_TRACE_EXIT(l); return JK_TRUE; } p->query_string = jk_pool_strdup(s->pool, s->query_string); if (!p->query_string) { jk_log(l, JK_LOG_ERROR, "Status worker '%s' could not copy query string", w->name); JK_TRACE_EXIT(l); return JK_FALSE; } /* XXX We simply mask special chars in the query string with '@' to prevent cross site scripting */ query = p->query_string; while ((query = strpbrk(query, JK_STATUS_ESC_CHARS))) query[0] = '@'; if (!jk_map_alloc(&(p->req_params))) { jk_log(l, JK_LOG_ERROR, "Status worker '%s' could not alloc map for request parameters", w->name); JK_TRACE_EXIT(l); return JK_FALSE; } m = p->req_params; query = jk_pool_strdup(s->pool, p->query_string); if (!query) { jk_log(l, JK_LOG_ERROR, "Status worker '%s' could not copy query string", w->name); JK_TRACE_EXIT(l); return JK_FALSE; } #ifdef _MT_CODE_PTHREAD for (param = strtok_r(query, "&", &lasts); param; param = strtok_r(NULL, "&", &lasts)) { #else for (param = strtok(query, "&"); param; param = strtok(NULL, "&")) { #endif char *key = jk_pool_strdup(s->pool, param); char *value; char *tmp; if (!key) { jk_log(l, JK_LOG_ERROR, "Status worker '%s' could not copy string", w->name); JK_TRACE_EXIT(l); return JK_FALSE; } value = strchr(key, '='); if (value) { *value = '\0'; value++; if (strlen(key)) { /* percent decoding */ if (jk_unescape_url(value, value, -1, NULL, NULL, 1, NULL) != JK_TRUE) { jk_log(l, JK_LOG_ERROR, "Status worker '%s' could not decode query string " "param '%s' with value '%s'", w->name, key, value); JK_TRACE_EXIT(l); return JK_FALSE; } /* XXX We simply mask special chars in the query string with '@' * to prevent cross site scripting */ tmp = value; while ((tmp = strpbrk(tmp, JK_STATUS_ESC_CHARS))) tmp[0] = '@'; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' adding request param '%s' with value '%s'", w->name, key, value); /* XXX Depending on the params values, we might need to trim */ jk_map_put(m, key, value, NULL); } } } JK_TRACE_EXIT(l); return JK_TRUE; } static void write_html_refresh_response(jk_ws_service_t *s, status_endpoint_t *p, const char *err, jk_logger_t *l) { if (!err) { jk_puts(s, "\n"); jk_putv(s, "

Result: OK - You will be redirected in " JK_STATUS_WAIT_AFTER_UPDATE " seconds.

", NULL); } } static int fetch_worker_and_sub_worker(status_endpoint_t *p, const char *operation, const char **worker, const char **sub_worker, jk_logger_t *l) { status_worker_t *w = p->worker; JK_TRACE_ENTER(l); status_get_string(p, JK_STATUS_ARG_WORKER, NULL, worker, l); status_get_string(p, JK_STATUS_ARG_SUB_WORKER, NULL, sub_worker, l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' %s worker '%s' sub worker '%s'", w->name, operation, *worker ? *worker : "(null)", *sub_worker ? *sub_worker : "(null)"); if (!*worker || !(*worker)[0]) { jk_log(l, JK_LOG_WARNING, "Status worker '%s' NULL or EMPTY worker param", w->name); p->msg = "NULL or EMPTY worker param"; JK_TRACE_EXIT(l); return JK_FALSE; } if (*sub_worker && !(*sub_worker)[0]) { jk_log(l, JK_LOG_WARNING, "Status worker '%s' EMPTY sub worker param", w->name); p->msg = "EMPTY sub worker param"; JK_TRACE_EXIT(l); return JK_FALSE; } JK_TRACE_EXIT(l); return JK_TRUE; } static int check_valid_lb(jk_ws_service_t *s, status_endpoint_t *p, jk_worker_t *jw, const char *worker, lb_worker_t **lbp, int implemented, jk_logger_t *l) { status_worker_t *w = p->worker; JK_TRACE_ENTER(l); if (jw->type != JK_LB_WORKER_TYPE) { if (implemented) { jk_log(l, JK_LOG_WARNING, "Status worker '%s' worker type of worker '%s' has no sub workers", w->name, worker); p->msg = "worker type has no sub workers"; } else { jk_log(l, JK_LOG_WARNING, "Status worker '%s' worker type of worker '%s' not implemented", w->name, worker); p->msg = "worker type not implemented"; } JK_TRACE_EXIT(l); return JK_FALSE; } *lbp = (lb_worker_t *)jw->worker_private; if (!*lbp) { jk_log(l, JK_LOG_WARNING, "Status worker '%s' lb structure of worker '%s' is (null)", w->name, worker); p->msg = "lb structure is (null)"; JK_TRACE_EXIT(l); return JK_FALSE; } p->msg = "OK"; JK_TRACE_EXIT(l); return JK_TRUE; } static int search_worker(jk_ws_service_t *s, status_endpoint_t *p, jk_worker_t **jwp, const char *worker, jk_logger_t *l) { status_worker_t *w = p->worker; JK_TRACE_ENTER(l); *jwp = NULL; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' searching worker '%s'", w->name, worker ? worker : "(null)"); if (!worker || !worker[0]) { jk_log(l, JK_LOG_WARNING, "Status worker '%s' NULL or EMPTY worker param", w->name); p->msg = "NULL or EMPTY worker param"; JK_TRACE_EXIT(l); return JK_FALSE; } *jwp = wc_get_worker_for_name(worker, l); if (!*jwp) { jk_log(l, JK_LOG_WARNING, "Status worker '%s' could not find worker '%s'", w->name, worker); p->msg = "Could not find given worker"; JK_TRACE_EXIT(l); return JK_FALSE; } p->msg = "OK"; JK_TRACE_EXIT(l); return JK_TRUE; } static int search_sub_worker(jk_ws_service_t *s, status_endpoint_t *p, jk_worker_t *jw, const char *worker, lb_sub_worker_t **wrp, const char *sub_worker, unsigned int *idx, jk_logger_t *l) { lb_worker_t *lb = NULL; lb_sub_worker_t *wr = NULL; status_worker_t *w = p->worker; unsigned int i = 0; JK_TRACE_ENTER(l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' searching sub worker '%s' of worker '%s'", w->name, sub_worker ? sub_worker : "(null)", worker ? worker : "(null)"); if (!sub_worker || !sub_worker[0]) { jk_log(l, JK_LOG_WARNING, "Status worker '%s' NULL or EMPTY sub_worker param", w->name); p->msg = "NULL or EMPTY sub_worker param"; JK_TRACE_EXIT(l); return JK_FALSE; } if (check_valid_lb(s, p, jw, worker, &lb, 1, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } if (idx) i = *idx; for (; i < lb->num_of_workers; i++) { wr = &(lb->lb_workers[i]); if (idx) { if (jk_wildchar_match(wr->name, sub_worker, 0) == 0) { *idx = i + 1; break; } } else if (strcmp(sub_worker, wr->name) == 0) break; } *wrp = wr; if (!wr || i == lb->num_of_workers) { jk_log(l, JK_LOG_WARNING, "Status worker '%s' could not find sub worker '%s' of worker '%s'", w->name, sub_worker, worker ? worker : "(null)"); p->msg = "could not find sub worker"; JK_TRACE_EXIT(l); return JK_FALSE; } p->msg = "OK"; JK_TRACE_EXIT(l); return JK_TRUE; } static int count_map(jk_uri_worker_map_t *uw_map, const char *worker, jk_logger_t *l) { unsigned int i; int count=0; JK_TRACE_ENTER(l); if (uw_map) { for (i = 0; i < uw_map->size[uw_map->index]; i++) { uri_worker_record_t *uwr = uw_map->maps[uw_map->index][i]; if (strcmp(uwr->worker_name, worker) && strcmp(uwr->worker_name, "*")) { continue; } count++; } } JK_TRACE_EXIT(l); return count; } static int count_maps(jk_ws_service_t *s, const char *worker, jk_logger_t *l) { int count=0; JK_TRACE_ENTER(l); if (s->next_vhost) { void *srv; for (srv = s->next_vhost(NULL); srv; srv = s->next_vhost(srv)) { count += count_map(s->vhost_to_uw_map(srv), worker, l); } } else if (s->uw_map) count = count_map(s->uw_map, worker, l); JK_TRACE_EXIT(l); return count; } static void display_map(jk_ws_service_t *s, status_endpoint_t *p, jk_uri_worker_map_t *uw_map, const char *worker, const char *server_name, int *count_ptr, int mime, jk_logger_t *l) { char buf[64]; unsigned int i; int count; status_worker_t *w = p->worker; JK_TRACE_ENTER(l); if (uw_map->fname) { uri_worker_map_update(uw_map, 1, l); } for (i = 0; i < uw_map->size[uw_map->index]; i++) { uri_worker_record_t *uwr = uw_map->maps[uw_map->index][i]; if (strcmp(uwr->worker_name, worker) && strcmp(uwr->worker_name, "*")) { continue; } (*count_ptr)++; count = *count_ptr; if (mime == JK_STATUS_MIME_HTML) { if (server_name) jk_printf(s, l, JK_STATUS_URI_MAP_TABLE_ROW2, server_name, uwr->uri, uri_worker_map_get_match(uwr, buf, l), uri_worker_map_get_source(uwr, l), uwr->extensions.reply_timeout, uwr->extensions.sticky_ignore, uwr->extensions.stateless, uwr->extensions.fail_on_status_str ? uwr->extensions.fail_on_status_str : "-", uwr->extensions.active ? uwr->extensions.active : "-", uwr->extensions.disabled ? uwr->extensions.disabled : "-", uwr->extensions.stopped ? uwr->extensions.stopped : "-", uwr->extensions.use_server_error_pages); else jk_printf(s, l, JK_STATUS_URI_MAP_TABLE_ROW, uwr->uri, uri_worker_map_get_match(uwr, buf, l), uri_worker_map_get_source(uwr, l), uwr->extensions.reply_timeout, uwr->extensions.sticky_ignore, uwr->extensions.stateless, uwr->extensions.fail_on_status_str ? uwr->extensions.fail_on_status_str : "-", uwr->extensions.active ? uwr->extensions.active : "-", uwr->extensions.disabled ? uwr->extensions.disabled : "-", uwr->extensions.stopped ? uwr->extensions.stopped : "-", uwr->extensions.use_server_error_pages); } else if (mime == JK_STATUS_MIME_XML) { jk_print_xml_start_elt(s, l, w, 6, 0, "map"); jk_print_xml_att_int(s, l, 8, "id", count); if (server_name) jk_print_xml_att_string(s, l, 8, "server", server_name); jk_print_xml_att_string(s, l, 8, "uri", uwr->uri); jk_print_xml_att_string(s, l, 8, "type", uri_worker_map_get_match(uwr, buf, l)); jk_print_xml_att_string(s, l, 8, "source", uri_worker_map_get_source(uwr, l)); jk_print_xml_att_int(s, l, 8, "reply_timeout", uwr->extensions.reply_timeout); jk_print_xml_att_int(s, l, 8, "sticky_ignore", uwr->extensions.sticky_ignore); jk_print_xml_att_int(s, l, 8, "stateless", uwr->extensions.stateless); jk_print_xml_att_string(s, l, 8, "fail_on_status", uwr->extensions.fail_on_status_str); jk_print_xml_att_string(s, l, 8, "active", uwr->extensions.active); jk_print_xml_att_string(s, l, 8, "disabled", uwr->extensions.disabled); jk_print_xml_att_string(s, l, 8, "stopped", uwr->extensions.stopped); jk_print_xml_att_int(s, l, 8, "use_server_errors", uwr->extensions.use_server_error_pages); jk_print_xml_stop_elt(s, l, 6, 1); } else if (mime == JK_STATUS_MIME_TXT) { jk_puts(s, "Map:"); jk_printf(s, l, " id=%d", count); if (server_name) jk_printf(s, l, " server=\"%s\"", server_name); jk_printf(s, l, " uri=\"%s\"", uwr->uri); jk_printf(s, l, " type=\"%s\"", uri_worker_map_get_match(uwr, buf, l)); jk_printf(s, l, " source=\"%s\"", uri_worker_map_get_source(uwr, l)); jk_printf(s, l, " reply_timeout=\"%d\"", uwr->extensions.reply_timeout); jk_printf(s, l, " sticky_ignore=\"%d\"", uwr->extensions.sticky_ignore); jk_printf(s, l, " stateless=\"%d\"", uwr->extensions.stateless); jk_printf(s, l, " fail_on_status=\"%s\"", uwr->extensions.fail_on_status_str ? uwr->extensions.fail_on_status_str : ""); jk_printf(s, l, " active=\"%s\"", uwr->extensions.active ? uwr->extensions.active : ""); jk_printf(s, l, " disabled=\"%s\"", uwr->extensions.disabled ? uwr->extensions.disabled : ""); jk_printf(s, l, " stopped=\"%s\"", uwr->extensions.stopped ? uwr->extensions.stopped : ""); jk_printf(s, l, " use_server_errors=\"%d\"", uwr->extensions.use_server_error_pages); jk_puts(s, "\n"); } else if (mime == JK_STATUS_MIME_PROP) { if (server_name) jk_print_prop_item_string(s, l, w, worker, "map", count, "server", server_name); jk_print_prop_item_string(s, l, w, worker, "map", count, "uri", uwr->uri); jk_print_prop_item_string(s, l, w, worker, "map", count, "type", uri_worker_map_get_match(uwr, buf, l)); jk_print_prop_item_string(s, l, w, worker, "map", count, "source", uri_worker_map_get_source(uwr, l)); jk_print_prop_item_int(s, l, w, worker, "map", count, "reply_timeout", uwr->extensions.reply_timeout); jk_print_prop_item_int(s, l, w, worker, "map", count, "sticky_ignore", uwr->extensions.sticky_ignore); jk_print_prop_item_int(s, l, w, worker, "map", count, "stateless", uwr->extensions.stateless); jk_print_prop_item_string(s, l, w, worker, "map", count, "fail_on_status", uwr->extensions.fail_on_status_str); jk_print_prop_item_string(s, l, w, worker, "map", count, "active", uwr->extensions.active); jk_print_prop_item_string(s, l, w, worker, "map", count, "disabled", uwr->extensions.disabled); jk_print_prop_item_string(s, l, w, worker, "map", count, "stopped", uwr->extensions.stopped); jk_print_prop_item_int(s, l, w, worker, "map", count, "use_server_errors", uwr->extensions.use_server_error_pages); } } JK_TRACE_EXIT(l); } static void display_maps(jk_ws_service_t *s, status_endpoint_t *p, const char *worker, jk_logger_t *l) { int mime; unsigned int hide; int has_server_iterator = 0; int count=0; const char *arg; status_worker_t *w = p->worker; jk_uri_worker_map_t *uw_map; char server_name[80]; void *srv; JK_TRACE_ENTER(l); status_get_string(p, JK_STATUS_ARG_MIME, NULL, &arg, l); mime = status_mime_int(arg); hide = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) & JK_STATUS_ARG_OPTION_NO_MAPS; if (s->next_vhost) has_server_iterator = 1; count = count_maps(s, worker, l); if (hide) { if (count && mime == JK_STATUS_MIME_HTML) { jk_puts(s, "

\n"); status_write_uri(s, p, "Show URI Mappings", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_MAPS, NULL, l); jk_puts(s, "

\n"); } JK_TRACE_EXIT(l); return; } if (count) { if (mime == JK_STATUS_MIME_HTML) { jk_printf(s, l, "

URI Mappings for %s (%d maps) [", worker, count); status_write_uri(s, p, "Hide", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN, NULL, NULL, JK_STATUS_ARG_OPTION_NO_MAPS, 0, NULL, l); jk_puts(s, "]

\n"); if (has_server_iterator) jk_printf(s, l, JK_STATUS_URI_MAP_TABLE_HEAD2, "Server", "URI", "Match
Type", "Source", "Reply
Timeout", "Sticky
Ignore", "Stateless", "Fail on
Status", "Active", "Disabled", "Stopped", "Use Server
Errors"); else jk_printf(s, l, JK_STATUS_URI_MAP_TABLE_HEAD, "URI", "Match
Type", "Source", "Reply
Timeout", "Sticky
Ignore", "Stateless", "Fail on
Status", "Active", "Disabled", "Stopped", "Use Server
Errors"); } count = 0; if (has_server_iterator) { for (srv = s->next_vhost(NULL); srv; srv = s->next_vhost(srv)) { uw_map = s->vhost_to_uw_map(srv); if (uw_map) { s->vhost_to_text(srv, server_name, 80); display_map(s, p, uw_map, worker, server_name, &count, mime, l); } } } else { uw_map = s->uw_map; if (uw_map) { display_map(s, p, uw_map, worker, NULL, &count, mime, l); } } if (mime == JK_STATUS_MIME_HTML) { jk_puts(s, "
\n"); } } else { if (mime == JK_STATUS_MIME_HTML) { jk_putv(s, "

Warning: No URI Mappings defined for ", worker, " !

\n", NULL); } } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' displayed %d maps for worker '%s'", w->name, count, worker); JK_TRACE_EXIT(l); } static const char *dump_ajp_addr(ajp_worker_t *aw, char *buf, size_t size) { if (aw->port > 0) return jk_dump_hinfo(&aw->worker_inet_addr, buf, size); else { if (aw->addr_sequence != aw->s->addr_sequence) return "unresolved"; else return "invalid"; } } static void display_worker_ajp_conf_details(jk_ws_service_t *s, status_endpoint_t *p, ajp_worker_t *aw, int is_member, int type, jk_logger_t *l) { char buf[64]; JK_TRACE_ENTER(l); if (is_member) jk_printf(s, l, JK_STATUS_SHOW_MEMBER_CONF_ROW, aw->name, status_worker_type(type), aw->host, dump_ajp_addr(aw, buf, sizeof(buf)), aw->source && *aw->source ? aw->source : "undefined", aw->cache_timeout, aw->connect_timeout, aw->prepost_timeout, aw->reply_timeout, aw->retries, aw->recovery_opts, aw->busy_limit, aw->max_packet_size); else jk_printf(s, l, JK_STATUS_SHOW_AJP_CONF_ROW, status_worker_type(type), aw->host, dump_ajp_addr(aw, buf, sizeof(buf)), aw->source && *aw->source ? aw->source : "undefined", aw->cache_timeout, aw->connect_timeout, aw->prepost_timeout, aw->reply_timeout, aw->retries, aw->recovery_opts, aw->busy_limit, aw->max_packet_size); JK_TRACE_EXIT(l); } static void display_worker_ajp_details(jk_ws_service_t *s, status_endpoint_t *p, ajp_worker_t *aw, lb_sub_worker_t *wr, lb_worker_t *lb, int ms_min, int ms_max, int map_count, jk_logger_t *l) { char buf[64]; char buf_rd[32]; char buf_rd_sec[32]; char buf_wr[32]; char buf_wr_sec[32]; int mime; const char *arg; time_t now = time(NULL); const char *name = NULL; const char *sub_name = NULL; const char *ajp_name = NULL; status_worker_t *w = p->worker; int rs_min = 0; int rs_max = 0; int delta_reset = (int)difftime(now, aw->s->last_reset); int delta_error = -1; char buf_time[JK_STATUS_TIME_BUF_SZ]; char buf_tz[JK_STATUS_TIME_BUF_SZ]; time_t error_time = 0; int rc_time = -1; JK_TRACE_ENTER(l); status_get_string(p, JK_STATUS_ARG_MIME, NULL, &arg, l); mime = status_mime_int(arg); if (lb) { name = lb->name; sub_name = wr->name; ajp_name = wr->name; error_time = wr->s->first_error_time; if (wr->s->state == JK_LB_STATE_ERROR) { rs_min = lb->recover_wait_time - (int)difftime(now, wr->s->last_error_time); if (rs_min < 0) { rs_min = 0; } rs_max = rs_min + lb->maintain_time; if (rs_min < ms_min) { rs_min = ms_min; } } } else { name = aw->name; sub_name = NULL; ajp_name = aw->name; error_time = aw->s->error_time; } if (error_time > 0) { delta_error = (int)difftime(now, error_time); rc_time = status_strftime(error_time, mime, buf_time, buf_tz, l); } if (mime == JK_STATUS_MIME_HTML) { if (lb) jk_printf(s, l, JK_STATUS_SHOW_MEMBER_ROW, sub_name, jk_lb_get_activation(wr, l), jk_lb_get_state(wr, l), wr->distance, wr->lb_factor, wr->lb_mult, wr->s->lb_value, aw->s->used, delta_reset > 0 ? (int)(aw->s->used / delta_reset) : -1, wr->s->sessions, delta_reset > 0 ? (int)(wr->s->sessions / delta_reset) : -1, wr->s->errors, aw->s->client_errors, aw->s->reply_timeouts, status_strfsize(aw->s->transferred, buf_wr), delta_reset > 0 ? status_strfsize(aw->s->transferred / delta_reset, buf_wr_sec) : "-", status_strfsize(aw->s->readed, buf_rd), delta_reset > 0 ? status_strfsize(aw->s->readed / delta_reset , buf_rd_sec) : "-", aw->s->busy, aw->s->max_busy, aw->s->connected, aw->s->max_connected, wr->route, wr->redirect ? (*wr->redirect ? wr->redirect : " ") : " ", wr->domain ? (*wr->domain ? wr->domain : " ") : " ", rs_min, rs_max, delta_reset, rc_time > 0 ? buf_time : " "); else { jk_printf(s, l, JK_STATUS_SHOW_AJP_ROW, jk_ajp_get_state(aw, l), aw->s->used, delta_reset > 0 ? (int)(aw->s->used / delta_reset) : -1, aw->s->errors, aw->s->client_errors, aw->s->reply_timeouts, status_strfsize(aw->s->transferred, buf_wr), delta_reset > 0 ? status_strfsize(aw->s->transferred / delta_reset, buf_wr_sec) : "-", status_strfsize(aw->s->readed, buf_rd), delta_reset > 0 ? status_strfsize(aw->s->readed / delta_reset , buf_rd_sec) : "-", aw->s->busy, aw->s->max_busy, aw->s->connected, aw->s->max_connected, delta_reset, rc_time > 0 ? buf_time : " "); } } else if (mime == JK_STATUS_MIME_XML) { int off = 2; if (lb) off = 6; if (lb) { jk_print_xml_start_elt(s, l, w, off, 0, "member"); jk_print_xml_att_string(s, l, off+2, "name", sub_name); jk_print_xml_att_string(s, l, off+2, "type", status_worker_type(wr->worker->type)); } else { jk_print_xml_start_elt(s, l, w, off, 0, "ajp"); jk_print_xml_att_string(s, l, off+2, "name", ajp_name); jk_print_xml_att_string(s, l, off+2, "type", status_worker_type(aw->worker.type)); } jk_print_xml_att_string(s, l, off+2, "host", aw->host); jk_print_xml_att_int(s, l, off+2, "port", aw->port); jk_print_xml_att_string(s, l, off+2, "address", dump_ajp_addr(aw, buf, sizeof(buf))); jk_print_xml_att_string(s, l, off+2, "source", aw->source && *aw->source ? aw->source : "undefined"); jk_print_xml_att_int(s, l, off+2, "connection_pool_timeout", aw->cache_timeout); jk_print_xml_att_int(s, l, off+2, "ping_timeout", aw->ping_timeout); jk_print_xml_att_int(s, l, off+2, "connect_timeout", aw->connect_timeout); jk_print_xml_att_int(s, l, off+2, "prepost_timeout", aw->prepost_timeout); jk_print_xml_att_int(s, l, off+2, "reply_timeout", aw->reply_timeout); jk_print_xml_att_int(s, l, off+2, "connection_ping_interval", aw->conn_ping_interval); jk_print_xml_att_int(s, l, off+2, "retries", aw->retries); jk_print_xml_att_uint(s, l, off+2, "recovery_options", aw->recovery_opts); jk_print_xml_att_int(s, l, off+2, "busy_limit", aw->busy_limit); jk_print_xml_att_uint(s, l, off+2, "max_packet_size", aw->max_packet_size); if (lb) { jk_print_xml_att_string(s, l, off+2, "activation", jk_lb_get_activation(wr, l)); jk_print_xml_att_int(s, l, off+2, "lbfactor", wr->lb_factor); jk_print_xml_att_string(s, l, off+2, "route", wr->route); jk_print_xml_att_string(s, l, off+2, "redirect", wr->redirect); jk_print_xml_att_string(s, l, off+2, "domain", wr->domain); jk_print_xml_att_int(s, l, off+2, "distance", wr->distance); jk_print_xml_att_string(s, l, off+2, "state", jk_lb_get_state(wr, l)); jk_print_xml_att_uint64(s, l, off+2, "lbmult", wr->lb_mult); jk_print_xml_att_uint64(s, l, off+2, "lbvalue", wr->s->lb_value); jk_print_xml_att_uint64(s, l, off+2, "elected", aw->s->used); jk_print_xml_att_uint64(s, l, off+2, "sessions", wr->s->sessions); jk_print_xml_att_uint32(s, l, off+2, "errors", wr->s->errors); } else { jk_print_xml_att_uint64(s, l, off+2, "used", aw->s->used); jk_print_xml_att_uint32(s, l, off+2, "errors", aw->s->errors); } jk_print_xml_att_uint32(s, l, off+2, "client_errors", aw->s->client_errors); jk_print_xml_att_uint32(s, l, off+2, "reply_timeouts", aw->s->reply_timeouts); jk_print_xml_att_uint64(s, l, off+2, "transferred", aw->s->transferred); jk_print_xml_att_uint64(s, l, off+2, "read", aw->s->readed); jk_print_xml_att_int(s, l, off+2, "busy", aw->s->busy); jk_print_xml_att_int(s, l, off+2, "max_busy", aw->s->max_busy); jk_print_xml_att_int(s, l, off+2, "connected", aw->s->connected); jk_print_xml_att_int(s, l, off+2, "max_connected", aw->s->max_connected); if (lb) { jk_print_xml_att_int(s, l, off+2, "time_to_recover_min", rs_min); jk_print_xml_att_int(s, l, off+2, "time_to_recover_max", rs_max); } else jk_print_xml_att_int(s, l, off+2, "map_count", map_count); jk_print_xml_att_long(s, l, off+2, "last_reset_at", (long)aw->s->last_reset); jk_print_xml_att_int(s, l, off+2, "last_reset_ago", delta_reset); if (rc_time > 0 ) { jk_print_xml_att_string(s, l, off+2, "error_time_datetime", buf_time); jk_print_xml_att_string(s, l, off+2, "error_time_tz", buf_tz); jk_print_xml_att_int(s, l, off+2, "error_time_unix_seconds", (int)error_time); jk_print_xml_att_int(s, l, off+2, "error_time_ago", delta_error); } /* Terminate the tag */ jk_print_xml_stop_elt(s, l, off, 1); } else if (mime == JK_STATUS_MIME_TXT) { if (lb) { jk_puts(s, "Member:"); jk_printf(s, l, " name=%s", sub_name); jk_printf(s, l, " type=%s", status_worker_type(wr->worker->type)); } else { jk_puts(s, "AJP Worker:"); jk_printf(s, l, " name=%s", ajp_name); jk_printf(s, l, " type=%s", status_worker_type(aw->worker.type)); } jk_printf(s, l, " host=%s", aw->host); jk_printf(s, l, " port=%d", aw->port); jk_printf(s, l, " address=%s", dump_ajp_addr(aw, buf, sizeof(buf))); jk_printf(s, l, " source=%s", aw->source && *aw->source ? aw->source : "undefined"); jk_printf(s, l, " connection_pool_timeout=%d", aw->cache_timeout); jk_printf(s, l, " ping_timeout=%d", aw->ping_timeout); jk_printf(s, l, " connect_timeout=%d", aw->connect_timeout); jk_printf(s, l, " prepost_timeout=%d", aw->prepost_timeout); jk_printf(s, l, " reply_timeout=%d", aw->reply_timeout); jk_printf(s, l, " retries=%d", aw->retries); jk_printf(s, l, " connection_ping_interval=%d", aw->conn_ping_interval); jk_printf(s, l, " recovery_options=%u", aw->recovery_opts); jk_printf(s, l, " busy_limit=%d", aw->busy_limit); jk_printf(s, l, " max_packet_size=%u", aw->max_packet_size); if (lb) { jk_printf(s, l, " activation=%s", jk_lb_get_activation(wr, l)); jk_printf(s, l, " lbfactor=%d", wr->lb_factor); jk_printf(s, l, " route=\"%s\"", wr->route ? wr->route : ""); jk_printf(s, l, " redirect=\"%s\"", wr->redirect ? wr->redirect : ""); jk_printf(s, l, " domain=\"%s\"", wr->domain ? wr->domain : ""); jk_printf(s, l, " distance=%d", wr->distance); jk_printf(s, l, " state=%s", jk_lb_get_state(wr, l)); jk_printf(s, l, " lbmult=%" JK_UINT64_T_FMT, wr->lb_mult); jk_printf(s, l, " lbvalue=%" JK_UINT64_T_FMT, wr->s->lb_value); jk_printf(s, l, " elected=%" JK_UINT64_T_FMT, aw->s->used); jk_printf(s, l, " sessions=%" JK_UINT64_T_FMT, wr->s->sessions); jk_printf(s, l, " errors=%" JK_UINT32_T_FMT, wr->s->errors); } else { jk_printf(s, l, " used=%" JK_UINT64_T_FMT, aw->s->used); jk_printf(s, l, " errors=%" JK_UINT32_T_FMT, aw->s->errors); } jk_printf(s, l, " client_errors=%" JK_UINT32_T_FMT, aw->s->client_errors); jk_printf(s, l, " reply_timeouts=%" JK_UINT32_T_FMT, aw->s->reply_timeouts); jk_printf(s, l, " transferred=%" JK_UINT64_T_FMT, aw->s->transferred); jk_printf(s, l, " read=%" JK_UINT64_T_FMT, aw->s->readed); jk_printf(s, l, " busy=%d", aw->s->busy); jk_printf(s, l, " max_busy=%d", aw->s->max_busy); jk_printf(s, l, " connected=%d", aw->s->connected); jk_printf(s, l, " max_connected=%d", aw->s->max_connected); if (lb) { jk_printf(s, l, " time_to_recover_min=%d", rs_min); jk_printf(s, l, " time_to_recover_max=%d", rs_max); } else jk_printf(s, l, " map_count=%d", map_count); jk_printf(s, l, " last_reset_at=%ld", (long)aw->s->last_reset); jk_printf(s, l, " last_reset_ago=%d", delta_reset); if (rc_time > 0) { jk_printf(s, l, " error_time_datetime=%s", buf_time); jk_printf(s, l, " error_time_tz=%s", buf_tz); jk_printf(s, l, " error_time_unix_seconds=%d", error_time); jk_printf(s, l, " error_time_ago=%d", delta_error); } jk_puts(s, "\n"); } else if (mime == JK_STATUS_MIME_PROP) { if (lb) { jk_print_prop_att_string(s, l, w, name, "balance_workers", sub_name); jk_print_prop_att_string(s, l, w, ajp_name, "type", status_worker_type(wr->worker->type)); } else { jk_print_prop_att_string(s, l, w, name, "list", ajp_name); jk_print_prop_att_string(s, l, w, ajp_name, "type", status_worker_type(aw->worker.type)); } jk_print_prop_att_string(s, l, w, ajp_name, "host", aw->host); jk_print_prop_att_int(s, l, w, ajp_name, "port", aw->port); jk_print_prop_att_string(s, l, w, ajp_name, "address", dump_ajp_addr(aw, buf, sizeof(buf))); jk_print_prop_att_string(s, l, w, ajp_name, "source", aw->source && *aw->source ? aw->source : "undefined"); jk_print_prop_att_int(s, l, w, ajp_name, "connection_pool_timeout", aw->cache_timeout); jk_print_prop_att_int(s, l, w, ajp_name, "ping_timeout", aw->ping_timeout); jk_print_prop_att_int(s, l, w, ajp_name, "connect_timeout", aw->connect_timeout); jk_print_prop_att_int(s, l, w, ajp_name, "prepost_timeout", aw->prepost_timeout); jk_print_prop_att_int(s, l, w, ajp_name, "reply_timeout", aw->reply_timeout); jk_print_prop_att_int(s, l, w, ajp_name, "retries", aw->retries); jk_print_prop_att_int(s, l, w, ajp_name, "connection_ping_interval", aw->conn_ping_interval); jk_print_prop_att_uint(s, l, w, ajp_name, "recovery_options", aw->recovery_opts); jk_print_prop_att_int(s, l, w, ajp_name, "busy_limit", aw->busy_limit); jk_print_prop_att_uint(s, l, w, ajp_name, "max_packet_size", aw->max_packet_size); if (lb) { jk_print_prop_att_string(s, l, w, ajp_name, "activation", jk_lb_get_activation(wr, l)); jk_print_prop_att_int(s, l, w, ajp_name, "lbfactor", wr->lb_factor); jk_print_prop_att_string(s, l, w, ajp_name, "route", wr->route); jk_print_prop_att_string(s, l, w, ajp_name, "redirect", wr->redirect); jk_print_prop_att_string(s, l, w, ajp_name, "domain", wr->domain); jk_print_prop_att_int(s, l, w, ajp_name, "distance", wr->distance); jk_print_prop_att_string(s, l, w, ajp_name, "state", jk_lb_get_state(wr, l)); jk_print_prop_att_uint64(s, l, w, ajp_name, "lbmult", wr->lb_mult); jk_print_prop_att_uint64(s, l, w, ajp_name, "lbvalue", wr->s->lb_value); jk_print_prop_att_uint64(s, l, w, ajp_name, "elected", aw->s->used); jk_print_prop_att_uint64(s, l, w, ajp_name, "sessions", wr->s->sessions); jk_print_prop_att_uint32(s, l, w, ajp_name, "errors", wr->s->errors); } else { jk_print_prop_att_uint64(s, l, w, ajp_name, "used", aw->s->used); jk_print_prop_att_uint32(s, l, w, ajp_name, "errors", aw->s->errors); } jk_print_prop_att_uint32(s, l, w, ajp_name, "client_errors", aw->s->client_errors); jk_print_prop_att_uint32(s, l, w, ajp_name, "reply_timeouts", aw->s->reply_timeouts); jk_print_prop_att_uint64(s, l, w, ajp_name, "transferred", aw->s->transferred); jk_print_prop_att_uint64(s, l, w, ajp_name, "read", aw->s->readed); jk_print_prop_att_int(s, l, w, ajp_name, "busy", aw->s->busy); jk_print_prop_att_int(s, l, w, ajp_name, "max_busy", aw->s->max_busy); jk_print_prop_att_int(s, l, w, ajp_name, "connected", aw->s->connected); jk_print_prop_att_int(s, l, w, ajp_name, "max_connected", aw->s->max_connected); if (lb) { jk_print_prop_att_int(s, l, w, ajp_name, "time_to_recover_min", rs_min); jk_print_prop_att_int(s, l, w, ajp_name, "time_to_recover_max", rs_max); } else jk_print_prop_att_int(s, l, w, name, "map_count", map_count); jk_print_prop_att_long(s, l, w, name, "last_reset_at", (long)aw->s->last_reset); jk_print_prop_att_int(s, l, w, name, "last_reset_ago", delta_reset); if (rc_time > 0) { jk_print_prop_att_string(s, l, w, name, "error_time_datetime", buf_time); jk_print_prop_att_string(s, l, w, name, "error_time_tz", buf_tz); jk_print_prop_att_int(s, l, w, name, "error_time_unix seconds", (int)error_time); jk_print_prop_att_int(s, l, w, name, "error_time_ago seconds", delta_error); } } JK_TRACE_EXIT(l); } static void display_worker_lb(jk_ws_service_t *s, status_endpoint_t *p, lb_worker_t *lb, lb_sub_worker_t *swr, jk_logger_t *l) { int cmd; int mime; int read_only = 0; int single = 0; unsigned int hide_members; unsigned int hide_lb_conf; unsigned int hide_lb_summary; unsigned int hide_ajp_conf; const char *arg; time_t now = time(NULL); unsigned int good = 0; unsigned int degraded = 0; unsigned int bad = 0; int map_count; int ms_min; int ms_max; unsigned int j; int pstart = JK_FALSE; const char *name = lb->name; status_worker_t *w = p->worker; JK_TRACE_ENTER(l); status_get_string(p, JK_STATUS_ARG_CMD, NULL, &arg, l); cmd = status_cmd_int(arg); status_get_string(p, JK_STATUS_ARG_MIME, NULL, &arg, l); mime = status_mime_int(arg); hide_members = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) & JK_STATUS_ARG_OPTION_NO_MEMBERS; hide_lb_conf = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) & JK_STATUS_ARG_OPTION_NO_LB_CONF; hide_lb_summary = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) & JK_STATUS_ARG_OPTION_NO_LB_SUMMARY; hide_ajp_conf = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) & JK_STATUS_ARG_OPTION_NO_AJP_CONF; if (w->read_only) { read_only = 1; } else { read_only = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) & JK_STATUS_ARG_OPTION_READ_ONLY; } if (cmd == JK_STATUS_CMD_SHOW) { single = 1; } if (lb->sequence != lb->s->h.sequence) jk_lb_pull(lb, JK_FALSE, l); for (j = 0; j < lb->num_of_workers; j++) { lb_sub_worker_t *wr = &(lb->lb_workers[j]); int rate; rate = status_rate(wr, w, l); if (rate > 0 ) good++; else if (rate < 0 ) bad++; else degraded++; } map_count = count_maps(s, name, l); ms_min = lb->maintain_time - (int)difftime(now, lb->s->last_maintain_time); ms_max = ms_min + lb->maintain_time; if (ms_min < 0) { ms_min = 0; } if (ms_max < 0) { ms_max = 0; } if (mime == JK_STATUS_MIME_HTML) { jk_puts(s, "

["); if (single) { jk_puts(s, "S"); } else { status_write_uri(s, p, "S", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN, name, "", 0, 0, "", l); } if (!read_only) { jk_puts(s, "|"); status_write_uri(s, p, "E", JK_STATUS_CMD_EDIT, JK_STATUS_MIME_UNKNOWN, name, "", 0, 0, "", l); jk_puts(s, "|"); status_write_uri(s, p, "R", JK_STATUS_CMD_RESET, JK_STATUS_MIME_UNKNOWN, name, "", 0, 0, "", l); } jk_puts(s, "]  "); jk_putv(s, "Worker Status for ", name, "

\n", NULL); if (hide_lb_conf) { pstart = JK_TRUE; jk_puts(s, "

\n"); if (single) { status_write_uri(s, p, "Show LB Configuration", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_LB_CONF, "", l); } else { status_write_uri(s, p, "Show LB Configuration", JK_STATUS_CMD_LIST, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_LB_CONF, "", l); } } if (hide_lb_summary) { if (pstart == JK_FALSE) jk_puts(s, "

\n"); else jk_puts(s, "  |  "); pstart = JK_TRUE; if (single) { status_write_uri(s, p, "Show LB Summary", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_LB_SUMMARY, "", l); } else { status_write_uri(s, p, "Show LB Summary", JK_STATUS_CMD_LIST, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_LB_SUMMARY, "", l); } } if (!hide_members && hide_ajp_conf) { if (pstart == JK_FALSE) jk_puts(s, "

\n"); else jk_puts(s, "  |  "); pstart = JK_TRUE; if (single) { status_write_uri(s, p, "Show AJP Configuration", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_AJP_CONF, "", l); } else { status_write_uri(s, p, "Show AJP Configuration", JK_STATUS_CMD_LIST, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_AJP_CONF, "", l); } } if (hide_members) { if (pstart == JK_FALSE) jk_puts(s, "

\n"); else jk_puts(s, "  |  "); pstart = JK_TRUE; if (single) { status_write_uri(s, p, "Show Balancer Members", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_MEMBERS, "", l); } else { status_write_uri(s, p, "Show Balancer Members", JK_STATUS_CMD_LIST, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_MEMBERS, "", l); } } if (pstart == JK_TRUE) jk_puts(s, "

\n"); if (!hide_lb_conf) { jk_puts(s, "" JK_STATUS_SHOW_LB_HEAD); jk_puts(s, "["); status_write_uri(s, p, "Hide", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN, NULL, NULL, JK_STATUS_ARG_OPTION_NO_LB_CONF, 0, NULL, l); jk_puts(s, "]"); jk_printf(s, l, JK_STATUS_SHOW_LB_ROW, status_worker_type(JK_LB_WORKER_TYPE), jk_get_bool(lb->sticky_session), jk_get_bool(lb->sticky_session_force), lb->retries, jk_lb_get_method(lb, l), jk_lb_get_lock(lb, l), lb->recover_wait_time, lb->error_escalation_time, lb->max_reply_timeouts); jk_puts(s, "
\n
\n"); } if (!hide_lb_summary) { jk_puts(s, "" "\n"); jk_printf(s, l, "", good); jk_printf(s, l, "", degraded); jk_printf(s, l, "", bad); jk_printf(s, l, "", lb->s->busy); jk_printf(s, l, "", lb->s->max_busy); jk_printf(s, l, "", ms_min, ms_max); jk_printf(s, l, "", (int)difftime(now, lb->s->last_reset)); jk_puts(s, "\n
GoodDegradedBad/StoppedBusyMax BusyNext MaintenanceLast Reset["); status_write_uri(s, p, "Hide", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN, NULL, NULL, JK_STATUS_ARG_OPTION_NO_LB_SUMMARY, 0, NULL, l); jk_puts(s, "]
%d%d%d%d%d%d/%d%d
\n\n"); } } else if (mime == JK_STATUS_MIME_XML) { jk_print_xml_start_elt(s, l, w, 2, 0, "balancer"); jk_print_xml_att_string(s, l, 4, "name", name); jk_print_xml_att_string(s, l, 4, "type", status_worker_type(JK_LB_WORKER_TYPE)); jk_print_xml_att_string(s, l, 4, "sticky_session", jk_get_bool(lb->sticky_session)); jk_print_xml_att_string(s, l, 4, "sticky_session_force", jk_get_bool(lb->sticky_session_force)); jk_print_xml_att_int(s, l, 4, "retries", lb->retries); jk_print_xml_att_int(s, l, 4, "recover_time", lb->recover_wait_time); jk_print_xml_att_int(s, l, 4, "error_escalation_time", lb->error_escalation_time); jk_print_xml_att_int(s, l, 4, "max_reply_timeouts", lb->max_reply_timeouts); jk_print_xml_att_string(s, l, 4, "method", jk_lb_get_method(lb, l)); jk_print_xml_att_string(s, l, 4, "lock", jk_lb_get_lock(lb, l)); jk_print_xml_att_int(s, l, 4, "member_count", lb->num_of_workers); jk_print_xml_att_int(s, l, 4, "good", good); jk_print_xml_att_int(s, l, 4, "degraded", degraded); jk_print_xml_att_int(s, l, 4, "bad", bad); jk_print_xml_att_int(s, l, 4, "busy", lb->s->busy); jk_print_xml_att_int(s, l, 4, "max_busy", lb->s->max_busy); jk_print_xml_att_int(s, l, 4, "map_count", map_count); jk_print_xml_att_int(s, l, 4, "time_to_maintenance_min", ms_min); jk_print_xml_att_int(s, l, 4, "time_to_maintenance_max", ms_max); jk_print_xml_att_long(s, l, 4, "last_reset_at", (long)lb->s->last_reset); jk_print_xml_att_int(s, l, 4, "last_reset_ago", (int)difftime(now, lb->s->last_reset)); jk_print_xml_stop_elt(s, l, 2, 0); } else if (mime == JK_STATUS_MIME_TXT) { jk_puts(s, "Balancer Worker:"); jk_printf(s, l, " name=%s", name); jk_printf(s, l, " type=%s", status_worker_type(JK_LB_WORKER_TYPE)); jk_printf(s, l, " sticky_session=%s", jk_get_bool(lb->sticky_session)); jk_printf(s, l, " sticky_session_force=%s", jk_get_bool(lb->sticky_session_force)); jk_printf(s, l, " retries=%d", lb->retries); jk_printf(s, l, " recover_time=%d", lb->recover_wait_time); jk_printf(s, l, " error_escalation_time=%d", lb->error_escalation_time); jk_printf(s, l, " max_reply_timeouts=%d", lb->max_reply_timeouts); jk_printf(s, l, " method=%s", jk_lb_get_method(lb, l)); jk_printf(s, l, " lock=%s", jk_lb_get_lock(lb, l)); jk_printf(s, l, " member_count=%d", lb->num_of_workers); jk_printf(s, l, " good=%d", good); jk_printf(s, l, " degraded=%d", degraded); jk_printf(s, l, " bad=%d", bad); jk_printf(s, l, " busy=%d", lb->s->busy); jk_printf(s, l, " max_busy=%d", lb->s->max_busy); jk_printf(s, l, " map_count=%d", map_count); jk_printf(s, l, " time_to_maintenance_min=%d", ms_min); jk_printf(s, l, " time_to_maintenance_max=%d", ms_max); jk_printf(s, l, " last_reset_at=%ld", (long)lb->s->last_reset); jk_printf(s, l, " last_reset_ago=%d", (int)difftime(now, lb->s->last_reset)); jk_puts(s, "\n"); } else if (mime == JK_STATUS_MIME_PROP) { jk_print_prop_att_string(s, l, w, NULL, "list", name); jk_print_prop_att_string(s, l, w, name, "type", status_worker_type(JK_LB_WORKER_TYPE)); jk_print_prop_att_string(s, l, w, name, "sticky_session", jk_get_bool(lb->sticky_session)); jk_print_prop_att_string(s, l, w, name, "sticky_session_force", jk_get_bool(lb->sticky_session_force)); jk_print_prop_att_int(s, l, w, name, "retries", lb->retries); jk_print_prop_att_int(s, l, w, name, "recover_time", lb->recover_wait_time); jk_print_prop_att_int(s, l, w, name, "error_escalation_time", lb->error_escalation_time); jk_print_prop_att_int(s, l, w, name, "max_reply_timeouts", lb->max_reply_timeouts); jk_print_prop_att_string(s, l, w, name, "method", jk_lb_get_method(lb, l)); jk_print_prop_att_string(s, l, w, name, "lock", jk_lb_get_lock(lb, l)); jk_print_prop_att_int(s, l, w, name, "member_count", lb->num_of_workers); jk_print_prop_att_int(s, l, w, name, "good", good); jk_print_prop_att_int(s, l, w, name, "degraded", degraded); jk_print_prop_att_int(s, l, w, name, "bad", bad); jk_print_prop_att_int(s, l, w, name, "busy", lb->s->busy); jk_print_prop_att_int(s, l, w, name, "max_busy", lb->s->max_busy); jk_print_prop_att_int(s, l, w, name, "map_count", map_count); jk_print_prop_att_int(s, l, w, name, "time_to_maintenance_min", ms_min); jk_print_prop_att_int(s, l, w, name, "time_to_maintenance_max", ms_max); jk_print_prop_att_long(s, l, w, name, "last_reset_at", (long)lb->s->last_reset); jk_print_prop_att_int(s, l, w, name, "last_reset_ago", (int)difftime(now, lb->s->last_reset)); } if (!hide_members) { if (mime == JK_STATUS_MIME_HTML) { jk_puts(s, "

Balancer Members ["); if (swr) { status_write_uri(s, p, "Show All Members", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN, name, "", 0, 0, "", l); jk_puts(s, "]  ["); } if (single) { status_write_uri(s, p, "Hide", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN, NULL, NULL, JK_STATUS_ARG_OPTION_NO_MEMBERS, 0, "", l); } else { status_write_uri(s, p, "Hide", JK_STATUS_CMD_LIST, JK_STATUS_MIME_UNKNOWN, NULL, NULL, JK_STATUS_ARG_OPTION_NO_MEMBERS, 0, "", l); } jk_puts(s, "]

\n"); if (!hide_ajp_conf) { jk_puts(s, "" JK_STATUS_SHOW_MEMBER_CONF_HEAD); jk_puts(s, "["); status_write_uri(s, p, "Hide", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN, NULL, NULL, JK_STATUS_ARG_OPTION_NO_AJP_CONF, 0, NULL, l); jk_puts(s, "]"); if (swr) { jk_worker_t *jw = (jk_worker_t *)swr->worker; ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private; display_worker_ajp_conf_details(s, p, aw, 1, jw->type, l); } else for (j = 0; j < lb->num_of_workers; j++) { lb_sub_worker_t *wr = &(lb->lb_workers[j]); jk_worker_t *jw = (jk_worker_t *)wr->worker; ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private; display_worker_ajp_conf_details(s, p, aw, 1, jw->type, l); } jk_puts(s, "
\n
\n"); } jk_puts(s, "" JK_STATUS_SHOW_MEMBER_HEAD); } if (swr) { const char *sub_name = swr->name; ajp_worker_t *aw = (ajp_worker_t *)swr->worker->worker_private; if (mime == JK_STATUS_MIME_HTML) { jk_puts(s, "\n"); } display_worker_ajp_details(s, p, aw, swr, lb, ms_min, ms_max, 0, l); } else for (j = 0; j < lb->num_of_workers; j++) { lb_sub_worker_t *wr = &(lb->lb_workers[j]); const char *sub_name = wr->name; ajp_worker_t *aw = (ajp_worker_t *)wr->worker->worker_private; if (mime == JK_STATUS_MIME_HTML) { jk_puts(s, "\n"); } display_worker_ajp_details(s, p, aw, wr, lb, ms_min, ms_max, 0, l); } if (mime == JK_STATUS_MIME_HTML) { jk_puts(s, "
["); jk_puts(s, "S"); if (!read_only) { jk_puts(s, "|"); status_write_uri(s, p, "E", JK_STATUS_CMD_EDIT, JK_STATUS_MIME_UNKNOWN, name, sub_name, 0, 0, "", l); jk_puts(s, "|"); status_write_uri(s, p, "R", JK_STATUS_CMD_RESET, JK_STATUS_MIME_UNKNOWN, name, sub_name, 0, 0, "", l); if (swr->s->state == JK_LB_STATE_ERROR) { jk_puts(s, "|"); status_write_uri(s, p, "T", JK_STATUS_CMD_RECOVER, JK_STATUS_MIME_UNKNOWN, name, sub_name, 0, 0, "", l); } } jk_puts(s, "]"); jk_puts(s, " 
["); status_write_uri(s, p, "S", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN, name, sub_name, 0, 0, "", l); if (!read_only) { jk_puts(s, "|"); status_write_uri(s, p, "E", JK_STATUS_CMD_EDIT, JK_STATUS_MIME_UNKNOWN, name, sub_name, 0, 0, "", l); jk_puts(s, "|"); status_write_uri(s, p, "R", JK_STATUS_CMD_RESET, JK_STATUS_MIME_UNKNOWN, name, sub_name, 0, 0, "", l); if (wr->s->state == JK_LB_STATE_ERROR) { jk_puts(s, "|"); status_write_uri(s, p, "T", JK_STATUS_CMD_RECOVER, JK_STATUS_MIME_UNKNOWN, name, sub_name, 0, 0, "", l); } } jk_puts(s, "]"); jk_puts(s, " 

\n"); if (!read_only) { const char *arg; status_get_string(p, JK_STATUS_ARG_CMD, NULL, &arg, l); status_start_form(s, p, "get", JK_STATUS_CMD_EDIT, NULL, l); jk_printf(s, l, JK_STATUS_FORM_HIDDEN_STRING, JK_STATUS_ARG_WORKER, name); if (arg) jk_printf(s, l, JK_STATUS_FORM_HIDDEN_STRING, JK_STATUS_ARG_FROM, arg); jk_puts(s, "
Edit this attribute for all members:"); jk_putv(s, "
\n"); } } } if (name) display_maps(s, p, name, l); if (mime == JK_STATUS_MIME_XML) { jk_print_xml_close_elt(s, l, w, 2, "balancer"); } JK_TRACE_EXIT(l); } static void display_worker_ajp(jk_ws_service_t *s, status_endpoint_t *p, ajp_worker_t *aw, int type, jk_logger_t *l) { int cmd; int mime; int read_only = 0; int single = 0; unsigned int hide_ajp_conf; const char *arg; int map_count; const char *name = aw->name; status_worker_t *w = p->worker; JK_TRACE_ENTER(l); status_get_string(p, JK_STATUS_ARG_CMD, NULL, &arg, l); cmd = status_cmd_int(arg); status_get_string(p, JK_STATUS_ARG_MIME, NULL, &arg, l); mime = status_mime_int(arg); hide_ajp_conf = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) & JK_STATUS_ARG_OPTION_NO_AJP_CONF; if (w->read_only) { read_only = 1; } else { read_only = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) & JK_STATUS_ARG_OPTION_READ_ONLY; } if (cmd == JK_STATUS_CMD_SHOW) { single = 1; } if (aw->sequence != aw->s->h.sequence) jk_ajp_pull(aw, JK_FALSE, l); map_count = count_maps(s, name, l); if (mime == JK_STATUS_MIME_HTML) { jk_puts(s, "

["); if (single) jk_puts(s, "S"); else status_write_uri(s, p, "S", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN, name, "", 0, 0, "", l); if (!read_only) { jk_puts(s, "|"); status_write_uri(s, p, "E", JK_STATUS_CMD_EDIT, JK_STATUS_MIME_UNKNOWN, name, "", 0, 0, "", l); jk_puts(s, "|"); status_write_uri(s, p, "R", JK_STATUS_CMD_RESET, JK_STATUS_MIME_UNKNOWN, name, "", 0, 0, "", l); } jk_puts(s, "]  "); jk_putv(s, "Worker Status for ", name, "

\n", NULL); if (!hide_ajp_conf) { jk_puts(s, "" JK_STATUS_SHOW_AJP_CONF_HEAD); jk_puts(s, "["); status_write_uri(s, p, "Hide", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN, NULL, NULL, JK_STATUS_ARG_OPTION_NO_AJP_CONF, 0, NULL, l); jk_puts(s, "]"); display_worker_ajp_conf_details(s, p, aw, 0, type, l); jk_puts(s, "
\n
\n"); } else { jk_puts(s, "

\n"); if (single) { status_write_uri(s, p, "Show AJP Configuration", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_AJP_CONF, "", l); } else { status_write_uri(s, p, "Show AJP Configuration", JK_STATUS_CMD_LIST, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_AJP_CONF, "", l); } jk_puts(s, "

\n"); } jk_puts(s, "" JK_STATUS_SHOW_AJP_HEAD); } display_worker_ajp_details(s, p, aw, NULL, NULL, 0, 0, map_count, l); if (mime == JK_STATUS_MIME_HTML) { jk_puts(s, "
\n"); } if (name) display_maps(s, p, name, l); JK_TRACE_EXIT(l); } static void display_worker(jk_ws_service_t *s, status_endpoint_t *p, jk_worker_t *jw, lb_sub_worker_t *swr, jk_logger_t *l) { status_worker_t *w = p->worker; JK_TRACE_ENTER(l); if (jw->type == JK_LB_WORKER_TYPE) { lb_worker_t *lb = (lb_worker_t *)jw->worker_private; if (lb) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' %s lb worker '%s'", w->name, "displaying", lb->name); display_worker_lb(s, p, lb, swr, l); } else { jk_log(l, JK_LOG_WARNING, "Status worker '%s' lb worker is (null)", w->name); } } else if (jw->type == JK_AJP13_WORKER_TYPE || jw->type == JK_AJP14_WORKER_TYPE) { ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private; if (aw) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' %s ajp worker '%s'", w->name, "displaying", aw->name); display_worker_ajp(s, p, aw, jw->type, l); } else { jk_log(l, JK_LOG_WARNING, "Status worker '%s' aw worker is (null)", w->name); } } else { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' worker type not implemented", w->name); JK_TRACE_EXIT(l); return; } } static void form_worker(jk_ws_service_t *s, status_endpoint_t *p, jk_worker_t *jw, jk_logger_t *l) { const char *name = NULL; lb_worker_t *lb = NULL; status_worker_t *w = p->worker; JK_TRACE_ENTER(l); if (jw->type == JK_LB_WORKER_TYPE) { lb = (lb_worker_t *)jw->worker_private; name = lb->name; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' producing edit form for lb worker '%s'", w->name, name); } else { jk_log(l, JK_LOG_WARNING, "Status worker '%s' worker type not implemented", w->name); JK_TRACE_EXIT(l); return; } if (!lb) { jk_log(l, JK_LOG_WARNING, "Status worker '%s' lb structure is (null)", w->name); JK_TRACE_EXIT(l); return; } jk_putv(s, "

Edit load balancer settings for ", name, "

\n", NULL); status_start_form(s, p, "get", JK_STATUS_CMD_UPDATE, NULL, l); jk_putv(s, "\n\n", lb->retries); jk_putv(s, "\n", lb->retry_interval); jk_putv(s, "\n", lb->recover_wait_time); jk_putv(s, "\n", lb->error_escalation_time); jk_putv(s, "\n", lb->max_reply_timeouts); jk_putv(s, "\n"); jk_putv(s, "\n"); jk_putv(s, "\n", NULL); jk_putv(s, "\n"); jk_putv(s, "\n"); jk_putv(s, "\n"); jk_putv(s, "\n"); jk_putv(s, "\n"); jk_putv(s, "\n", NULL); jk_putv(s, "\n"); jk_putv(s, "\n"); jk_puts(s, "
", JK_STATUS_ARG_LB_TEXT_RETRIES, ":
", JK_STATUS_ARG_LB_TEXT_RETRY_INT, ":
", JK_STATUS_ARG_LB_TEXT_RECOVER_TIME, ":
", JK_STATUS_ARG_LB_TEXT_ERROR_ESCALATION_TIME, ":
", JK_STATUS_ARG_LB_TEXT_MAX_REPLY_TIMEOUTS, ":
", JK_STATUS_ARG_LB_TEXT_STICKY, ":sticky_session) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/>
", JK_STATUS_ARG_LB_TEXT_STICKY_FORCE, ":sticky_session_force) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/>
", JK_STATUS_ARG_LB_TEXT_METHOD, ":
  Requestslbmethod == JK_LB_METHOD_REQUESTS) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/>
  Trafficlbmethod == JK_LB_METHOD_TRAFFIC) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/>
  Busynesslbmethod == JK_LB_METHOD_BUSYNESS) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/>
  Sessionslbmethod == JK_LB_METHOD_SESSIONS) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/>
  Nextlbmethod == JK_LB_METHOD_NEXT) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/>
", JK_STATUS_ARG_LB_TEXT_LOCK, ":
  Optimisticlblock == JK_LB_LOCK_OPTIMISTIC) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/>
  Pessimisticlblock == JK_LB_LOCK_PESSIMISTIC) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/>
\n"); jk_puts(s, "
\n"); JK_TRACE_EXIT(l); } static void form_member(jk_ws_service_t *s, status_endpoint_t *p, lb_sub_worker_t *wr, ajp_worker_t *aw, const char *lb_name, jk_logger_t *l) { status_worker_t *w = p->worker; JK_TRACE_ENTER(l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' producing edit form for sub worker '%s' of lb worker '%s'", w->name, wr? wr->name : aw->name, lb_name); jk_putv(s, "

Edit worker settings for ", wr? wr->name : aw->name, "

\n", NULL); status_start_form(s, p, "get", JK_STATUS_CMD_UPDATE, NULL, l); if (wr) { jk_puts(s, "\n"); jk_puts(s, "\n"); jk_puts(s, "\n"); jk_puts(s, "
Balancing related settings  AJP settings
\n"); jk_putv(s, "\n", NULL); jk_putv(s, "\n"); jk_putv(s, "\n"); jk_putv(s, "\n"); jk_putv(s, "\n", wr->lb_factor); jk_putv(s, "\n", JK_MAX_NAME_LEN); jk_putv(s, "\n", JK_MAX_NAME_LEN); jk_putv(s, "\n", JK_MAX_NAME_LEN); jk_putv(s, "\n", wr->distance); jk_puts(s, "
", JK_STATUS_ARG_LBM_TEXT_ACTIVATION, ":
  Activeactivation == JK_LB_ACTIVATION_ACTIVE) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/>
  Disabledactivation == JK_LB_ACTIVATION_DISABLED) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/>
  Stoppedactivation == JK_LB_ACTIVATION_STOPPED) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/>
", JK_STATUS_ARG_LBM_TEXT_FACTOR, ":
", JK_STATUS_ARG_LBM_TEXT_ROUTE, ":route, NULL); jk_printf(s, l, "\" maxlength=\"%d\"/>
", JK_STATUS_ARG_LBM_TEXT_REDIRECT, ":redirect, NULL); jk_printf(s, l, "\" maxlength=\"%d\"/>
", JK_STATUS_ARG_LBM_TEXT_DOMAIN, ":domain, NULL); jk_printf(s, l, "\" maxlength=\"%d\"/>
", JK_STATUS_ARG_LBM_TEXT_DISTANCE, ":
\n"); jk_puts(s, "
\n"); } jk_puts(s, "\n"); jk_putv(s, "\n", JK_MAX_NAME_LEN); jk_putv(s, "\n", aw->port); jk_putv(s, "\n", aw->cache_timeout); jk_putv(s, "\n", aw->ping_timeout); jk_putv(s, "\n", aw->connect_timeout); jk_putv(s, "\n", aw->prepost_timeout); jk_putv(s, "\n", aw->reply_timeout); jk_putv(s, "\n", aw->retries); jk_putv(s, "\n", aw->retry_interval); jk_putv(s, "\n", aw->conn_ping_interval); jk_putv(s, "\n", aw->recovery_opts); jk_putv(s, "\n", aw->busy_limit); jk_putv(s, "\n", aw->max_packet_size); jk_puts(s, "
", JK_STATUS_ARG_AJP_TEXT_HOST_STR, ":host, NULL); jk_printf(s, l, "\" maxlength=\"%d\"/>
", JK_STATUS_ARG_AJP_TEXT_PORT, ":
", JK_STATUS_ARG_AJP_TEXT_CACHE_TO, ":
", JK_STATUS_ARG_AJP_TEXT_PING_TO, ":
", JK_STATUS_ARG_AJP_TEXT_CONNECT_TO, ":
", JK_STATUS_ARG_AJP_TEXT_PREPOST_TO, ":
", JK_STATUS_ARG_AJP_TEXT_REPLY_TO, ":
", JK_STATUS_ARG_AJP_TEXT_RETRIES, ":
", JK_STATUS_ARG_AJP_TEXT_RETRY_INT, ":
", JK_STATUS_ARG_AJP_TEXT_CPING_INT, ":
", JK_STATUS_ARG_AJP_TEXT_REC_OPTS, ":
", JK_STATUS_ARG_AJP_TEXT_BUSY_LIMIT, ":
", JK_STATUS_ARG_AJP_TEXT_MAX_PK_SZ, ":
\n"); if (wr) jk_puts(s, "
\n"); jk_puts(s, "
\n\n"); JK_TRACE_EXIT(l); } static void form_all_members(jk_ws_service_t *s, status_endpoint_t *p, jk_worker_t *jw, const char *attribute, jk_logger_t *l) { const char *name = NULL; lb_worker_t *lb = NULL; status_worker_t *w = p->worker; const char *aname; unsigned int i; JK_TRACE_ENTER(l); if (!attribute) { jk_log(l, JK_LOG_WARNING, "Status worker '%s' missing request parameter '%s'", w->name, JK_STATUS_ARG_ATTRIBUTE); JK_TRACE_EXIT(l); return; } else { if (!strcmp(attribute, JK_STATUS_ARG_LBM_ACTIVATION)) aname=JK_STATUS_ARG_LBM_TEXT_ACTIVATION; else if (!strcmp(attribute, JK_STATUS_ARG_LBM_FACTOR)) aname=JK_STATUS_ARG_LBM_TEXT_FACTOR; else if (!strcmp(attribute, JK_STATUS_ARG_LBM_ROUTE)) aname=JK_STATUS_ARG_LBM_TEXT_ROUTE; else if (!strcmp(attribute, JK_STATUS_ARG_LBM_REDIRECT)) aname=JK_STATUS_ARG_LBM_TEXT_REDIRECT; else if (!strcmp(attribute, JK_STATUS_ARG_LBM_DOMAIN)) aname=JK_STATUS_ARG_LBM_TEXT_DOMAIN; else if (!strcmp(attribute, JK_STATUS_ARG_LBM_DISTANCE)) aname=JK_STATUS_ARG_LBM_TEXT_DISTANCE; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CACHE_TO)) aname=JK_STATUS_ARG_AJP_TEXT_CACHE_TO; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_PING_TO)) aname=JK_STATUS_ARG_AJP_TEXT_PING_TO; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CONNECT_TO)) aname=JK_STATUS_ARG_AJP_TEXT_CONNECT_TO; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_PREPOST_TO)) aname=JK_STATUS_ARG_AJP_TEXT_PREPOST_TO; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REPLY_TO)) aname=JK_STATUS_ARG_AJP_TEXT_REPLY_TO; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_RETRIES)) aname=JK_STATUS_ARG_AJP_TEXT_RETRIES; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_RETRY_INT)) aname=JK_STATUS_ARG_AJP_TEXT_RETRY_INT; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CPING_INT)) aname=JK_STATUS_ARG_AJP_TEXT_CPING_INT; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REC_OPTS)) aname=JK_STATUS_ARG_AJP_TEXT_REC_OPTS; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_BUSY_LIMIT)) aname=JK_STATUS_ARG_AJP_TEXT_BUSY_LIMIT; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_MAX_PK_SZ)) aname=JK_STATUS_ARG_AJP_TEXT_MAX_PK_SZ; else { jk_log(l, JK_LOG_WARNING, "Status worker '%s' unknown attribute '%s'", w->name, attribute); JK_TRACE_EXIT(l); return; } } if (jw->type == JK_LB_WORKER_TYPE) { lb = (lb_worker_t *)jw->worker_private; name = lb->name; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' producing edit form for attribute '%s' [%s] of all members of lb worker '%s'", w->name, attribute, aname, name); } else { jk_log(l, JK_LOG_WARNING, "Status worker '%s' worker type not implemented", w->name); JK_TRACE_EXIT(l); return; } if (lb) { jk_putv(s, "

Edit attribute '", aname, "' for all members of load balancer ", name, "

\n", NULL); status_start_form(s, p, "get", JK_STATUS_CMD_UPDATE, NULL, l); jk_putv(s, "" "" "", NULL); for (i = 0; i < lb->num_of_workers; i++) { lb_sub_worker_t *wr = &(lb->lb_workers[i]); jk_worker_t *jw = wr->worker; ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private;; jk_putv(s, ""); } jk_puts(s, "
Balanced Worker", aname, "
", wr->name, "\n", NULL); if (!strcmp(attribute, JK_STATUS_ARG_LBM_ACTIVATION)) { jk_printf(s, l, "Active: activation == JK_LB_ACTIVATION_ACTIVE) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/> | \n"); jk_printf(s, l, "Disabled: activation == JK_LB_ACTIVATION_DISABLED) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/> | \n"); jk_printf(s, l, "Stopped: activation == JK_LB_ACTIVATION_STOPPED) jk_puts(s, " checked=\"checked\""); jk_puts(s, "/>\n"); } else if (!strcmp(attribute, JK_STATUS_ARG_LBM_FACTOR)) { jk_printf(s, l, "\n", wr->lb_factor); } else if (!strcmp(attribute, JK_STATUS_ARG_LBM_ROUTE)) { jk_printf(s, l, "route, NULL); jk_printf(s, l, "\" maxlength=\"%d\"/>\n", JK_MAX_NAME_LEN); } else if (!strcmp(attribute, JK_STATUS_ARG_LBM_REDIRECT)) { jk_printf(s, l, "redirect, NULL); jk_printf(s, l, "\" maxlength=\"%d\"/>\n", JK_MAX_NAME_LEN); } else if (!strcmp(attribute, JK_STATUS_ARG_LBM_DOMAIN)) { jk_printf(s, l, "domain, NULL); jk_printf(s, l, "\" maxlength=\"%d\"/>\n", JK_MAX_NAME_LEN); } else if (!strcmp(attribute, JK_STATUS_ARG_LBM_DISTANCE)) { jk_printf(s, l, "\n", wr->distance); } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CACHE_TO)) { jk_printf(s, l, "\n", aw->cache_timeout); } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_PING_TO)) { jk_printf(s, l, "\n", aw->ping_timeout); } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CONNECT_TO)) { jk_printf(s, l, "\n", aw->connect_timeout); } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_PREPOST_TO)) { jk_printf(s, l, "\n", aw->prepost_timeout); } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REPLY_TO)) { jk_printf(s, l, "\n", aw->reply_timeout); } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_RETRIES)) { jk_printf(s, l, "\n", aw->retries); } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_RETRY_INT)) { jk_printf(s, l, "\n", aw->retry_interval); } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CPING_INT)) { jk_printf(s, l, "\n", aw->conn_ping_interval); } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REC_OPTS)) { jk_printf(s, l, "\n", aw->recovery_opts); } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_BUSY_LIMIT)) { jk_printf(s, l, "\n", aw->busy_limit); } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_MAX_PK_SZ)) { jk_printf(s, l, "\n", aw->max_packet_size); } jk_puts(s, "
\n"); jk_puts(s, "
\n"); } JK_TRACE_EXIT(l); } static void commit_worker(jk_ws_service_t *s, status_endpoint_t *p, jk_worker_t *jw, jk_logger_t *l) { const char *name = NULL; lb_worker_t *lb = NULL; status_worker_t *w = p->worker; const char *arg; int sync_needed = JK_FALSE; int i; JK_TRACE_ENTER(l); if (jw->type == JK_LB_WORKER_TYPE) { lb = (lb_worker_t *)jw->worker_private; name = lb->name; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' committing changes for lb worker '%s'", w->name, name); } else { jk_log(l, JK_LOG_WARNING, "Status worker '%s' worker type not implemented", w->name); JK_TRACE_EXIT(l); return; } if (!lb) { jk_log(l, JK_LOG_WARNING, "Status worker '%s' lb structure is (null)", w->name); JK_TRACE_EXIT(l); return; } i = status_get_int(p, JK_STATUS_ARG_LB_RETRIES, lb->retries, l); if (i != lb->retries && i > 0) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'retries' for lb worker '%s' from '%d' to '%d'", w->name, name, lb->retries, i); lb->retries = i; sync_needed = JK_TRUE; } i = status_get_int(p, JK_STATUS_ARG_LB_RETRY_INT, lb->retry_interval, l); if (i != lb->retry_interval && i > 0) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'retry_interval' for lb worker '%s' from '%d' to '%d'", w->name, name, lb->retry_interval, i); lb->retry_interval = i; sync_needed = JK_TRUE; } i = status_get_int(p, JK_STATUS_ARG_LB_RECOVER_TIME, lb->recover_wait_time, l); if (i != lb->recover_wait_time && i > 0) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'recover_time' for lb worker '%s' from '%d' to '%d'", w->name, name, lb->recover_wait_time, i); lb->recover_wait_time = i; sync_needed = JK_TRUE; } i = status_get_int(p, JK_STATUS_ARG_LB_ERROR_ESCALATION_TIME, lb->error_escalation_time, l); if (i != lb->error_escalation_time && i > 0) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'error_escalation_time' for lb worker '%s' from '%d' to '%d'", w->name, name, lb->error_escalation_time, i); lb->error_escalation_time = i; sync_needed = JK_TRUE; } i = status_get_int(p, JK_STATUS_ARG_LB_MAX_REPLY_TIMEOUTS, lb->max_reply_timeouts, l); if (i != lb->max_reply_timeouts && i >= 0) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'max_reply_timeouts' for lb worker '%s' from '%d' to '%d'", w->name, name, lb->max_reply_timeouts, i); lb->max_reply_timeouts = i; sync_needed = JK_TRUE; } i = status_get_bool(p, JK_STATUS_ARG_LB_STICKY, lb->sticky_session, l); if (i != lb->sticky_session) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'sticky_session' for lb worker '%s' from '%d' to '%d'", w->name, name, lb->sticky_session, i); lb->sticky_session = i; sync_needed = JK_TRUE; } i = status_get_bool(p, JK_STATUS_ARG_LB_STICKY_FORCE, lb->sticky_session_force, l); if (i != lb->sticky_session_force) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'sticky_session_force' for lb worker '%s' from '%d' to '%d'", w->name, name, lb->sticky_session_force, i); lb->sticky_session_force = i; sync_needed = JK_TRUE; } if (status_get_string(p, JK_STATUS_ARG_LB_METHOD, NULL, &arg, l) == JK_TRUE) { i = jk_lb_get_method_code(arg); if (i != lb->lbmethod && i >= 0 && i <= JK_LB_METHOD_MAX) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'method' for lb worker '%s' from '%s' to '%s'", w->name, name, jk_lb_get_method(lb, l), jk_lb_get_method_direct(i, l)); lb->lbmethod = i; sync_needed = JK_TRUE; } } if (status_get_string(p, JK_STATUS_ARG_LB_LOCK, NULL, &arg, l) == JK_TRUE) { i = jk_lb_get_lock_code(arg); if (i != lb->lblock && i >= 0 && i <= JK_LB_LOCK_MAX) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'lock' for lb worker '%s' from '%s' to '%s'", w->name, name, jk_lb_get_lock(lb, l), jk_lb_get_lock_direct(i, l)); lb->lblock = i; sync_needed = JK_TRUE; } } if (sync_needed == JK_TRUE) { lb->sequence = -1; jk_lb_push(lb, JK_TRUE, l); } } static int set_int_if_changed(status_endpoint_t *p, const char *name, const char *att, const char *arg, int min, int max, int *param, const char *lb_name, jk_logger_t *l) { int i; status_worker_t *w = p->worker; i = status_get_int(p, arg, *param, l); if (i != *param && i >= min && i <= max) { if (lb_name) jk_log(l, JK_LOG_INFO, "Status worker '%s' changing '%s' for sub worker '%s' of lb worker '%s' from '%d' to '%d'", w->name, att, name, lb_name, *param, i); else jk_log(l, JK_LOG_INFO, "Status worker '%s' changing '%s' for ajp worker '%s' from '%d' to '%d'", w->name, att, name, *param, i); *param = i; return JK_TRUE; } return JK_FALSE; } static int set_uint_if_changed(status_endpoint_t *p, const char *name, const char *att, const char *arg, unsigned int min, unsigned int max, unsigned int align, unsigned int *param, const char *lb_name, jk_logger_t *l) { unsigned i; status_worker_t *w = p->worker; i = (unsigned)status_get_int(p, arg, *param, l); if (align > 1) { i = JK_ALIGN(i, align); } if (i != *param && i >= min && i <= max) { if (lb_name) jk_log(l, JK_LOG_INFO, "Status worker '%s' changing '%s' for sub worker '%s' of lb worker '%s' from '%u' to '%u'", w->name, att, name, lb_name, *param, i); else jk_log(l, JK_LOG_INFO, "Status worker '%s' changing '%s' for ajp worker '%s' from '%u' to '%u'", w->name, att, name, *param, i); *param = i; return JK_TRUE; } return JK_FALSE; } static int commit_member(jk_ws_service_t *s, status_endpoint_t *p, lb_worker_t *lb, lb_sub_worker_t *wr, ajp_worker_t *aw, int *side_effect, jk_logger_t *l) { const char *arg; const char *lb_name = NULL; status_worker_t *w = p->worker; int rc = JK_TRUE; int rv; int i; int old; int resolve = JK_FALSE; char host[JK_SHM_STR_SIZ]; int port = 0; JK_TRACE_ENTER(l); if (lb) { lb_name = lb->name; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' committing changes for sub worker '%s' of lb worker '%s'", w->name, wr->name, lb_name); } else { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' committing changes for ajp worker '%s'", w->name, aw->name); } if (lb) { if (status_get_string(p, JK_STATUS_ARG_LBM_ACTIVATION, NULL, &arg, l) == JK_TRUE) { i = jk_lb_get_activation_code(arg); if (i != wr->activation && i >= 0 && i <= JK_LB_ACTIVATION_MAX) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'activation' for sub worker '%s' of lb worker '%s' from '%s' to '%s'", w->name, wr->name, lb_name, jk_lb_get_activation(wr, l), jk_lb_get_activation_direct(i, l)); wr->activation = i; *side_effect |= JK_STATUS_NEEDS_RESET_LB_VALUES | JK_STATUS_NEEDS_PUSH; } } if (set_int_if_changed(p, wr->name, "lbfactor", JK_STATUS_ARG_LBM_FACTOR, 1, INT_MAX, &wr->lb_factor, lb_name, l)) /* Recalculate the load multiplicators wrt. lb_factor */ *side_effect |= JK_STATUS_NEEDS_UPDATE_MULT | JK_STATUS_NEEDS_PUSH; if ((rv = status_get_string(p, JK_STATUS_ARG_LBM_ROUTE, NULL, &arg, l)) == JK_TRUE) { if (jk_check_attribute_length("route", arg, l) == JK_FALSE) { const char *msg = "Update failed (at least partially): new route '%s' " "too long for sub worker '%s', see log file for details."; size_t size = strlen(msg) + strlen(arg) + strlen(wr->name) + 1; p->msg = jk_pool_alloc(s->pool, size); snprintf(p->msg, size, msg, arg, aw->name); rc = JK_FALSE; } else if (strncmp(wr->route, arg, JK_SHM_STR_SIZ )) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'route' for sub worker '%s' of lb worker '%s' from '%s' to '%s'", w->name, wr->name, lb_name, wr->route, arg); strncpy(wr->route, arg, JK_SHM_STR_SIZ ); *side_effect |= JK_STATUS_NEEDS_PUSH; if (!wr->domain[0]) { char * id_domain = strchr(wr->route, '.'); if (id_domain) { *id_domain = '\0'; strcpy(wr->domain, wr->route); *id_domain = '.'; } } } } if ((rv = status_get_string(p, JK_STATUS_ARG_LBM_REDIRECT, NULL, &arg, l)) == JK_TRUE) { if (jk_check_attribute_length("redirect", arg, l) == JK_FALSE) { const char *msg = "Update failed (at least partially): new redirect '%s' " "too long for sub worker '%s', see log file for details."; size_t size = strlen(msg) + strlen(arg) + strlen(wr->name) + 1; p->msg = jk_pool_alloc(s->pool, size); snprintf(p->msg, size, msg, arg, aw->name); rc = JK_FALSE; } else if (strncmp(wr->redirect, arg, JK_SHM_STR_SIZ )) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'redirect' for sub worker '%s' of lb worker '%s' from '%s' to '%s'", w->name, wr->name, lb_name, wr->redirect, arg); strncpy(wr->redirect, arg, JK_SHM_STR_SIZ ); *side_effect |= JK_STATUS_NEEDS_PUSH; } } if ((rv = status_get_string(p, JK_STATUS_ARG_LBM_DOMAIN, NULL, &arg, l)) == JK_TRUE) { if (jk_check_attribute_length("domain", arg, l) == JK_FALSE) { const char *msg = "Update failed (at least partially): new domain '%s' " "too long for sub worker '%s', see log file for details."; size_t size = strlen(msg) + strlen(arg) + strlen(wr->name) + 1; p->msg = jk_pool_alloc(s->pool, size); snprintf(p->msg, size, msg, arg, aw->name); rc = JK_FALSE; } else if (strncmp(wr->domain, arg, JK_SHM_STR_SIZ )) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'domain' for sub worker '%s' of lb worker '%s' from '%s' to '%s'", w->name, wr->name, lb_name, wr->domain, arg); strncpy(wr->domain, arg, JK_SHM_STR_SIZ); *side_effect |= JK_STATUS_NEEDS_PUSH; } } if (set_int_if_changed(p, wr->name, "distance", JK_STATUS_ARG_LBM_DISTANCE, 0, INT_MAX, &wr->distance, lb_name, l)) *side_effect |= JK_STATUS_NEEDS_PUSH; } old = aw->cache_timeout; if (set_int_if_changed(p, aw->name, "connection_pool_timeout", JK_STATUS_ARG_AJP_CACHE_TO, 0, INT_MAX, &aw->cache_timeout, lb_name, l)) { *side_effect |= JK_STATUS_NEEDS_PUSH; if (old == 0) { unsigned int i; for (i = 0; i < aw->ep_cache_sz; i++) { ajp_endpoint_t *ae = (ajp_endpoint_t *) aw->ep_cache[i]; if (ae) ae->last_access = time(NULL); } } } port = aw->port; if (set_int_if_changed(p, aw->name, "port", JK_STATUS_ARG_AJP_PORT, 0, INT_MAX, &port, lb_name, l)) { strncpy(host, aw->host, JK_SHM_STR_SIZ); resolve = JK_TRUE; } if ((rv = status_get_string(p, JK_STATUS_ARG_AJP_HOST_STR, NULL, &arg, l)) == JK_TRUE) { if (jk_check_attribute_length("host name", arg, l) == JK_FALSE) { const char *msg = "Update failed (at least partially): new host name '%s' " "too long for sub worker '%s', see log file for details."; size_t size = strlen(msg) + strlen(arg) + strlen(aw->name) + 1; p->msg = jk_pool_alloc(s->pool, size); snprintf(p->msg, size, msg, arg, aw->name); rc = JK_FALSE; } else if (strncmp(aw->host, arg, JK_SHM_STR_SIZ)) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'host' for sub worker '%s' from '%s' to '%s'", w->name, aw->name, aw->host, arg); strncpy(host, arg, JK_SHM_STR_SIZ); resolve = JK_TRUE; } } if (resolve == JK_TRUE) { jk_sockaddr_t inet_addr; if (!jk_resolve(host, port, &inet_addr, aw->worker.we->pool, aw->prefer_ipv6, l)) { const char *msg = "Update failed (at least partially): could not resolve address '%s:%d' for sub worker '%s'."; size_t size = strlen(msg) + strlen(host) + strlen(aw->name) + 10 + 1; p->msg = jk_pool_alloc(s->pool, size); snprintf(p->msg, size, msg, host, port, aw->name); jk_log(l, JK_LOG_ERROR, "Status worker '%s' failed resolving address '%s:%d' for sub worker '%s'.", w->name, host, port, aw->name); rc = JK_FALSE; } else { /* This is not atomic and not thread safe */ aw->port = port; strncpy(aw->host, host, JK_SHM_STR_SIZ); jk_clone_sockaddr(&(aw->worker_inet_addr), &inet_addr); *side_effect |= JK_STATUS_NEEDS_PUSH | JK_STATUS_NEEDS_ADDR_PUSH; } } if (set_int_if_changed(p, aw->name, "ping_timeout", JK_STATUS_ARG_AJP_PING_TO, 0, INT_MAX, &aw->ping_timeout, lb_name, l)) *side_effect |= JK_STATUS_NEEDS_PUSH; if (set_int_if_changed(p, aw->name, "connect_timeout", JK_STATUS_ARG_AJP_CONNECT_TO, 0, INT_MAX, &aw->connect_timeout, lb_name, l)) *side_effect |= JK_STATUS_NEEDS_PUSH; if (set_int_if_changed(p, aw->name, "prepost_timeout", JK_STATUS_ARG_AJP_PREPOST_TO, 0, INT_MAX, &aw->prepost_timeout, lb_name, l)) *side_effect |= JK_STATUS_NEEDS_PUSH; if (set_int_if_changed(p, aw->name, "reply_timeout", JK_STATUS_ARG_AJP_REPLY_TO, 0, INT_MAX, &aw->reply_timeout, lb_name, l)) *side_effect |= JK_STATUS_NEEDS_PUSH; if (set_int_if_changed(p, aw->name, "retries", JK_STATUS_ARG_AJP_RETRIES, 1, INT_MAX, &aw->retries, lb_name, l)) *side_effect |= JK_STATUS_NEEDS_PUSH; if (set_int_if_changed(p, aw->name, "retry_interval", JK_STATUS_ARG_AJP_RETRY_INT, 1, INT_MAX, &aw->retry_interval, lb_name, l)) *side_effect |= JK_STATUS_NEEDS_PUSH; if (set_int_if_changed(p, aw->name, "connection_ping_interval", JK_STATUS_ARG_AJP_CPING_INT, 1, INT_MAX, &aw->conn_ping_interval, lb_name, l)) *side_effect |= JK_STATUS_NEEDS_PUSH; if (set_uint_if_changed(p, aw->name, "recovery_options", JK_STATUS_ARG_AJP_REC_OPTS, 0, INT_MAX, 1, &aw->recovery_opts, lb_name, l)) *side_effect |= JK_STATUS_NEEDS_PUSH; if (set_int_if_changed(p, aw->name, "busy_limit", JK_STATUS_ARG_AJP_BUSY_LIMIT, 0, INT_MAX, &aw->busy_limit, lb_name, l)) *side_effect |= JK_STATUS_NEEDS_PUSH; if (set_uint_if_changed(p, aw->name, "max_packet_size", JK_STATUS_ARG_AJP_MAX_PK_SZ, AJP13_DEF_PACKET_SIZE, AJP13_MAX_PACKET_SIZE, AJP13_PACKET_SIZE_ALIGN, &aw->max_packet_size, lb_name, l)) { *side_effect |= JK_STATUS_NEEDS_PUSH; if (aw->max_packet_size > lb->max_packet_size) { lb->max_packet_size = aw->max_packet_size; } } return rc; } static void commit_all_members(jk_ws_service_t *s, status_endpoint_t *p, jk_worker_t *jw, const char *attribute, jk_logger_t *l) { const char *arg; char vname[32]; const char *name = NULL; lb_worker_t *lb = NULL; status_worker_t *w = p->worker; const char *aname; int i; int rc = 0; unsigned int j; JK_TRACE_ENTER(l); if (!attribute) { jk_log(l, JK_LOG_WARNING, "Status worker '%s' missing request parameter '%s'", w->name, JK_STATUS_ARG_ATTRIBUTE); JK_TRACE_EXIT(l); return; } else { if (!strcmp(attribute, JK_STATUS_ARG_LBM_ACTIVATION)) aname=JK_STATUS_ARG_LBM_TEXT_ACTIVATION; else if (!strcmp(attribute, JK_STATUS_ARG_LBM_FACTOR)) aname=JK_STATUS_ARG_LBM_TEXT_FACTOR; else if (!strcmp(attribute, JK_STATUS_ARG_LBM_ROUTE)) aname=JK_STATUS_ARG_LBM_TEXT_ROUTE; else if (!strcmp(attribute, JK_STATUS_ARG_LBM_REDIRECT)) aname=JK_STATUS_ARG_LBM_TEXT_REDIRECT; else if (!strcmp(attribute, JK_STATUS_ARG_LBM_DOMAIN)) aname=JK_STATUS_ARG_LBM_TEXT_DOMAIN; else if (!strcmp(attribute, JK_STATUS_ARG_LBM_DISTANCE)) aname=JK_STATUS_ARG_LBM_TEXT_DISTANCE; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CACHE_TO)) aname=JK_STATUS_ARG_AJP_TEXT_CACHE_TO; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_PING_TO)) aname=JK_STATUS_ARG_AJP_TEXT_PING_TO; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CONNECT_TO)) aname=JK_STATUS_ARG_AJP_TEXT_CONNECT_TO; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_PREPOST_TO)) aname=JK_STATUS_ARG_AJP_TEXT_PREPOST_TO; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REPLY_TO)) aname=JK_STATUS_ARG_AJP_TEXT_REPLY_TO; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_RETRIES)) aname=JK_STATUS_ARG_AJP_TEXT_RETRIES; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_RETRY_INT)) aname=JK_STATUS_ARG_AJP_TEXT_RETRY_INT; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CPING_INT)) aname=JK_STATUS_ARG_AJP_TEXT_CPING_INT; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REC_OPTS)) aname=JK_STATUS_ARG_AJP_TEXT_REC_OPTS; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_BUSY_LIMIT)) aname=JK_STATUS_ARG_AJP_TEXT_BUSY_LIMIT; else if (!strcmp(attribute, JK_STATUS_ARG_AJP_MAX_PK_SZ)) aname=JK_STATUS_ARG_AJP_TEXT_MAX_PK_SZ; else { jk_log(l, JK_LOG_WARNING, "Status worker '%s' unknown attribute '%s'", w->name, attribute); JK_TRACE_EXIT(l); return; } } if (jw->type == JK_LB_WORKER_TYPE) { lb = (lb_worker_t *)jw->worker_private; name = lb->name; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' committing changes for attribute '%s' [%s] of all members of lb worker '%s'", w->name, attribute, aname, name); } else { jk_log(l, JK_LOG_WARNING, "Status worker '%s' worker type not implemented", w->name); JK_TRACE_EXIT(l); return; } if (lb) { for (j = 0; j < lb->num_of_workers; j++) { int sync_needed = JK_FALSE; lb_sub_worker_t *wr = &(lb->lb_workers[j]); jk_worker_t *jw = wr->worker; ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private;; snprintf(vname, 32-1, "" JK_STATUS_ARG_MULT_VALUE_BASE "%d", j); if (!strcmp(attribute, JK_STATUS_ARG_LBM_FACTOR)) { if (set_int_if_changed(p, wr->name, "lbfactor", vname, 1, INT_MAX, &wr->lb_factor, name, l)) { rc = 2; sync_needed = JK_TRUE; } } else if (!strcmp(attribute, JK_STATUS_ARG_LBM_DISTANCE)) { if (set_int_if_changed(p, wr->name, "distance", vname, 0, INT_MAX, &wr->distance, name, l)) sync_needed = JK_TRUE; } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CACHE_TO)) { int old = aw->cache_timeout; if (set_int_if_changed(p, aw->name, "connection_pool_timeout", vname, 0, INT_MAX, &aw->cache_timeout, name, l)) { sync_needed = JK_TRUE; if (old == 0) { unsigned int i; for (i = 0; i < aw->ep_cache_sz; i++) { ajp_endpoint_t *ae = (ajp_endpoint_t *) aw->ep_cache[i]; if (ae) ae->last_access = time(NULL); } } } } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_PING_TO)) { if (set_int_if_changed(p, aw->name, "ping_timeout", vname, 0, INT_MAX, &aw->ping_timeout, name, l)) sync_needed = JK_TRUE; } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CONNECT_TO)) { if (set_int_if_changed(p, aw->name, "connect_timeout", vname, 0, INT_MAX, &aw->connect_timeout, name, l)) sync_needed = JK_TRUE; } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_PREPOST_TO)) { if (set_int_if_changed(p, aw->name, "prepost_timeout", vname, 0, INT_MAX, &aw->prepost_timeout, name, l)) sync_needed = JK_TRUE; } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REPLY_TO)) { if (set_int_if_changed(p, aw->name, "reply_timeout", vname, 0, INT_MAX, &aw->reply_timeout, name, l)) sync_needed = JK_TRUE; } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_RETRIES)) { if (set_int_if_changed(p, aw->name, "retries", vname, 1, INT_MAX, &aw->retries, name, l)) sync_needed = JK_TRUE; } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_RETRY_INT)) { if (set_int_if_changed(p, aw->name, "retry_interval", vname, 1, INT_MAX, &aw->retry_interval, name, l)) sync_needed = JK_TRUE; } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_CPING_INT)) { if (set_int_if_changed(p, aw->name, "connection_ping_interval", vname, 1, INT_MAX, &aw->conn_ping_interval, name, l)) sync_needed = JK_TRUE; } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_REC_OPTS)) { if (set_uint_if_changed(p, aw->name, "recovery_options", vname, 0, INT_MAX, 1, &aw->recovery_opts, name, l)) sync_needed = JK_TRUE; } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_BUSY_LIMIT)) { if (set_int_if_changed(p, aw->name, "busy_limit", vname, 0, INT_MAX, &aw->busy_limit, name, l)) sync_needed = JK_TRUE; } else if (!strcmp(attribute, JK_STATUS_ARG_AJP_MAX_PK_SZ)) { if (set_uint_if_changed(p, aw->name, "max_packet_size", vname, AJP13_DEF_PACKET_SIZE, AJP13_MAX_PACKET_SIZE, AJP13_PACKET_SIZE_ALIGN, &aw->max_packet_size, name, l)) { sync_needed = JK_TRUE; if (aw->max_packet_size > lb->max_packet_size) { lb->max_packet_size = aw->max_packet_size; } } } else { int rv = status_get_string(p, vname, NULL, &arg, l); if (!strcmp(attribute, JK_STATUS_ARG_LBM_ACTIVATION)) { if (rv == JK_TRUE) { i = jk_lb_get_activation_code(arg); if (i != wr->activation && i >= 0 && i <= JK_LB_ACTIVATION_MAX) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'activation' for sub worker '%s' of lb worker '%s' from '%s' to '%s'", w->name, wr->name, name, jk_lb_get_activation(wr, l), jk_lb_get_activation_direct(i, l)); wr->activation = i; rc = 1; sync_needed = JK_TRUE; } } } else if (!strcmp(attribute, JK_STATUS_ARG_LBM_ROUTE)) { if (rv == JK_TRUE) { if (jk_check_attribute_length("route", arg, l) == JK_FALSE) { const char *msg = "Update failed (at least partially): new route '%s' " "too long for sub worker '%s', see log file for details."; size_t size = strlen(msg) + strlen(arg) + strlen(wr->name) + 1; p->msg = jk_pool_alloc(s->pool, size); snprintf(p->msg, size, msg, arg, aw->name); rc = JK_FALSE; } else if (strncmp(wr->route, arg, JK_SHM_STR_SIZ)) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'route' for sub worker '%s' of lb worker '%s' from '%s' to '%s'", w->name, wr->name, name, wr->route, arg); strncpy(wr->route, arg, JK_SHM_STR_SIZ); sync_needed = JK_TRUE; if (!wr->domain[0]) { char * id_domain = strchr(wr->route, '.'); if (id_domain) { *id_domain = '\0'; strcpy(wr->domain, wr->route); *id_domain = '.'; } } } } } else if (!strcmp(attribute, JK_STATUS_ARG_LBM_REDIRECT)) { if (rv == JK_TRUE) { if (jk_check_attribute_length("redirect", arg, l) == JK_FALSE) { const char *msg = "Update failed (at least partially): new redirect '%s' " "too long for sub worker '%s', see log file for details."; size_t size = strlen(msg) + strlen(arg) + strlen(wr->name) + 1; p->msg = jk_pool_alloc(s->pool, size); snprintf(p->msg, size, msg, arg, aw->name); rc = JK_FALSE; } else if (strncmp(wr->redirect, arg, JK_SHM_STR_SIZ)) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'redirect' for sub worker '%s' of lb worker '%s' from '%s' to '%s'", w->name, wr->name, name, wr->redirect, arg); strncpy(wr->redirect, arg, JK_SHM_STR_SIZ); sync_needed = JK_TRUE; } } } else if (!strcmp(attribute, JK_STATUS_ARG_LBM_DOMAIN)) { if (rv == JK_TRUE) { if (jk_check_attribute_length("domain", arg, l) == JK_FALSE) { const char *msg = "Update failed (at least partially): new domain '%s' " "too long for sub worker '%s', see log file for details."; size_t size = strlen(msg) + strlen(arg) + strlen(wr->name) + 1; p->msg = jk_pool_alloc(s->pool, size); snprintf(p->msg, size, msg, arg, aw->name); rc = JK_FALSE; } else if (strncmp(wr->domain, arg, JK_SHM_STR_SIZ)) { jk_log(l, JK_LOG_INFO, "Status worker '%s' changing 'domain' for sub worker '%s' of lb worker '%s' from '%s' to '%s'", w->name, wr->name, name, wr->domain, arg); strncpy(wr->domain, arg, JK_SHM_STR_SIZ); sync_needed = JK_TRUE; } } } } if (sync_needed == JK_TRUE) { wr->sequence = -1; if (!rc) rc = 3; } } if (rc == 1) reset_lb_values(lb, l); else if (rc == 2) /* Recalculate the load multiplicators wrt. lb_factor */ update_mult(lb, l); if (rc) { lb->sequence = -1; jk_lb_push(lb, JK_TRUE, l); } } JK_TRACE_EXIT(l); } static void display_legend(jk_ws_service_t *s, status_endpoint_t *p, jk_logger_t *l) { int mime; const char *arg; unsigned int hide_legend; JK_TRACE_ENTER(l); status_get_string(p, JK_STATUS_ARG_MIME, NULL, &arg, l); mime = status_mime_int(arg); if (mime != JK_STATUS_MIME_HTML) { JK_TRACE_EXIT(l); return; } hide_legend = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) & JK_STATUS_ARG_OPTION_NO_LEGEND; if (hide_legend) { jk_puts(s, "

\n"); status_write_uri(s, p, "Show Legend", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_LEGEND, NULL, l); jk_puts(s, "

\n"); } else { jk_puts(s, "

Legend ["); status_write_uri(s, p, "Hide", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN, NULL, NULL, JK_STATUS_ARG_OPTION_NO_LEGEND, 0, NULL, l); jk_puts(s, "]

\n"); jk_puts(s, "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "\n" "
NameWorker name
TypeWorker type
RouteWorker route
ActWorker activation configuration
\n" "ACT=Active, DIS=Disabled, STP=Stopped
StateWorker error status
\n" "OK=OK, ERR=Error with substates
\n" "IDLE=No requests handled, BUSY=All connections busy,
\n" "REC=Recovering, PRB=Probing, FRC=Forced Recovery
DWorker distance
FLoad Balancer factor
MLoad Balancer multiplicity
VLoad Balancer value
AccNumber of requests
SessNumber of sessions created
ErrNumber of failed requests
CENumber of client errors
RENumber of reply timeouts (decayed)
WrNumber of bytes transferred
RdNumber of bytes read
BusyCurrent number of busy connections
MaxBusyMaximum number of busy connections
ConCurrent number of backend connections
MaxConMaximum number of backend connections
RRRoute redirect
CdCluster domain
RsRecovery scheduled in app. min/max seconds
LRSeconds since last reset of statistics counters
LETimestamp of the last error
\n"); } JK_TRACE_EXIT(l); } static int check_worker(jk_ws_service_t *s, status_endpoint_t *p, jk_uint32_t allow_wildchars, jk_logger_t *l) { const char *worker; const char *sub_worker; status_worker_t *w = p->worker; jk_worker_t *jw = NULL; lb_sub_worker_t *wr = NULL; JK_TRACE_ENTER(l); if (fetch_worker_and_sub_worker(p, "checking", &worker, &sub_worker, l) == JK_FALSE || search_worker(s, p, &jw, worker, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } if (sub_worker && sub_worker[0]) { unsigned int idx = 0; unsigned int *wi = NULL; if (strchr(sub_worker, '*') || strchr(sub_worker, '?')) { /* We have a wildchar matching rule */ if (!allow_wildchars) { jk_log(l, JK_LOG_ERROR, "Status worker '%s' wildcards in sub worker '%s' of worker '%s' not allowed for this command", w->name, sub_worker, worker ? worker : "(null)"); p->msg = "wildcard not allowed in sub worker for this command"; JK_TRACE_EXIT(l); return JK_FALSE; } else { wi = &idx; } } if (search_sub_worker(s, p, jw, worker, &wr, sub_worker, wi, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } } JK_TRACE_EXIT(l); return JK_TRUE; } static void count_workers(jk_ws_service_t *s, status_endpoint_t *p, int *lb_cnt, int *ajp_cnt, jk_logger_t *l) { unsigned int i; jk_worker_t *jw = NULL; status_worker_t *w = p->worker; JK_TRACE_ENTER(l); *lb_cnt = 0; *ajp_cnt = 0; for (i = 0; i < w->we->num_of_workers; i++) { jw = wc_get_worker_for_name(w->we->worker_list[i], l); if (!jw) { jk_log(l, JK_LOG_WARNING, "Status worker '%s' could not find worker '%s'", w->name, w->we->worker_list[i]); continue; } if (jw->type == JK_LB_WORKER_TYPE) { (*lb_cnt)++; } else if (jw->type == JK_AJP13_WORKER_TYPE || jw->type == JK_AJP14_WORKER_TYPE) { (*ajp_cnt)++; } } JK_TRACE_EXIT(l); } static void list_workers_type(jk_ws_service_t *s, status_endpoint_t *p, int list_lb, int count, jk_logger_t *l) { const char *arg; unsigned int i; int mime; unsigned int hide; jk_worker_t *jw = NULL; status_worker_t *w = p->worker; JK_TRACE_ENTER(l); status_get_string(p, JK_STATUS_ARG_MIME, NULL, &arg, l); mime = status_mime_int(arg); if (list_lb) { hide = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) & JK_STATUS_ARG_OPTION_NO_LB; if (hide) { if (mime == JK_STATUS_MIME_HTML) { jk_puts(s, "

\n"); status_write_uri(s, p, "Show Load Balancing Workers", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_LB, NULL, l); jk_puts(s, "

\n"); } } else { if (mime == JK_STATUS_MIME_XML) { jk_print_xml_start_elt(s, l, w, 0, 0, "balancers"); jk_print_xml_att_int(s, l, 2, "count", count); jk_print_xml_stop_elt(s, l, 0, 0); } else if (mime == JK_STATUS_MIME_TXT) { jk_printf(s, l, "Balancer Workers: count=%d\n", count); } else if (mime == JK_STATUS_MIME_PROP) { jk_print_prop_att_int(s, l, w, NULL, "lb_count", count); } else { jk_printf(s, l, "

Listing Load Balancing Worker%s (%d Worker%s) [", count>1 ? "s" : "", count, count>1 ? "s" : ""); status_write_uri(s, p, "Hide", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN, NULL, NULL, JK_STATUS_ARG_OPTION_NO_LB, 0, NULL, l); jk_puts(s, "]

\n"); } } } else { hide = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) & JK_STATUS_ARG_OPTION_NO_AJP; if (hide) { if (mime == JK_STATUS_MIME_HTML) { jk_puts(s, "

\n"); status_write_uri(s, p, "Show AJP Workers", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, JK_STATUS_ARG_OPTION_NO_AJP, NULL, l); jk_puts(s, "

\n"); } } else { if (mime == JK_STATUS_MIME_XML) { jk_print_xml_start_elt(s, l, w, 0, 0, "ajp_workers"); jk_print_xml_att_int(s, l, 2, "count", count); jk_print_xml_stop_elt(s, l, 0, 0); } else if (mime == JK_STATUS_MIME_TXT) { jk_printf(s, l, "AJP Workers: count=%d\n", count); } else if (mime == JK_STATUS_MIME_PROP) { jk_print_prop_att_int(s, l, w, NULL, "ajp_count", count); } else { jk_printf(s, l, "

Listing AJP Worker%s (%d Worker%s) [", count>1 ? "s" : "", count, count>1 ? "s" : ""); status_write_uri(s, p, "Hide", JK_STATUS_CMD_UNKNOWN, JK_STATUS_MIME_UNKNOWN, NULL, NULL, JK_STATUS_ARG_OPTION_NO_AJP, 0, NULL, l); jk_puts(s, "]

\n"); } } } if (hide) { JK_TRACE_EXIT(l); return; } for (i = 0; i < w->we->num_of_workers; i++) { jw = wc_get_worker_for_name(w->we->worker_list[i], l); if (!jw) { jk_log(l, JK_LOG_WARNING, "Status worker '%s' could not find worker '%s'", w->name, w->we->worker_list[i]); continue; } if ((list_lb && jw->type == JK_LB_WORKER_TYPE) || (!list_lb && jw->type != JK_LB_WORKER_TYPE)) { display_worker(s, p, jw, NULL, l); } } if (list_lb) { if (mime == JK_STATUS_MIME_XML) { jk_print_xml_close_elt(s, l, w, 0, "balancers"); } else if (mime == JK_STATUS_MIME_TXT) { } else if (mime == JK_STATUS_MIME_PROP) { } else if (mime == JK_STATUS_MIME_HTML) { } } else { if (mime == JK_STATUS_MIME_XML) { jk_print_xml_close_elt(s, l, w, 0, "ajp_workers"); } else if (mime == JK_STATUS_MIME_TXT) { } else if (mime == JK_STATUS_MIME_PROP) { } else if (mime == JK_STATUS_MIME_HTML) { } } JK_TRACE_EXIT(l); } static int list_workers(jk_ws_service_t *s, status_endpoint_t *p, jk_logger_t *l) { int lb_cnt = 0; int ajp_cnt = 0; JK_TRACE_ENTER(l); count_workers(s, p, &lb_cnt, &ajp_cnt, l); if (lb_cnt) { list_workers_type(s, p, 1, lb_cnt, l); } if (ajp_cnt) { list_workers_type(s, p, 0, ajp_cnt, l); } JK_TRACE_EXIT(l); return JK_TRUE; } static int show_worker(jk_ws_service_t *s, status_endpoint_t *p, jk_logger_t *l) { const char *worker; const char *sub_worker; jk_worker_t *jw = NULL; lb_sub_worker_t *wr = NULL; JK_TRACE_ENTER(l); if (fetch_worker_and_sub_worker(p, "showing", &worker, &sub_worker, l) == JK_FALSE || search_worker(s, p, &jw, worker, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } if (sub_worker && sub_worker[0]) { if (search_sub_worker(s, p, jw, worker, &wr, sub_worker, NULL, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } } display_worker(s, p, jw, wr, l); JK_TRACE_EXIT(l); return JK_TRUE; } static int edit_worker(jk_ws_service_t *s, status_endpoint_t *p, jk_logger_t *l) { const char *worker; const char *sub_worker; status_worker_t *w = p->worker; jk_worker_t *jw = NULL; lb_worker_t *lb = NULL; lb_sub_worker_t *wr = NULL; ajp_worker_t *aw = NULL; JK_TRACE_ENTER(l); if (fetch_worker_and_sub_worker(p, "editing", &worker, &sub_worker, l) == JK_FALSE || search_worker(s, p, &jw, worker, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } if (jw->type == JK_LB_WORKER_TYPE) { if (check_valid_lb(s, p, jw, worker, &lb, 0, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } if (lb->sequence != lb->s->h.sequence) jk_lb_pull(lb, JK_FALSE, l); if (!sub_worker || !sub_worker[0]) { const char *arg; if (status_get_string(p, JK_STATUS_ARG_ATTRIBUTE, NULL, &arg, l) == JK_TRUE) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' %s lb worker '%s' with all sub workers", w->name, "editing", lb->name); form_all_members(s, p, jw, arg, l); } else { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' %s lb worker '%s'", w->name, "editing", lb->name); form_worker(s, p, jw, l); } JK_TRACE_EXIT(l); return JK_TRUE; } else { if (search_sub_worker(s, p, jw, worker, &wr, sub_worker, NULL, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' %s lb worker '%s' sub worker '%s'", w->name, "editing", lb->name, wr->name); aw = (ajp_worker_t *)wr->worker->worker_private; form_member(s, p, wr, aw, worker, l); JK_TRACE_EXIT(l); return JK_TRUE; } } else if (jw->type == JK_AJP13_WORKER_TYPE || jw->type == JK_AJP14_WORKER_TYPE) { ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private; if (aw) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' %s ajp worker '%s'", w->name, "editing", aw->name); if (aw->sequence != aw->s->h.sequence) jk_ajp_pull(aw, JK_FALSE, l); form_member(s, p, NULL, aw, worker, l); JK_TRACE_EXIT(l); return JK_TRUE; } else { jk_log(l, JK_LOG_WARNING, "Status worker '%s' aw worker is (null)", w->name); } } else { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' worker type not implemented", w->name); } JK_TRACE_EXIT(l); return JK_FALSE; } static int update_worker(jk_ws_service_t *s, status_endpoint_t *p, jk_logger_t *l) { const char *worker; const char *sub_worker; status_worker_t *w = p->worker; jk_worker_t *jw = NULL; lb_worker_t *lb = NULL; lb_sub_worker_t *wr = NULL; ajp_worker_t *aw = NULL; int rc = JK_TRUE; int rv; JK_TRACE_ENTER(l); if (fetch_worker_and_sub_worker(p, "updating", &worker, &sub_worker, l) == JK_FALSE || search_worker(s, p, &jw, worker, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } if (jw->type == JK_LB_WORKER_TYPE) { if (check_valid_lb(s, p, jw, worker, &lb, 0, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } if (lb->sequence != lb->s->h.sequence) jk_lb_pull(lb, JK_TRUE, l); if (!sub_worker || !sub_worker[0]) { const char *arg; if (status_get_string(p, JK_STATUS_ARG_ATTRIBUTE, NULL, &arg, l) == JK_TRUE) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' %s lb worker '%s' with all sub workers", w->name, "updating", lb->name); commit_all_members(s, p, jw, arg, l); } else { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' %s lb worker '%s'", w->name, "updating", lb->name); commit_worker(s, p, jw, l); } JK_TRACE_EXIT(l); return JK_TRUE; } else { unsigned int idx = 0; unsigned int *wi = NULL; int is_wildchar = JK_FALSE; if (strchr(sub_worker, '*') || strchr(sub_worker, '?')) { /* We have a wildchar matching rule */ wi = &idx; is_wildchar = JK_TRUE; } for (;;) { if (search_sub_worker(s, p, jw, worker, &wr, sub_worker, wi, l) == JK_FALSE) { if (!idx) { JK_TRACE_EXIT(l); return JK_FALSE; } else { /* We have found at least one match previously */ p->msg = "OK"; break; } } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' %s lb worker '%s' sub worker '%s'", w->name, "updating", lb->name, wr->name); aw = (ajp_worker_t *)wr->worker->worker_private; rv = 0; rc = commit_member(s, p, lb, wr, aw, &rv, l); if (rv & JK_STATUS_NEEDS_ADDR_PUSH) { aw->addr_sequence = -1; } if (rv & (JK_STATUS_NEEDS_PUSH | JK_STATUS_NEEDS_ADDR_PUSH)) { wr->sequence = -1; lb->sequence = -1; jk_lb_push(lb, JK_TRUE, l); } if (rv & JK_STATUS_NEEDS_RESET_LB_VALUES) reset_lb_values(lb, l); if (rv & JK_STATUS_NEEDS_UPDATE_MULT) /* Recalculate the load multiplicators wrt. lb_factor */ update_mult(lb, l); if (rc == JK_FALSE) { jk_log(l, JK_LOG_ERROR, "Status worker '%s' failed updating sub worker '%s' (at least partially).%s", w->name, aw->name, (is_wildchar == JK_TRUE) ? " Aborting further wildcard updates." : ""); if (!strncmp("OK", p->msg, 3)) { const char *msg = "Update failed (at least partially) for sub worker '%s'"; size_t size = strlen(msg) + strlen(aw->name) + 1; p->msg = jk_pool_alloc(s->pool, size); snprintf(p->msg, size, msg, aw->name); } if (is_wildchar == JK_TRUE) { const char *msg = " Aborting further wildcard updates."; size_t size = strlen(msg) + strlen(p->msg) + 1; p->msg = jk_pool_realloc(s->pool, size, p->msg, strlen(p->msg) + 1); strcat(p->msg, msg); } break; } if (!wi) break; } JK_TRACE_EXIT(l); return rc; } } else if (jw->type == JK_AJP13_WORKER_TYPE || jw->type == JK_AJP14_WORKER_TYPE) { ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private; if (aw) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' %s ajp worker '%s'", w->name, "updating", aw->name); if (aw->sequence != aw->s->h.sequence) jk_ajp_pull(aw, JK_TRUE, l); rv = 0; rc = commit_member(s, p, NULL, NULL, aw, &rv, l); if (rv & JK_STATUS_NEEDS_ADDR_PUSH) { aw->addr_sequence = -1; } if (rv & (JK_STATUS_NEEDS_PUSH | JK_STATUS_NEEDS_ADDR_PUSH)) { aw->sequence = -1; jk_ajp_push(aw, JK_TRUE, l); } if (rc == JK_FALSE) { jk_log(l, JK_LOG_ERROR, "Status worker '%s' failed updating worker '%s' (at least partially).", w->name, aw->name); if (!strncmp("OK", p->msg, 3)) { const char *msg = "Update failed (at least partially) for worker '%s'"; size_t size = strlen(msg) + strlen(aw->name) + 1; p->msg = jk_pool_alloc(s->pool, size); snprintf(p->msg, size, msg, aw->name); } } JK_TRACE_EXIT(l); return rc; } else { jk_log(l, JK_LOG_WARNING, "Status worker '%s' aw worker is (null)", w->name); } } else { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' worker type not implemented", w->name); } JK_TRACE_EXIT(l); return JK_FALSE; } static int reset_worker(jk_ws_service_t *s, status_endpoint_t *p, jk_logger_t *l) { unsigned int i; const char *worker; const char *sub_worker; status_worker_t *w = p->worker; jk_worker_t *jw = NULL; lb_worker_t *lb = NULL; lb_sub_worker_t *wr = NULL; ajp_worker_t *aw = NULL; time_t now = 0; JK_TRACE_ENTER(l); if (fetch_worker_and_sub_worker(p, "resetting", &worker, &sub_worker, l) == JK_FALSE || search_worker(s, p, &jw, worker, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } now = time(NULL); if (jw->type == JK_LB_WORKER_TYPE) { if (check_valid_lb(s, p, jw, worker, &lb, 0, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } if (!sub_worker || !sub_worker[0]) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' %s lb worker '%s' with all sub workers", w->name, "resetting", lb->name); lb->s->max_busy = 0; lb->s->last_reset = now; for (i = 0; i < lb->num_of_workers; i++) { wr = &(lb->lb_workers[i]); aw = (ajp_worker_t *)wr->worker->worker_private; wr->s->state = JK_LB_STATE_IDLE; wr->s->elected_snapshot = 0; wr->s->sessions = 0; wr->s->first_error_time = 0; wr->s->last_error_time = 0; wr->s->errors = 0; wr->s->lb_value = 0; aw->s->used = 0; aw->s->client_errors = 0; aw->s->reply_timeouts = 0; aw->s->transferred = 0; aw->s->readed = 0; aw->s->max_busy = 0; aw->s->max_connected = 0; aw->s->last_reset = now; } JK_TRACE_EXIT(l); return JK_TRUE; } else { if (search_sub_worker(s, p, jw, worker, &wr, sub_worker, NULL, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' %s lb worker '%s' sub worker '%s'", w->name, "resetting", lb->name, wr->name); aw = (ajp_worker_t *)wr->worker->worker_private; wr->s->state = JK_LB_STATE_IDLE; wr->s->elected_snapshot = 0; wr->s->sessions = 0; wr->s->first_error_time = 0; wr->s->last_error_time = 0; wr->s->errors = 0; wr->s->lb_value = 0; aw->s->used = 0; aw->s->client_errors = 0; aw->s->reply_timeouts = 0; aw->s->transferred = 0; aw->s->readed = 0; aw->s->max_busy = 0; aw->s->max_connected = 0; aw->s->last_reset = now; JK_TRACE_EXIT(l); return JK_TRUE; } } else if (jw->type == JK_AJP13_WORKER_TYPE || jw->type == JK_AJP14_WORKER_TYPE) { ajp_worker_t *aw = (ajp_worker_t *)jw->worker_private; if (aw) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' %s ajp worker '%s'", w->name, "resetting", aw->name); aw->s->errors = 0; aw->s->used = 0; aw->s->client_errors = 0; aw->s->reply_timeouts = 0; aw->s->transferred = 0; aw->s->readed = 0; aw->s->max_busy = 0; aw->s->max_connected = 0; aw->s->last_reset = now; JK_TRACE_EXIT(l); return JK_TRUE; } else { jk_log(l, JK_LOG_WARNING, "Status worker '%s' aw worker is (null)", w->name); } } else { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' worker type not implemented", w->name); } JK_TRACE_EXIT(l); return JK_FALSE; } static int recover_worker(jk_ws_service_t *s, status_endpoint_t *p, jk_logger_t *l) { const char *worker; const char *sub_worker; jk_worker_t *jw = NULL; lb_sub_worker_t *wr = NULL; ajp_worker_t *aw = NULL; status_worker_t *w = p->worker; JK_TRACE_ENTER(l); if (fetch_worker_and_sub_worker(p, "recovering", &worker, &sub_worker, l) == JK_FALSE || search_worker(s, p, &jw, worker, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } if (search_sub_worker(s, p, jw, worker, &wr, sub_worker, NULL, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } aw = (ajp_worker_t *)wr->worker->worker_private; if (wr->s->state == JK_LB_STATE_ERROR) { lb_worker_t *lb = NULL; /* We need an lb to correct the lb_value */ if (check_valid_lb(s, p, jw, worker, &lb, 0, l) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } if (lb->lbmethod != JK_LB_METHOD_BUSYNESS) { unsigned int i; jk_uint64_t curmax = 0; for (i = 0; i < lb->num_of_workers; i++) { if (lb->lb_workers[i].s->lb_value > curmax) { curmax = lb->lb_workers[i].s->lb_value; } } wr->s->lb_value = curmax; } aw->s->reply_timeouts = 0; wr->s->state = JK_LB_STATE_RECOVER; jk_log(l, JK_LOG_INFO, "Status worker '%s' marked worker '%s' sub worker '%s' for recovery", w->name, worker ? worker : "(null)", sub_worker ? sub_worker : "(null)"); JK_TRACE_EXIT(l); return JK_TRUE; } jk_log(l, JK_LOG_WARNING, "Status worker '%s' could not mark worker '%s' sub worker '%s' for recovery - state %s is not an error state", w->name, worker ? worker : "(null)", sub_worker ? sub_worker : "(null)", jk_lb_get_state(wr, l)); JK_TRACE_EXIT(l); return JK_FALSE; } static int dump_config(jk_ws_service_t *s, status_endpoint_t *p, int mime, jk_logger_t *l) { status_worker_t *w = p->worker; jk_worker_env_t *we = w->we; jk_map_t *init_data = we->init_data; JK_TRACE_ENTER(l); if (init_data) { int n = jk_map_size(init_data); int i; if (mime == JK_STATUS_MIME_HTML) { jk_puts(s, "

Configuration Data


\n"); jk_puts(s, "This dump does not include any changes applied by the status worker\n"); jk_puts(s, "to the configuration after the initial startup\n"); jk_puts(s, "
\n");
        }
        else if (mime == JK_STATUS_MIME_XML) {
            jk_print_xml_start_elt(s, l, w, 2, 0, "configuration");
        }
        else if (mime == JK_STATUS_MIME_TXT) {
            jk_puts(s, "Configuration:\n");
        }
        for (i=0;i sizeof(".secret") &&
                    strcmp(name + nl - 7, ".secret") == 0) {
                    continue;
                }
                value = jk_map_value_at(init_data, i);
                if (!value)
                    value = "(null)";
                if (mime == JK_STATUS_MIME_HTML ||
                    mime == JK_STATUS_MIME_PROP ||
                    mime == JK_STATUS_MIME_TXT) {
                    jk_putv(s, name, "=", value, "\n", NULL);
                }
                else if (mime == JK_STATUS_MIME_XML) {
                     jk_print_xml_att_string(s, l, 4, name, value);
                }
            }
        }
        if (mime == JK_STATUS_MIME_HTML) {
            jk_puts(s, "
\n"); } else if (mime == JK_STATUS_MIME_XML) { jk_print_xml_stop_elt(s, l, 2, 1); } } else { JK_TRACE_EXIT(l); return JK_FALSE; } JK_TRACE_EXIT(l); return JK_TRUE; } /* * Return values of service() method for status worker: * return value is_error reason * JK_FALSE JK_HTTP_SERVER_ERROR Invalid parameters (null values) * JK_TRUE JK_HTTP_OK All other cases */ static int JK_METHOD service(jk_endpoint_t *e, jk_ws_service_t *s, jk_logger_t *l, int *is_error) { int cmd; jk_uint32_t cmd_props; int mime; int refresh; int read_only = 0; const char *arg; char *err = NULL; status_endpoint_t *p; status_worker_t *w; int denied = 0; JK_TRACE_ENTER(l); if (!e || !e->endpoint_private || !s || !is_error) { JK_LOG_NULL_PARAMS(l); if (is_error) *is_error = JK_HTTP_SERVER_ERROR; JK_TRACE_EXIT(l); return JK_FALSE; } p = e->endpoint_private; w = p->worker; /* Set returned error to OK */ *is_error = JK_HTTP_OK; if (w->num_of_users) { if (s->remote_user) { unsigned int i; denied = 1; for (i = 0; i < w->num_of_users; i++) { if (w->user_case_insensitive) { if (!strcasecmp(s->remote_user, w->user_names[i])) { denied = 0; break; } } else { if (!strcmp(s->remote_user, w->user_names[i])) { denied = 0; break; } } } } else { denied = 2; } } /* Step 1: Process GET params and update configuration */ if (status_parse_uri(s, p, l) != JK_TRUE) { err = "Error during parsing of URI"; } status_get_string(p, JK_STATUS_ARG_CMD, NULL, &arg, l); cmd = status_cmd_int(arg); cmd_props = status_cmd_props(cmd); status_get_string(p, JK_STATUS_ARG_MIME, NULL, &arg, l); mime = status_mime_int(arg); refresh = status_get_int(p, JK_STATUS_ARG_REFRESH, 0, l); if (w->read_only) { read_only = 1; } else { read_only = status_get_int(p, JK_STATUS_ARG_OPTIONS, 0, l) & JK_STATUS_ARG_OPTION_READ_ONLY; } if (mime == JK_STATUS_MIME_HTML) { s->start_response(s, 200, "OK", headers_names, headers_vhtml, 3); jk_puts(s, JK_STATUS_HEAD); } else if (mime == JK_STATUS_MIME_XML) { s->start_response(s, 200, "OK", headers_names, headers_vxml, 3); jk_puts(s, JK_STATUS_XMLH); if (w->doctype) { jk_putv(s, w->doctype, "\n", NULL); } jk_print_xml_start_elt(s, l, w, 0, 0, "status"); if (w->xmlns && strlen(w->xmlns)) jk_putv(s, " ", w->xmlns, NULL); jk_print_xml_stop_elt(s, l, 0, 0); } else { s->start_response(s, 200, "OK", headers_names, headers_vtxt, 3); } if (denied == 0) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' service allowed for user '%s' [%s] from %s [%s]", w->name, s->remote_user ? s->remote_user : "(null)", s->auth_type ? s->auth_type : "(null)", s->remote_addr ? s->remote_addr : "(null)", s->remote_host ? s->remote_host : "(null)"); } else if (denied == 1) { err = "Access denied."; jk_log(l, JK_LOG_WARNING, "Status worker '%s' service denied for user '%s' [%s] from %s [%s]", w->name, s->remote_user ? s->remote_user : "(null)", s->auth_type ? s->auth_type : "(null)", s->remote_addr ? s->remote_addr : "(null)", s->remote_host ? s->remote_host : "(null)"); } else if (denied == 2) { err = "Access denied."; jk_log(l, JK_LOG_WARNING, "Status worker '%s' service denied (no user) [%s] from %s [%s]", w->name, s->remote_user ? s->remote_user : "(null)", s->auth_type ? s->auth_type : "(null)", s->remote_addr ? s->remote_addr : "(null)", s->remote_host ? s->remote_host : "(null)"); } else { err = "Access denied."; jk_log(l, JK_LOG_WARNING, "Status worker '%s' service denied (unknown reason) for user '%s' [%s] from %s [%s]", w->name, s->remote_user ? s->remote_user : "(null)", s->auth_type ? s->auth_type : "(null)", s->remote_addr ? s->remote_addr : "(null)", s->remote_host ? s->remote_host : "(null)"); } if (!err) { if (read_only && !(cmd_props & JK_STATUS_CMD_PROP_READONLY)) { err = "This command is not allowed in read only mode."; } } if (!err) { if (cmd == JK_STATUS_CMD_UNKNOWN) { err = "Invalid command."; } else if (mime == JK_STATUS_MIME_UNKNOWN) { err = "Invalid mime type."; } else if (cmd_props & JK_STATUS_CMD_PROP_CHECK_WORKER && (check_worker(s, p, cmd_props & JK_STATUS_CMD_PROP_WILDCARD, l) != JK_TRUE)) { err = p->msg; } } if (!err) { char buf_time[JK_STATUS_TIME_BUF_SZ]; char buf_tz[JK_STATUS_TIME_BUF_SZ]; time_t clock = time(NULL); long unix_seconds = (long)clock; int rc_time = status_strftime(clock, mime, buf_time, buf_tz, l); if (cmd == JK_STATUS_CMD_UPDATE) { /* lock shared memory */ jk_shm_lock(); if (update_worker(s, p, l) == JK_FALSE) { if (strncmp("OK", p->msg, 3)) err = p->msg; else err = "Update failed"; } /* unlock the shared memory */ jk_shm_unlock(); if (mime == JK_STATUS_MIME_HTML) { write_html_refresh_response(s, p, err, l); } } else if (cmd == JK_STATUS_CMD_RESET) { /* lock shared memory */ jk_shm_lock(); if (reset_worker(s, p, l) == JK_FALSE) { err = "Reset failed"; } /* unlock the shared memory */ jk_shm_unlock(); if (mime == JK_STATUS_MIME_HTML) { write_html_refresh_response(s, p, err, l); } } else if (cmd == JK_STATUS_CMD_RECOVER) { /* lock shared memory */ jk_shm_lock(); if (recover_worker(s, p, l) == JK_FALSE) { err = "Marking worker for recovery failed"; } /* unlock the shared memory */ jk_shm_unlock(); if (mime == JK_STATUS_MIME_HTML) { write_html_refresh_response(s, p, err, l); } } else { if (mime == JK_STATUS_MIME_XML) { jk_print_xml_start_elt(s, l, w, 0, 0, "server"); jk_print_xml_att_string(s, l, 2, "name", s->server_name); jk_print_xml_att_int(s, l, 2, "port", s->server_port); jk_print_xml_stop_elt(s, l, 0, 1); if (cmd_props & JK_STATUS_CMD_PROP_HEAD) { if (rc_time > 0 ) { jk_print_xml_start_elt(s, l, w, 0, 0, "time"); jk_print_xml_att_string(s, l, 2, "datetime", buf_time); jk_print_xml_att_string(s, l, 2, "tz", buf_tz); jk_print_xml_att_long(s, l, 2, "unix", unix_seconds); jk_print_xml_stop_elt(s, l, 0, 1); } jk_print_xml_start_elt(s, l, w, 0, 0, "software"); jk_print_xml_att_string(s, l, 2, "web_server", s->server_software); jk_print_xml_att_string(s, l, 2, "jk_version", JK_FULL_EXPOSED_VERSION); jk_print_xml_stop_elt(s, l, 0, 1); } if (cmd == JK_STATUS_CMD_LIST) { /* Step 2: Display configuration */ if (list_workers(s, p, l) != JK_TRUE) { err = "Error in listing the workers."; } } else if (cmd == JK_STATUS_CMD_SHOW) { /* Step 2: Display detailed configuration */ if (show_worker(s, p, l) != JK_TRUE) { err = "Error in showing this worker."; } } } else if (mime == JK_STATUS_MIME_TXT) { jk_puts(s, "Server:"); jk_printf(s, l, " name=%s", s->server_name); jk_printf(s, l, " port=%d", s->server_port); jk_puts(s, "\n"); if (cmd_props & JK_STATUS_CMD_PROP_HEAD) { if (rc_time > 0) { jk_puts(s, "Time:"); jk_printf(s, l, " datetime=%s", buf_time); jk_printf(s, l, " tz=%s", buf_tz); jk_printf(s, l, " unix=%ld", unix_seconds); jk_puts(s, "\n"); } jk_puts(s, "Software:"); jk_printf(s, l, " web_server=\"%s\"", s->server_software); jk_printf(s, l, " jk_version=%s", JK_FULL_EXPOSED_VERSION); jk_puts(s, "\n"); } if (cmd == JK_STATUS_CMD_LIST) { /* Step 2: Display configuration */ if (list_workers(s, p, l) != JK_TRUE) { err = "Error in listing the workers."; } } else if (cmd == JK_STATUS_CMD_SHOW) { /* Step 2: Display detailed configuration */ if (show_worker(s, p, l) != JK_TRUE) { err = "Error in showing this worker."; } } } else if (mime == JK_STATUS_MIME_PROP) { jk_print_prop_att_string(s, l, w, NULL, "server_name", s->server_name); jk_print_prop_att_int(s, l, w, NULL, "server_port", s->server_port); if (cmd_props & JK_STATUS_CMD_PROP_HEAD) { if (rc_time > 0) { jk_print_prop_att_string(s, l, w, NULL, "time_datetime", buf_time); jk_print_prop_att_string(s, l, w, NULL, "time_tz", buf_tz); jk_print_prop_att_long(s, l, w, NULL, "time_unix", unix_seconds); } jk_print_prop_att_string(s, l, w, NULL, "web_server", s->server_software); jk_print_prop_att_string(s, l, w, NULL, "jk_version", JK_FULL_EXPOSED_VERSION); } if (cmd == JK_STATUS_CMD_LIST) { /* Step 2: Display configuration */ if (list_workers(s, p, l) != JK_TRUE) { err = "Error in listing the workers."; } } else if (cmd == JK_STATUS_CMD_SHOW) { /* Step 2: Display detailed configuration */ if (show_worker(s, p, l) != JK_TRUE) { err = "Error in showing this worker."; } } } else if (mime == JK_STATUS_MIME_HTML) { if (cmd_props & JK_STATUS_CMD_PROP_REFRESH && refresh > 0) { jk_printf(s, l, "\n", refresh, s->req_uri, p->query_string); } if (w->css) { jk_putv(s, "\ncss, "\" />\n", NULL); } jk_puts(s, JK_STATUS_HEND); jk_puts(s, "

JK Status Manager for "); jk_puts(s, s->server_name); jk_printf(s, l, ":%d", s->server_port); if (read_only) { jk_puts(s, " (read only)"); } jk_puts(s, "

\n\n"); if (cmd_props & JK_STATUS_CMD_PROP_HEAD) { jk_putv(s, "\n"); jk_putv(s, "
Server Version:", s->server_software, "   ", NULL); if (rc_time > 0) { jk_putv(s, "Server Time:", buf_time, NULL); } jk_puts(s, "
JK Version:", JK_FULL_EXPOSED_VERSION, "", NULL); jk_printf(s, l, "Unix Seconds:%d", unix_seconds); jk_puts(s, "
\n
\n"); } jk_puts(s, "\n"); if (cmd_props & JK_STATUS_CMD_PROP_REFRESH) { jk_puts(s, "\n"); } if (cmd_props & JK_STATUS_CMD_PROP_FMT) { jk_puts(s, "\n"); } jk_puts(s, "
"); if (refresh > 0) { const char *str = p->query_string; char *buf = jk_pool_alloc(s->pool, sizeof(char *) * (strlen(str)+1)); int result = 0; size_t scan = 0; size_t len = strlen(JK_STATUS_ARG_REFRESH); while (str[scan] != '\0') { if (strncmp(&str[scan], JK_STATUS_ARG_REFRESH, len) == 0 && str[scan+len] == '=') { scan += len + 1; while (str[scan] != '\0' && str[scan] != '&') scan++; if (str[scan] == '&') scan++; } else { if (result > 0 && str[scan] != '\0' && str[scan] != '&') { buf[result] = '&'; result++; } while (str[scan] != '\0' && str[scan] != '&') { buf[result] = str[scan]; result++; scan++; } if (str[scan] == '&') scan++; } } buf[result] = '\0'; jk_putv(s, "[req_uri, NULL); if (buf && buf[0]) jk_putv(s, "?", buf, NULL); jk_puts(s, "\">Stop auto refresh]"); } else { status_start_form(s, p, "get", JK_STATUS_CMD_UNKNOWN, JK_STATUS_ARG_REFRESH, l); jk_puts(s, "\n"); jk_putv(s, "(every ", " ", "seconds)", NULL); jk_puts(s, "\n"); } jk_puts(s, "  |  \n"); status_start_form(s, p, "get", JK_STATUS_CMD_UNKNOWN, JK_STATUS_ARG_MIME, l); jk_puts(s, "\n"); jk_putv(s, "\n"); jk_puts(s, "
\n"); jk_puts(s, "\n"); if (cmd_props & JK_STATUS_CMD_PROP_BACK_LINK) { int from; jk_puts(s, "\n"); } if (cmd_props & JK_STATUS_CMD_PROP_SWITCH_RO) { jk_puts(s, "\n"); } if (cmd_props & JK_STATUS_CMD_PROP_DUMP_LINK) { jk_puts(s, "\n"); } if (cmd_props & JK_STATUS_CMD_PROP_LINK_HELP && (cmd == JK_STATUS_CMD_LIST || !read_only)) { jk_puts(s, "\n"); } jk_puts(s, "
\n"); status_get_string(p, JK_STATUS_ARG_FROM, NULL, &arg, l); from = status_cmd_int(arg); jk_puts(s, "["); if (cmd_props & JK_STATUS_CMD_PROP_BACK_LIST || from == JK_STATUS_CMD_LIST) { status_write_uri(s, p, "Back to worker list", JK_STATUS_CMD_LIST, JK_STATUS_MIME_UNKNOWN, "", "", 0, 0, "", l); } else { status_write_uri(s, p, "Back to worker view", JK_STATUS_CMD_SHOW, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, 0, "", l); } jk_puts(s, "]  "); jk_puts(s, "\n"); if (!w->read_only) { jk_puts(s, "["); if (read_only) { status_write_uri(s, p, "Read/Write", 0, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, JK_STATUS_ARG_OPTION_READ_ONLY, NULL, l); } else { status_write_uri(s, p, "Read Only", 0, JK_STATUS_MIME_UNKNOWN, NULL, NULL, JK_STATUS_ARG_OPTION_READ_ONLY, 0, NULL, l); } jk_puts(s, "]  \n"); } jk_puts(s, "\n"); jk_puts(s, "["); status_write_uri(s, p, "Dump", JK_STATUS_CMD_DUMP, JK_STATUS_MIME_UNKNOWN, NULL, NULL, 0, 0, NULL, l); jk_puts(s, "]  \n"); jk_puts(s, "\n"); jk_puts(s, "["); if (cmd == JK_STATUS_CMD_LIST) { jk_puts(s, "S=Show only this worker, "); } jk_puts(s, "E=Edit worker, R=Reset worker state, T=Try worker recovery"); jk_puts(s, "]
\n"); jk_puts(s, "
\n"); if (cmd == JK_STATUS_CMD_LIST) { /* Step 2: Display configuration */ if (list_workers(s, p, l) != JK_TRUE) { err = "Error in listing the workers."; } } else if (cmd == JK_STATUS_CMD_SHOW) { /* Step 2: Display detailed configuration */ if (show_worker(s, p, l) != JK_TRUE) { err = "Error in showing this worker."; } } else if (cmd == JK_STATUS_CMD_EDIT) { /* Step 2: Display edit form */ if (edit_worker(s, p, l) != JK_TRUE) { err = "Error in generating this worker's configuration form."; } } } if (cmd == JK_STATUS_CMD_DUMP) { if (dump_config(s, p, mime, l) == JK_FALSE) { err = "Dumping configuration failed"; } } if (cmd_props & JK_STATUS_CMD_PROP_LEGEND) { display_legend(s, p, l); } } } if (err) { jk_log(l, JK_LOG_WARNING, "Status worker '%s': %s", w->name, err); if (mime == JK_STATUS_MIME_HTML) { jk_putv(s, "

Result: ERROR - ", err, "
", NULL); jk_putv(s, "req_uri, "\">JK Status Manager Start Page

", NULL); } else if (mime == JK_STATUS_MIME_XML) { jk_print_xml_start_elt(s, l, w, 2, 0, "result"); jk_print_xml_att_string(s, l, 4, "type", "ERROR"); jk_print_xml_att_string(s, l, 4, "message", err); jk_print_xml_stop_elt(s, l, 2, 1); } else if (mime == JK_STATUS_MIME_TXT) { jk_puts(s, "Result:"); jk_printf(s, l, " type=%s", "ERROR"); jk_printf(s, l, " message=\"%s\"", err); jk_puts(s, "\n"); } else { jk_print_prop_att_string(s, l, w, "result", "type", "ERROR"); jk_print_prop_att_string(s, l, w, "result", "message", err); } } else { if (mime == JK_STATUS_MIME_HTML) { jk_putv(s, "

req_uri, "\">JK Status Manager Start Page

", NULL); } else if (mime == JK_STATUS_MIME_XML) { jk_print_xml_start_elt(s, l, w, 2, 0, "result"); jk_print_xml_att_string(s, l, 4, "type", "OK"); jk_print_xml_att_string(s, l, 4, "message", "Action finished"); jk_print_xml_stop_elt(s, l, 2, 1); } else if (mime == JK_STATUS_MIME_TXT) { jk_puts(s, "Result:"); jk_printf(s, l, " type=%s", "OK"); jk_printf(s, l, " message=\"%s\"", "Action finished"); jk_puts(s, "\n"); } else { jk_print_prop_att_string(s, l, w, "result", "type", "OK"); jk_print_prop_att_string(s, l, w, "result", "message", "Action finished"); } } if (mime == JK_STATUS_MIME_HTML) { if (w->css) { jk_putv(s, "
", JK_STATUS_COPYRIGHT, "
\n", NULL); } else { jk_putv(s, "

", JK_STATUS_COPYRIGHT, "

\n", NULL); } jk_puts(s, JK_STATUS_BEND); } else if (mime == JK_STATUS_MIME_XML) { jk_print_xml_close_elt(s, l, w, 0, "status"); } JK_TRACE_EXIT(l); return JK_TRUE; } static int JK_METHOD done(jk_endpoint_t **e, jk_logger_t *l) { JK_TRACE_ENTER(l); if (e && *e && (*e)->endpoint_private) { status_endpoint_t *p = (*e)->endpoint_private; jk_map_free(&(p->req_params)); free(p); *e = NULL; JK_TRACE_EXIT(l); return JK_TRUE; } JK_LOG_NULL_PARAMS(l); JK_TRACE_EXIT(l); return JK_FALSE; } static int JK_METHOD validate(jk_worker_t *pThis, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l) { JK_TRACE_ENTER(l); if (pThis && pThis->worker_private) { JK_TRACE_EXIT(l); return JK_TRUE; } JK_LOG_NULL_PARAMS(l); JK_TRACE_EXIT(l); return JK_FALSE; } static int JK_METHOD init(jk_worker_t *pThis, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l) { JK_TRACE_ENTER(l); if (pThis && pThis->worker_private) { status_worker_t *p = pThis->worker_private; char **good_rating; unsigned int num_of_good; char **bad_rating; unsigned int num_of_bad; unsigned int i; p->we = we; p->css = jk_get_worker_style_sheet(props, p->name, NULL); p->prefix = jk_get_worker_prop_prefix(props, p->name, JK_STATUS_PREFIX_DEF); p->ns = jk_get_worker_name_space(props, p->name, JK_STATUS_NS_DEF); p->xmlns = jk_get_worker_xmlns(props, p->name, JK_STATUS_XMLNS_DEF); p->doctype = jk_get_worker_xml_doctype(props, p->name, NULL); p->read_only = jk_get_is_read_only(props, p->name); p->user_case_insensitive = jk_get_worker_user_case_insensitive(props, p->name); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' is %s and has css '%s', prefix '%s', name space '%s', xml name space '%s', document type '%s'", p->name, p->read_only ? "read-only" : "read/write", p->css ? p->css : "(null)", p->prefix ? p->prefix : "(null)", p->ns ? p->ns : "(null)", p->xmlns ? p->xmlns : "(null)", p->doctype ? p->doctype : "(null)"); if (jk_get_worker_user_list(props, p->name, &(p->user_names), &(p->num_of_users)) && p->num_of_users) { for (i = 0; i < p->num_of_users; i++) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' restricting access to user '%s' case %s", p->name, p->user_names[i], p->user_case_insensitive ? "insensitive" : "sensitive"); } } if (jk_get_worker_good_rating(props, p->name, &good_rating, &num_of_good) && num_of_good) { p->good_mask = 0; for (i = 0; i < num_of_good; i++) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' rating as good: '%s'", p->name, good_rating[i]); p->good_mask |= status_get_rating(good_rating[i], l); } } else { p->good_mask = JK_STATUS_MASK_GOOD_DEF; } if (jk_get_worker_bad_rating(props, p->name, &bad_rating, &num_of_bad) && num_of_bad) { p->bad_mask = 0; for (i = 0; i < num_of_bad; i++) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' rating as bad: '%s'", p->name, bad_rating[i]); p->bad_mask |= status_get_rating(bad_rating[i], l); } } else { p->bad_mask = JK_STATUS_MASK_BAD_DEF; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Status worker '%s' has good rating for '%08" JK_UINT32_T_HEX_FMT "' and bad rating for '%08" JK_UINT32_T_HEX_FMT "'", p->name, p->good_mask, p->bad_mask); if (p->good_mask & p->bad_mask) jk_log(l, JK_LOG_WARNING, "Status worker '%s' has non empty intersection '%08" JK_UINT32_T_HEX_FMT "' between good rating for '%08" JK_UINT32_T_HEX_FMT "' and bad rating for '%08" JK_UINT32_T_HEX_FMT "'", p->name, p->good_mask & p->bad_mask, p->good_mask, p->bad_mask); } JK_TRACE_EXIT(l); return JK_TRUE; } static int JK_METHOD get_endpoint(jk_worker_t *pThis, jk_endpoint_t **pend, jk_logger_t *l) { JK_TRACE_ENTER(l); if (pThis && pThis->worker_private && pend) { status_endpoint_t *p = (status_endpoint_t *) malloc(sizeof(status_endpoint_t)); p->worker = pThis->worker_private; p->endpoint.endpoint_private = p; p->endpoint.service = service; p->endpoint.done = done; p->req_params = NULL; p->msg = NULL; *pend = &p->endpoint; JK_TRACE_EXIT(l); return JK_TRUE; } else { JK_LOG_NULL_PARAMS(l); } JK_TRACE_EXIT(l); return JK_FALSE; } static int JK_METHOD destroy(jk_worker_t **pThis, jk_logger_t *l) { JK_TRACE_ENTER(l); if (pThis && *pThis && (*pThis)->worker_private) { status_worker_t *private_data = (*pThis)->worker_private; jk_close_pool(&private_data->p); free(private_data); JK_TRACE_EXIT(l); return JK_TRUE; } JK_LOG_NULL_PARAMS(l); JK_TRACE_EXIT(l); return JK_FALSE; } int JK_METHOD status_worker_factory(jk_worker_t **w, const char *name, jk_logger_t *l) { JK_TRACE_ENTER(l); if (NULL != name && NULL != w) { status_worker_t *private_data = (status_worker_t *) calloc(1, sizeof(status_worker_t)); jk_open_pool(&private_data->p, private_data->buf, sizeof(jk_pool_atom_t) * TINY_POOL_SIZE); private_data->name = name; private_data->worker.worker_private = private_data; private_data->worker.validate = validate; private_data->worker.init = init; private_data->worker.get_endpoint = get_endpoint; private_data->worker.destroy = destroy; *w = &private_data->worker; JK_TRACE_EXIT(l); return JK_STATUS_WORKER_TYPE; } else { JK_LOG_NULL_PARAMS(l); } JK_TRACE_EXIT(l); return 0; } tomcat-connectors-1.2.41-src/native/common/jk_context.h0000644000000000000020000000571110516516102021413 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Context Stuff (Autoconf) * * Author: Henri Gomez * * Version: $Revision: 466585 $ * ***************************************************************************/ #ifndef JK_CONTEXT_H #define JK_CONTEXT_H #include "jk_pool.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define CBASE_INC_SIZE (8) /* Allocate memory by step of 8 URIs : ie 8 URI by context */ #define URI_INC_SIZE (8) /* Allocate memory by step of 8 CONTEXTs : ie 8 contexts by worker */ typedef struct { /* * Context base (ie examples) */ char *cbase; /* * Status (Up/Down) */ int status; /* * Num of URI handled */ int size; /* * Capacity */ int capacity; /* * URL/URIs (autoconf) */ char **uris; } jk_context_item_t; typedef struct { /* * Memory Pool */ jk_pool_t p; jk_pool_atom_t buf[SMALL_POOL_SIZE]; /* * Virtual Server (if use) */ char *virt; /* * Num of context handled (ie: examples, admin...) */ int size; /* * Capacity */ int capacity; /* * Context list, context / URIs */ jk_context_item_t **contexts; } jk_context_t; /* * functions defined here */ int context_set_virtual(jk_context_t *c, char *virt); int context_open(jk_context_t *c, char *virt); int context_close(jk_context_t *c); int context_alloc(jk_context_t **c, char *virt); int context_free(jk_context_t **c); jk_context_item_t *context_find_base(jk_context_t *c, char *cbase); char *context_item_find_uri(jk_context_item_t *ci, char *uri); void context_dump_uris(jk_context_t *c, char *cbase, FILE * f); jk_context_item_t *context_add_base(jk_context_t *c, char *cbase); int context_add_uri(jk_context_t *c, char *cbase, char *uri); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_CONTEXT_H */ tomcat-connectors-1.2.41-src/native/common/jk_worker_list.h0000644000000000000020000000617511660656133022312 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Worker list * * Author: Gal Shachor * * Author: Henri Gomez * * Version: $Revision: 1202546 $ * ***************************************************************************/ /* * This file includes a list of all the possible workers in the jk library * plus their factories. * * If you want to add a worker just place it in the worker_factories array * with its unique name and factory. * * If you want to remove a worker, hjust comment out its line in the * worker_factories array as well as its header file. For example, look * at what we have done to the ajp23 worker. * * Note: This file should be included only in the jk_worker controller. * Currently the jk_worker controller is located in jk_worker.c */ #ifdef _PLACE_WORKER_LIST_HERE #ifndef _JK_WORKER_LIST_H #define _JK_WORKER_LIST_H #include "jk_ajp12_worker.h" #include "jk_ajp13_worker.h" #include "jk_ajp14_worker.h" #include "jk_lb_worker.h" #include "jk_status.h" struct worker_factory_record { const char *name; int type; worker_factory fac; }; typedef struct worker_factory_record worker_factory_record_t; static worker_factory_record_t worker_factories[] = { /* * AJPv12 worker, this is the stable worker. */ {JK_AJP12_WORKER_NAME, JK_AJP12_WORKER_TYPE, ajp12_worker_factory}, /* * AJPv13 worker, fast bi-directional worker. */ {JK_AJP13_WORKER_NAME, JK_AJP13_WORKER_TYPE, ajp13_worker_factory}, /* * AJPv14 worker, next generation fast bi-directional worker. */ {JK_AJP14_WORKER_NAME, JK_AJP14_WORKER_TYPE, ajp14_worker_factory}, /* * Load balancing worker. Performs round robin with sticky * session load balancing. */ {JK_LB_WORKER_NAME, JK_LB_WORKER_TYPE, lb_worker_factory}, /* * Status worker. Performs display display and * worker management. */ {JK_STATUS_WORKER_NAME, JK_STATUS_WORKER_TYPE, status_worker_factory}, /* * Marks the end of the worker factory list. */ {NULL, 0, NULL} }; #endif /* _JK_WORKER_LIST_H */ #endif /* _PLACE_WORKER_LIST_HERE */ tomcat-connectors-1.2.41-src/native/common/jk_map.c0000644000000000000020000006257012446650514020517 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: General purpose map object * * Author: Gal Shachor * * Author: Mladen Turk * * Version: $Revision: 1647863 $ * ***************************************************************************/ #if defined(AS400) && !defined(AS400_UTF8) #include "apr_xlate.h" #endif #include "jk_global.h" #include "jk_pool.h" #include "jk_util.h" #include "jk_map.h" #define CAPACITY_INC_SIZE (50) #define LENGTH_OF_LINE (8192) #define JK_MAP_RECURSION (20) #define JK_MAP_REFERENCE (".reference") #define JK_MAP_REFERENCE_SZ (strlen(JK_MAP_REFERENCE)) /* Taken from APR tables/apr_hash.c */ /* * This is the popular `times 33' hash algorithm which is used by * perl and also appears in Berkeley DB. This is one of the best * known hash functions for strings because it is both computed * very fast and distributes very well. * * The originator may be Dan Bernstein but the code in Berkeley DB * cites Chris Torek as the source. The best citation I have found * is "Chris Torek, Hash function for text in C, Usenet message * <27038@mimsy.umd.edu> in comp.lang.c , October, 1990." in Rich * Salz's USENIX 1992 paper about INN which can be found at * . * * The magic of number 33, i.e. why it works better than many other * constants, prime or not, has never been adequately explained by * anyone. So I try an explanation: if one experimentally tests all * multipliers between 1 and 256 (as I did while writing a low-level * data structure library some time ago) one detects that even * numbers are not useable at all. The remaining 128 odd numbers * (except for the number 1) work more or less all equally well. * They all distribute in an acceptable way and this way fill a hash * table with an average percent of approx. 86%. * * If one compares the chi^2 values of the variants (see * Bob Jenkins ``Hashing Frequently Asked Questions'' at * http://burtleburtle.net/bob/hash/hashfaq.html for a description * of chi^2), the number 33 not even has the best value. But the * number 33 and a few other equally good numbers like 17, 31, 63, * 127 and 129 have nevertheless a great advantage to the remaining * numbers in the large set of possible multipliers: their multiply * operation can be replaced by a faster operation based on just one * shift plus either a single addition or subtraction operation. And * because a hash function has to both distribute good _and_ has to * be very fast to compute, those few numbers should be preferred. * * -- Ralf S. Engelschall */ #define COMPUTE_KEY_HASH(key, hash) \ { \ const unsigned char *p; \ hash = 0; \ for (p = (const unsigned char *)key; *p; p++) { \ hash = hash * 33 + *p; \ } \ } static volatile int global_map_id = 0; static void trim_prp_comment(char *prp); static size_t trim(char *s); static int map_realloc(jk_map_t *m); static char *jk_map_replace_properties(jk_map_t *m, jk_map_t *env, char *value); int jk_map_alloc(jk_map_t **m) { if (m) { *m = (jk_map_t *)calloc(1, sizeof(jk_map_t)); if (*m) return jk_map_open(*m); } return JK_FALSE; } int jk_map_free(jk_map_t **m) { int rc = JK_FALSE; if (m && *m) { jk_map_close(*m); free(*m); *m = NULL; } return rc; } int jk_map_open(jk_map_t *m) { int rc = JK_FALSE; if (m) { jk_open_pool(&m->p, m->buf, sizeof(jk_pool_atom_t) * SMALL_POOL_SIZE); m->id = ++global_map_id; m->capacity = 0; m->size = 0; m->keys = NULL; m->names = NULL; m->values = NULL; rc = JK_TRUE; } return rc; } int jk_map_close(jk_map_t *m) { int rc = JK_FALSE; if (m) { jk_close_pool(&m->p); rc = JK_TRUE; } return rc; } void *jk_map_get(jk_map_t *m, const char *name, const void *def) { const void *rc = (void *)def; if (m && name) { unsigned int i; unsigned int hash; COMPUTE_KEY_HASH(name, hash) for (i = 0; i < m->size; i++) { if (m->keys[i] == hash && strcmp(m->names[i], name) == 0) { rc = m->values[i]; break; } } } return (void *)rc; /* DIRTY */ } int jk_map_get_id(jk_map_t *m, const char *name) { int rc = -1; if (m && name) { unsigned int i; unsigned int hash; COMPUTE_KEY_HASH(name, hash) for (i = 0; i < m->size; i++) { if (m->keys[i] == hash && strcmp(m->names[i], name) == 0) { rc = i; break; } } } return rc; } const char *jk_map_get_string(jk_map_t *m, const char *name, const char *def) { const char *rc = def; if (m && name) { unsigned int i; unsigned int hash; COMPUTE_KEY_HASH(name, hash) for (i = 0; i < m->size; i++) { if (m->keys[i] == hash && strcmp(m->names[i], name) == 0) { rc = m->values[i]; break; } } } return rc; } int jk_map_get_int(jk_map_t *m, const char *name, int def) { char buf[100]; const char *rc; size_t len; int int_res; sprintf(buf, "%d", def); rc = jk_map_get_string(m, name, buf); len = strlen(rc); if (len) { const char *lastchar = &rc[0] + len - 1; int multit = 1; if ('m' == *lastchar || 'M' == *lastchar) { multit = 1024 * 1024; } else if ('k' == *lastchar || 'K' == *lastchar) { multit = 1024; } /* Safe because atoi() will stop at any non-numeric lastchar */ int_res = atoi(rc) * multit; } else int_res = def; return int_res; } double jk_map_get_double(jk_map_t *m, const char *name, double def) { char buf[100]; const char *rc; sprintf(buf, "%f", def); rc = jk_map_get_string(m, name, buf); return atof(rc); } int jk_map_get_bool(jk_map_t *m, const char *name, int def) { char buf[100]; const char *rc; sprintf(buf, "%d", def); rc = jk_map_get_string(m, name, buf); return jk_get_bool_code(rc, def); } char **jk_map_get_string_list(jk_map_t *m, const char *name, unsigned int *list_len, const char *def) { const char *l = jk_map_get_string(m, name, def); char **ar = NULL; #ifdef _MT_CODE_PTHREAD char *lasts; #endif *list_len = 0; if (l) { unsigned capacity = 0; unsigned idex = 0; char *p; char *v = jk_pool_strdup(&m->p, l); if (!v) { return NULL; } /* * GS, in addition to VG's patch, we now need to * strtok also by a "*" */ #ifdef _MT_CODE_PTHREAD for (p = strtok_r(v, " \t,", &lasts); p; p = strtok_r(NULL, " \t,", &lasts)) #else for (p = strtok(v, " \t,"); p; p = strtok(NULL, " \t,")) #endif { if (idex == capacity) { ar = jk_pool_realloc(&m->p, sizeof(char *) * (capacity + 5), ar, sizeof(char *) * capacity); if (!ar) { return NULL; } capacity += 5; } ar[idex] = jk_pool_strdup(&m->p, p); idex++; } *list_len = idex; } return ar; } int *jk_map_get_int_list(jk_map_t *m, const char *name, unsigned int *list_len, const char *def) { const char *l = jk_map_get_string(m, name, def); int *ar = NULL; #ifdef _MT_CODE_PTHREAD char *lasts; #endif if (l) { unsigned int capacity = 0; unsigned int idex = 0; char *p; char *v = jk_pool_strdup(&m->p, l); if (!v) { return NULL; } /* * GS, in addition to VG's patch, we now need to * strtok also by a "*" */ #ifdef _MT_CODE_PTHREAD for (p = strtok_r(v, " \t,", &lasts); p; p = strtok_r(NULL, " \t,", &lasts)) #else for (p = strtok(v, " \t,"); p; p = strtok(NULL, " \t,")) #endif { if (idex == capacity) { ar = jk_pool_realloc(&m->p, sizeof(int) * (capacity + 5), ar, sizeof(int) * capacity); if (!ar) { return NULL; } capacity += 5; } ar[idex] = atoi(p); idex++; } *list_len = idex; } return ar; } int jk_map_add(jk_map_t *m, const char *name, const void *value) { int rc = JK_FALSE; if (m && name) { unsigned int hash; COMPUTE_KEY_HASH(name, hash) map_realloc(m); if (m->size < m->capacity) { m->values[m->size] = value; m->names[m->size] = jk_pool_strdup(&m->p, name); m->keys[m->size] = hash; m->size++; rc = JK_TRUE; } } return rc; } int jk_map_put(jk_map_t *m, const char *name, const void *value, void **old) { int rc = JK_FALSE; if (m && name) { unsigned int i; unsigned int hash; COMPUTE_KEY_HASH(name, hash) for (i = 0; i < m->size; i++) { if (m->keys[i] == hash && strcmp(m->names[i], name) == 0) { break; } } if (i < m->size) { if (old) *old = (void *)m->values[i]; /* DIRTY */ m->values[i] = value; rc = JK_TRUE; } else { rc = jk_map_add(m, name, value); } } return rc; } static int jk_map_validate_property(char *prp, jk_logger_t *l) { /* check the worker properties */ if (!jk_is_valid_property(prp)) { jk_log(l, JK_LOG_ERROR, "The attribute '%s' is not supported - please check" " the documentation for the supported attributes.", prp); return JK_FALSE; } if (jk_is_deprecated_property(prp)) { jk_log(l, JK_LOG_WARNING, "The attribute '%s' is deprecated - please check" " the documentation for the correct replacement.", prp); } return JK_TRUE; } static int jk_map_handle_duplicates(jk_map_t *m, const char *prp, char **v, int treatment, jk_logger_t *l) { const char *oldv = jk_map_get_string(m, prp, NULL); if (oldv) { if ((treatment == JK_MAP_HANDLE_DUPLICATES) && jk_is_unique_property(prp) == JK_FALSE) { char *tmpv = jk_pool_alloc(&m->p, strlen(*v) + strlen(oldv) + 3); if (tmpv) { char sep = '*'; if (jk_is_path_property(prp)) sep = PATH_SEPERATOR; else if (jk_is_cmd_line_property(prp)) sep = ' '; else if (jk_is_list_property(prp)) sep = ','; sprintf(tmpv, "%s%c%s", oldv, sep, *v); } *v = tmpv; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Concatenated value is: %s -> %s", prp, *v); return JK_FALSE; } else { jk_log(l, JK_LOG_WARNING, "Duplicate key '%s' detected - previous value '%s'" " will be overwritten with '%s'.", prp, oldv ? oldv : "(null)", v ? *v : "(null)"); return JK_TRUE; } } else { return JK_TRUE; } } int jk_map_read_property(jk_map_t *m, jk_map_t *env, const char *str, int treatment, jk_logger_t *l) { int rc = JK_TRUE; char buf[LENGTH_OF_LINE + 1]; char *prp = &buf[0]; if (strlen(str) > LENGTH_OF_LINE) { jk_log(l, JK_LOG_ERROR, "Line too long (%d > %d), ignoring entry", strlen(str), LENGTH_OF_LINE); return JK_FALSE; } strcpy(prp, str); if (trim(prp)) { char *v = strchr(prp, '='); if (v) { *v = '\0'; v++; if (trim(v) && trim(prp)) { if (treatment == JK_MAP_HANDLE_RAW) { v = jk_pool_strdup(&m->p, v); } else { if (jk_map_validate_property(prp, l) == JK_FALSE) return JK_FALSE; v = jk_map_replace_properties(m, env, v); if (jk_map_handle_duplicates(m, prp, &v, treatment, l) == JK_TRUE) v = jk_pool_strdup(&m->p, v); } if (v) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Adding property '%s' with value '%s' to map.", prp, v); jk_map_put(m, prp, v, NULL); } else { JK_LOG_NULL_PARAMS(l); rc = JK_FALSE; } } } } return rc; } int jk_map_read_properties(jk_map_t *m, jk_map_t *env, const char *f, time_t *modified, int treatment, jk_logger_t *l) { int rc = JK_FALSE; if (m && f) { struct stat statbuf; FILE *fp; if (jk_stat(f, &statbuf) == -1) return JK_FALSE; #if defined(AS400) && !defined(AS400_UTF8) fp = fopen(f, "r, o_ccsid=0"); #else fp = fopen(f, "r"); #endif if (fp) { char buf[LENGTH_OF_LINE + 1]; char *prp; rc = JK_TRUE; while (NULL != (prp = fgets(buf, LENGTH_OF_LINE, fp))) { trim_prp_comment(prp); if (*prp) { if ((rc = jk_map_read_property(m, env, prp, treatment, l)) == JK_FALSE) break; } } fclose(fp); if (modified) *modified = statbuf.st_mtime; } } return rc; } int jk_map_size(jk_map_t *m) { if (m) { return m->size; } return -1; } const char *jk_map_name_at(jk_map_t *m, int idex) { if (m && idex >= 0) { return m->names[idex]; /* DIRTY */ } return NULL; } void *jk_map_value_at(jk_map_t *m, int idex) { if (m && idex >= 0) { return (void *)m->values[idex]; /* DIRTY */ } return NULL; } void jk_map_dump(jk_map_t *m, jk_logger_t *l) { if (m) { int s = jk_map_size(m); int i; for (i=0;i '%s'", m->id, jk_map_name_at(m, i) ? jk_map_name_at(m, i) : "(null)", jk_map_value_at(m, i) ? jk_map_value_at(m, i) : "(null)"); } } } } int jk_map_copy(jk_map_t *src, jk_map_t *dst) { int sz = jk_map_size(src); int i; for (i = 0; i < sz; i++) { const char *name = jk_map_name_at(src, i); if (jk_map_get(dst, name, NULL) == NULL) { if (!jk_map_put(dst, name, jk_pool_strdup(&dst->p, jk_map_get_string(src, name, NULL)), NULL)) { return JK_FALSE; } } } return JK_TRUE; } static void trim_prp_comment(char *prp) { #if defined(AS400) && !defined(AS400_UTF8) char *comment; /* lots of lines that translate a '#' realtime deleted */ comment = strchr(prp, *APR_NUMBERSIGN); #else char *comment = strchr(prp, '#'); #endif if (comment) { *comment = '\0'; } } static size_t trim(char *s) { size_t first; size_t len; /* check for empty strings */ if (!(len = strlen(s))) return 0; for (len = len - 1; (len > 0) && jk_isspace(s[len]); len--); if ((len > 0) || !jk_isspace(s[len])) { len++; } s[len] = '\0'; len++; for (first = 0; (s[first] != '\0') && jk_isspace(s[first]); first++); if (first > 0) { memmove(s, s + first, len - first); } return len; } static int map_realloc(jk_map_t *m) { if (m->size == m->capacity) { const char **names; const void **values; unsigned int *keys; int capacity = m->capacity + CAPACITY_INC_SIZE; size_t old_sz = m->capacity * sizeof(void *); size_t new_sz = capacity * sizeof(void *); names = (const char **)jk_pool_realloc(&m->p, new_sz, m->names, old_sz); values = (const void **)jk_pool_realloc(&m->p, new_sz, m->values, old_sz); keys = (unsigned int *)jk_pool_realloc(&m->p, new_sz, m->keys, old_sz); if (values && names && keys) { m->names = names; m->values = values; m->keys = keys; m->capacity = capacity; return JK_TRUE; } } return JK_FALSE; } /** * Replace $(property) in value. * */ static char *jk_map_replace_properties(jk_map_t *m, jk_map_t *env, char *value) { char *rc = value; char *env_start = rc; int rec = 0; while ((env_start = strstr(env_start, "$(")) != NULL) { char *env_end = strstr(env_start, ")"); if (rec++ > 20) return rc; if (env_end) { char env_name[LENGTH_OF_LINE + 1] = ""; const char *env_value; #if defined(WIN32) char env_buf[LENGTH_OF_LINE + 1]; #endif *env_end = '\0'; strcpy(env_name, env_start + 2); *env_end = ')'; env_value = jk_map_get_string(m, env_name, NULL); if (!env_value) { env_value = getenv(env_name); } if (!env_value && env) { /* Search inside local environment table */ env_value = jk_map_get_string(env, env_name, NULL); } #if defined(WIN32) if (!env_value) { /* Try the env block from calling process */ if (GetEnvironmentVariable(env_name, env_buf, sizeof(env_buf))) env_value = &env_buf[0]; } #endif if (env_value) { size_t offset = 0; char *new_value = jk_pool_alloc(&m->p, (sizeof(char) * (strlen(rc) + strlen(env_value)))); if (!new_value) { break; } *env_start = '\0'; strcpy(new_value, rc); strcat(new_value, env_value); strcat(new_value, env_end + 1); offset = env_start - rc + strlen(env_value); rc = new_value; /* Avoid recursive subst */ env_start = rc + offset; } else { env_start = env_end; } } else { break; } } return rc; } /** * Resolve references * */ int jk_map_resolve_references(jk_map_t *m, const char *prefix, int wildcard, int depth, jk_logger_t *l) { int rc = JK_FALSE; JK_TRACE_ENTER(l); if (m && prefix) { if (depth <= JK_MAP_RECURSION) { size_t prelen = strlen(prefix); unsigned int i; rc = JK_TRUE; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Checking for references with prefix %s with%s wildcard (recursion %d)", prefix, wildcard? "" : "out", depth); for (i = 0; i < m->size; i++) { char *v = (char *)m->values[i]; if (v && *v && !strncmp(m->names[i], prefix, prelen)) { size_t remain = strlen(m->names[i]) - prelen; if ((remain == JK_MAP_REFERENCE_SZ ) || (wildcard && remain > JK_MAP_REFERENCE_SZ)) { remain = strlen(m->names[i]) - JK_MAP_REFERENCE_SZ; if (!strncmp(m->names[i] + remain, JK_MAP_REFERENCE, JK_MAP_REFERENCE_SZ)) { char *from = jk_pool_alloc(&m->p, (sizeof(char) * (strlen(v) + 2))); char *to = jk_pool_alloc(&m->p, (sizeof(char) * (remain + 2))); if (!from || !to) { jk_log(l, JK_LOG_ERROR, "Error in string allocation"); rc = JK_FALSE; break; } strcpy(from, v); *(from+strlen(v)) = '.'; *(from+strlen(v)+1) = '\0'; strncpy(to, m->names[i], remain); *(to+remain) = '.'; *(to+remain+1) = '\0'; rc = jk_map_resolve_references(m, v, 0, depth+1, l); if (rc == JK_FALSE) { break; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Copying values from %s to %s", from, to); rc = jk_map_inherit_properties(m, from, to, l); if (rc == JK_FALSE) { break; } } } } } } else { jk_log(l, JK_LOG_ERROR, "Recursion limit %d for worker references with prefix '%s' reached", JK_MAP_RECURSION, prefix); } } else { JK_LOG_NULL_PARAMS(l); } JK_TRACE_EXIT(l); return rc; } /** * Inherit properties * */ int jk_map_inherit_properties(jk_map_t *m, const char *from, const char *to, jk_logger_t *l) { int rc = JK_FALSE; const char *prp; char *to_prp; if (m && from && to) { unsigned int i; for (i = 0; i < m->size; i++) { if (!strncmp(m->names[i], from, strlen(from))) { rc = JK_TRUE; prp = m->names[i] + strlen(from); to_prp = jk_pool_alloc(&m->p, (sizeof(char) * (strlen(to) + strlen(prp) + 1))); if (!to_prp) { jk_log(l, JK_LOG_ERROR, "Error in string allocation for attribute '%s.%s'", to, prp); rc = JK_FALSE; break; } strcpy(to_prp, to); strcat(to_prp, prp); if (jk_map_get_id(m, to_prp) < 0 ) { rc = jk_map_add(m, to_prp, m->values[i]); if (rc == JK_FALSE) { jk_log(l, JK_LOG_ERROR, "Error when adding attribute '%s'", to_prp); break; } } } } if ( rc == JK_FALSE) { jk_log(l, JK_LOG_ERROR, "Reference '%s' not found", from); } } else { JK_LOG_NULL_PARAMS(l); } return rc; } tomcat-connectors-1.2.41-src/native/common/ap_snprintf.h0000644000000000000020000001356010737034234021575 0ustar rootbin/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * The ap_vsnprintf/ap_snprintf functions are based on, and used with the * permission of, the SIO stdio-replacement strx_* functions by Panos * Tsirigotis for xinetd. */ #ifndef APACHE_AP_SNPRINTF_H #define APACHE_AP_SNPRINTF_H #include #include #include #ifdef __cplusplus extern "C" { #endif /* stuff marked API_EXPORT is part of the API, and intended for use * by modules */ #ifndef API_EXPORT #define API_EXPORT(type) type #endif /* Stuff marked API_EXPORT_NONSTD is part of the API, and intended for * use by modules. The difference between API_EXPORT and * API_EXPORT_NONSTD is that the latter is required for any functions * which use varargs or are used via indirect function call. This * is to accomodate the two calling conventions in windows dlls. */ #ifndef API_EXPORT_NONSTD #define API_EXPORT_NONSTD(type) type #endif #if !defined(__GNUC__) || __GNUC__ < 2 || \ (__GNUC__ == 2 && __GNUC_MINOR__ < 7) ||\ defined(NEXT) #define __attribute__(__x) #endif /* These macros allow correct support of 8-bit characters on systems which * support 8-bit characters. Pretty dumb how the cast is required, but * that's legacy libc for ya. These new macros do not support EOF like * the standard macros do. Tough. */ #define ap_isalpha(c) (isalpha(((unsigned char)(c)))) #define ap_isdigit(c) (isdigit(((unsigned char)(c)))) #define ap_islower(c) (islower(((unsigned char)(c)))) /* ap_vformatter() is a generic printf-style formatting routine * with some extensions. The extensions are: * * %pA takes a struct in_addr *, and prints it as a.b.c.d * %pI takes a struct sockaddr_in * and prints it as a.b.c.d:port * %pp takes a void * and outputs it in hex * * The %p hacks are to force gcc's printf warning code to skip * over a pointer argument without complaining. This does * mean that the ANSI-style %p (output a void * in hex format) won't * work as expected at all, but that seems to be a fair trade-off * for the increased robustness of having printf-warnings work. * * Additionally, ap_vformatter allows for arbitrary output methods * using the ap_vformatter_buff and flush_func. * * The ap_vformatter_buff has two elements curpos and endpos. * curpos is where ap_vformatter will write the next byte of output. * It proceeds writing output to curpos, and updating curpos, until * either the end of output is reached, or curpos == endpos (i.e. the * buffer is full). * * If the end of output is reached, ap_vformatter returns the * number of bytes written. * * When the buffer is full, the flush_func is called. The flush_func * can return -1 to indicate that no further output should be attempted, * and ap_vformatter will return immediately with -1. Otherwise * the flush_func should flush the buffer in whatever manner is * appropriate, re-initialize curpos and endpos, and return 0. * * Note that flush_func is only invoked as a result of attempting to * write another byte at curpos when curpos >= endpos. So for * example, it's possible when the output exactly matches the buffer * space available that curpos == endpos will be true when * ap_vformatter returns. * * ap_vformatter does not call out to any other code, it is entirely * self-contained. This allows the callers to do things which are * otherwise "unsafe". For example, ap_psprintf uses the "scratch" * space at the unallocated end of a block, and doesn't actually * complete the allocation until ap_vformatter returns. ap_psprintf * would be completely broken if ap_vformatter were to call anything * that used a pool. Similarly http_bprintf() uses the "scratch" * space at the end of its output buffer, and doesn't actually note * that the space is in use until it either has to flush the buffer * or until ap_vformatter returns. */ typedef struct { char *curpos; char *endpos; } ap_vformatter_buff; API_EXPORT(int) ap_vformatter(int (*flush_func)(ap_vformatter_buff *), ap_vformatter_buff *, const char *fmt, va_list ap); /* These are snprintf implementations based on ap_vformatter(). * * Note that various standards and implementations disagree on the return * value of snprintf, and side-effects due to %n in the formatting string. * ap_snprintf behaves as follows: * * Process the format string until the entire string is exhausted, or * the buffer fills. If the buffer fills then stop processing immediately * (so no further %n arguments are processed), and return the buffer * length. In all cases the buffer is NUL terminated. The return value * is the number of characters placed in the buffer, excluding the * terminating NUL. All this implies that, at most, (len-1) characters * will be copied over; if the return value is >= len, then truncation * occured. * * In no event does ap_snprintf return a negative number. */ API_EXPORT_NONSTD(int) ap_snprintf(char *buf, size_t len, const char *format,...) __attribute__((format(printf,3,4))); API_EXPORT(int) ap_vsnprintf(char *buf, size_t len, const char *format, va_list ap); #ifdef __cplusplus } #endif #endif /* !APACHE_AP_SNPRINTF_H */ tomcat-connectors-1.2.41-src/native/common/jk_sockbuf.h0000644000000000000020000000322610516516102021362 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Socket buffer header file * * Author: Gal Shachor * * Version: $Revision: 466585 $ * ***************************************************************************/ #include "jk_global.h" #define SOCKBUF_SIZE (8*1024) struct jk_sockbuf { char buf[SOCKBUF_SIZE]; unsigned int start; unsigned int end; jk_sock_t sd; }; typedef struct jk_sockbuf jk_sockbuf_t; int jk_sb_open(jk_sockbuf_t *sb, jk_sock_t sd); int jk_sb_write(jk_sockbuf_t *sb, const void *buf, unsigned sz); int jk_sb_read(jk_sockbuf_t *sb, char **buf, unsigned sz, unsigned *ac); int jk_sb_flush(jk_sockbuf_t *sb); int jk_sb_gets(jk_sockbuf_t *sb, char **ps); tomcat-connectors-1.2.41-src/native/common/jk_ajp14.h0000644000000000000020000002036312447333010020646 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Next generation bi-directional protocol handler. * * Author: Henri Gomez * * Version: $Revision: 1648014 $ * ***************************************************************************/ #ifndef JK_AJP14_H #define JK_AJP14_H #include "jk_ajp_common.h" #include "jk_context.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define AJP14_PROTO 14 #define AJP14_WS_HEADER 0x1235 #define AJP14_SW_HEADER 0x1235 /* AJP14 use now the same header in both directions */ #define AJP14_DEF_HOST ("localhost") #define AJP14_DEF_PORT (8011) #define AJP14_DEF_RETRY_ATTEMPTS (1) #define AJP14_DEF_CACHE_SZ (1) #define AJP14_HEADER_LEN (4) #define AJP14_HEADER_SZ_LEN (2) /* * Initial Login Phase (web server -> servlet engine) */ #define AJP14_LOGINIT_CMD (unsigned char)0x10 /* * Second Login Phase (servlet engine -> web server), md5 seed is received */ #define AJP14_LOGSEED_CMD (unsigned char)0x11 /* * Third Login Phase (web server -> servlet engine), md5 of seed + secret is sent */ #define AJP14_LOGCOMP_CMD (unsigned char)0x12 /* * Login Accepted (servlet engine -> web server) */ #define AJP14_LOGOK_CMD (unsigned char)0x13 /* * Login Rejected (servlet engine -> web server), will be logged */ #define AJP14_LOGNOK_CMD (unsigned char)0x14 /* * Context Query (web server -> servlet engine), which URI are handled by servlet engine ? */ #define AJP14_CONTEXT_QRY_CMD (unsigned char)0x15 /* * Context Info (servlet engine -> web server), URI handled response */ #define AJP14_CONTEXT_INFO_CMD (unsigned char)0x16 /* * Context Update (servlet engine -> web server), status of context changed */ #define AJP14_CONTEXT_UPDATE_CMD (unsigned char)0x17 /* * Servlet Engine Status (web server -> servlet engine), what's the status of the servlet engine ? */ #define AJP14_STATUS_CMD (unsigned char)0x18 /* * Secure Shutdown command (web server -> servlet engine), please servlet stop yourself. */ #define AJP14_SHUTDOWN_CMD (unsigned char)0x19 /* * Secure Shutdown command Accepted (servlet engine -> web server) */ #define AJP14_SHUTOK_CMD (unsigned char)0x1A /* * Secure Shutdown Rejected (servlet engine -> web server) */ #define AJP14_SHUTNOK_CMD (unsigned char)0x1B /* * Context Status (web server -> servlet engine), what's the status of the context ? */ #define AJP14_CONTEXT_STATE_CMD (unsigned char)0x1C /* * Context Status Reply (servlet engine -> web server), status of context */ #define AJP14_CONTEXT_STATE_REP_CMD (unsigned char)0x1D /* * Unknown Packet Reply (web server <-> servlet engine), when a packet couldn't be decoded */ #define AJP14_UNKNOW_PACKET_CMD (unsigned char)0x1E /* * Negotiation flags */ /* * web-server want context info after login */ #define AJP14_CONTEXT_INFO_NEG 0x80000000 /* * web-server want context updates */ #define AJP14_CONTEXT_UPDATE_NEG 0x40000000 /* * web-server want compressed stream */ #define AJP14_GZIP_STREAM_NEG 0x20000000 /* * web-server want crypted DES56 stream with secret key */ #define AJP14_DES56_STREAM_NEG 0x10000000 /* * Extended info on server SSL vars */ #define AJP14_SSL_VSERVER_NEG 0x08000000 /* *Extended info on client SSL vars */ #define AJP14_SSL_VCLIENT_NEG 0x04000000 /* * Extended info on crypto SSL vars */ #define AJP14_SSL_VCRYPTO_NEG 0x02000000 /* * Extended info on misc SSL vars */ #define AJP14_SSL_VMISC_NEG 0x01000000 /* * mask of protocol supported */ #define AJP14_PROTO_SUPPORT_AJPXX_NEG 0x00FF0000 /* * communication could use AJP14 */ #define AJP14_PROTO_SUPPORT_AJP14_NEG 0x00010000 /* * communication could use AJP15 */ #define AJP14_PROTO_SUPPORT_AJP15_NEG 0x00020000 /* * communication could use AJP16 */ #define AJP14_PROTO_SUPPORT_AJP16_NEG 0x00040000 /* * Some failure codes */ #define AJP14_BAD_KEY_ERR 0xFFFFFFFF #define AJP14_ENGINE_DOWN_ERR 0xFFFFFFFE #define AJP14_RETRY_LATER_ERR 0xFFFFFFFD #define AJP14_SHUT_AUTHOR_FAILED_ERR 0xFFFFFFFC /* * Some status codes */ #define AJP14_CONTEXT_DOWN 0x01 #define AJP14_CONTEXT_UP 0x02 #define AJP14_CONTEXT_OK 0x03 /* * Misc defines */ #define AJP14_ENTROPY_SEED_LEN 32 /* we're using MD5 => 32 chars */ #define AJP14_COMPUTED_KEY_LEN 32 /* we're using MD5 also */ /* * The login structure */ typedef struct jk_login_service jk_login_service_t; struct jk_login_service { /* * Pointer to web-server name */ const char *web_server_name; /* * Pointer to servlet-engine name */ char *servlet_engine_name; /* * Pointer to secret key */ const char *secret_key; /* * Received entropy seed */ char entropy[AJP14_ENTROPY_SEED_LEN + 1]; /* * Computed key */ char computed_key[AJP14_COMPUTED_KEY_LEN + 1]; /* * What we want to negociate */ unsigned long negotiation; /* * What we received from servlet engine */ unsigned long negociated; }; /* * functions defined here */ void ajp14_compute_md5(jk_login_service_t *s, jk_logger_t *l); int ajp14_marshal_login_init_into_msgb(jk_msg_buf_t *msg, jk_login_service_t *s, jk_logger_t *l); int ajp14_unmarshal_login_seed(jk_msg_buf_t *msg, jk_login_service_t *s, jk_logger_t *l); int ajp14_marshal_login_comp_into_msgb(jk_msg_buf_t *msg, jk_login_service_t *s, jk_logger_t *l); int ajp14_unmarshal_log_ok(jk_msg_buf_t *msg, jk_login_service_t *s, jk_logger_t *l); int ajp14_unmarshal_log_nok(jk_msg_buf_t *msg, jk_logger_t *l); int ajp14_marshal_shutdown_into_msgb(jk_msg_buf_t *msg, jk_login_service_t *s, jk_logger_t *l); int ajp14_unmarshal_shutdown_nok(jk_msg_buf_t *msg, jk_logger_t *l); int ajp14_marshal_unknown_packet_into_msgb(jk_msg_buf_t *msg, jk_msg_buf_t *unk, jk_logger_t *l); int ajp14_marshal_context_query_into_msgb(jk_msg_buf_t *msg, char *virtual, jk_logger_t *l); int ajp14_unmarshal_context_info(jk_msg_buf_t *msg, jk_context_t *context, jk_logger_t *l); int ajp14_marshal_context_state_into_msgb(jk_msg_buf_t *msg, jk_context_t *context, char *cname, jk_logger_t *l); int ajp14_unmarshal_context_state_reply(jk_msg_buf_t *msg, jk_context_t *context, jk_logger_t *l); int ajp14_unmarshal_context_update_cmd(jk_msg_buf_t *msg, jk_context_t *context, jk_logger_t *l); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_AJP14_H */ tomcat-connectors-1.2.41-src/native/common/Makefile.in0000644000000000000020000000251712445347314021152 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. #### XXXX DO we need this Makefile ???? srcdir = @srcdir@ top_srcdir = @top_srcdir@ VPATH = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ APXSLDFLAGS=@APXSLDFLAGS@ APXSCFLAGS=@APXSCFLAGS@ APXSCPPFLAGS=@APXSCPPFLAGS@ SHELL=@SHELL@ top_builddir = .. LIBTOOL = @LIBTOOL@ CC = @CC@ OEXT=.lo include list.mk CFLAGS=-I. @apache_include@ @CFLAGS@ ${APXSCFLAGS} ${APXSCPPFLAGS} include @top_srcdir@/scripts/build/rules.mk JK=./ all: ${APACHE_OBJECTS} install: clean: rm -f *.o *.lo *.a *.la *.so *.so.* *.slo rm -rf .libs maintainer-clean: clean distclean: clean tomcat-connectors-1.2.41-src/native/common/jk_global.h0000644000000000000020000003353212453217212021173 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Global definitions and include files that should exist * * anywhere * * Author: Gal Shachor * * Version: $Revision: 1650043 $ * ***************************************************************************/ #ifndef JK_GLOBAL_H #define JK_GLOBAL_H #if defined(HAVE_CONFIG_H) /* Undefine autoconf defines also existing * in Apache web server includes, and which * will be redefined in our config.h */ #undef PACKAGE #undef PACKAGE_NAME #undef PACKAGE_STRING #undef PACKAGE_TARNAME #undef PACKAGE_VERSION #undef PACKAGE_BUGREPORT #undef PACKAGE_URL #include "config.h" #endif #if defined(WIN32) /* Ignore most warnings (back down to /W3) for poorly constructed headers */ #if defined(_MSC_VER) && _MSC_VER >= 1200 #pragma warning(push, 3) #endif /* disable or reduce the frequency of... * C4057: indirection to slightly different base types * C4075: slight indirection changes (unsigned short* vs short[]) * C4100: unreferenced formal parameter * C4127: conditional expression is constant * C4163: '_rotl64' : not available as an intrinsic function * C4201: nonstandard extension nameless struct/unions * C4244: int to char/short - precision loss * C4514: unreferenced inline function removed */ #pragma warning(disable: 4100 4127 4163 4201 4514; once: 4057 4075 4244) /* Ignore Microsoft's interpretation of secure development * and the POSIX string handling API */ #if defined(_MSC_VER) && _MSC_VER >= 1400 #ifndef _CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_NO_DEPRECATE #endif #pragma warning(disable: 4996) #endif /* defined(_MSC_VER) && _MSC_VER >= 1400 */ #endif /* defined(WIN32) */ #include "jk_version.h" #ifdef HAVE_APR #include "apr_lib.h" #include "apr_strings.h" #include "apr_atomic.h" #endif #include #include #include #include #include #include #include #include #ifdef _OSD_POSIX #include "ap_config.h" #endif #ifdef AS400 #include "ap_config.h" extern char *strdup(const char *str); #endif #include #include #ifdef WIN32 #ifndef _WINDOWS_ #ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #endif #ifndef _WIN32_WINNT /* Restrict the server to a subset of Windows NT 4.0 header files by default */ #define _WIN32_WINNT 0x0500 #endif #ifndef NOUSER #define NOUSER #endif #ifndef NOMCX #define NOMCX #endif #ifndef NOIME #define NOIME #endif #include /* * Add a _very_few_ declarations missing from the restricted set of headers * (If this list becomes extensive, re-enable the required headers above!) * winsock headers were excluded by WIN32_LEAN_AND_MEAN, so include them now */ #include #include #include #endif /* _WINDOWS_ */ #ifdef _WINDOWS_ #ifndef SIO_RCVALL #include #endif #endif #include #include #include #include #else /* WIN32 */ #include #if defined(NETWARE) && defined(__NOVELL_LIBC__) #include #define __sys_socket_h__ #define __netdb_h__ #define __netinet_in_h__ #define HAVE_VSNPRINTF #define HAVE_SNPRINTF #endif #include #include #include #include #ifdef NETWARE #ifndef _SOCKLEN_T #define _SOCKLEN_T typedef int socklen_t; #endif #else #include #include #include #if !defined(_OSD_POSIX) && !defined(AS400) && !defined(__CYGWIN__) && !defined(HPUX11) #include #endif #if !defined(HPUX11) && !defined(AS400) #include #endif #endif /* NETWARE */ #include #include #endif /* WIN32 */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define JK_WORKER_FILE_TAG ("worker_file") #define JK_MOUNT_FILE_TAG ("worker_mount_file") #define JK_LOG_LEVEL_TAG ("log_level") #define JK_LOG_FILE_TAG ("log_file") #define JK_SHM_FILE_TAG ("shm_file") #define JK_WORKER_NAME_TAG ("worker") #define JK_WORKER_FILE_DEF ("workers.properties") /* Urimap reload check time. Use 60 seconds by default. */ #define JK_URIMAP_DEF_RELOAD (60) #define JK_TRUE (1) #define JK_FALSE (0) #define JK_UNSET (-1) #define JK_LF (10) #define JK_CR (13) #define JK_MAX_NAME_LEN (60) #define JK_SESSION_IDENTIFIER "JSESSIONID" #define JK_PATH_SESSION_IDENTIFIER ";jsessionid" #if defined(WIN32) || defined(NETWARE) #ifdef __GNUC__ #define JK_METHOD #define C_LEVEL_TRY_START #define C_LEVEL_TRY_END #define C_LEVEL_FINALLY_START #define C_LEVEL_FINALLY_END #else #define JK_METHOD __stdcall #define C_LEVEL_TRY_START __try { #define C_LEVEL_TRY_END } #define C_LEVEL_FINALLY_START __finally { #define C_LEVEL_FINALLY_END } #endif #define PATH_SEPERATOR (';') #define FILE_SEPERATOR ('\\') #define PATH_ENV_VARIABLE ("PATH") /* incompatible names... */ #ifndef strcasecmp #define strcasecmp stricmp #endif #else /* defined(WIN32) || defined(NETWARE) */ #define JK_METHOD #define C_LEVEL_TRY_START #define C_LEVEL_TRY_END #define C_LEVEL_FINALLY_START #define C_LEVEL_FINALLY_END #define PATH_SEPERATOR (':') #define FILE_SEPERATOR ('/') #define PATH_ENV_VARIABLE ("LD_LIBRARY_PATH") #endif /* defined(WIN32) || defined(NETWARE) */ /* HTTP Error codes */ #define JK_HTTP_OK 200 #define JK_HTTP_BAD_REQUEST 400 #define JK_HTTP_UNAUTHORIZED 401 #define JK_HTTP_REQUEST_TOO_LARGE 413 #define JK_HTTP_SERVER_ERROR 500 #define JK_HTTP_NOT_IMPLEMENTED 501 #define JK_HTTP_BAD_GATEWAY 502 #define JK_HTTP_SERVER_BUSY 503 #define JK_HTTP_GATEWAY_TIME_OUT 504 /* * RECO STATUS */ #define RECO_NONE 0x00 #define RECO_INITED 0x01 #define RECO_FILLED 0x02 /* * JK options */ #define JK_OPT_FWDURIMASK 0x0007 #define JK_OPT_FWDADDRMASK 0x0810 #define JK_OPT_FWDURICOMPAT 0x0001 #define JK_OPT_FWDURICOMPATUNPARSED 0x0002 #define JK_OPT_FWDURIESCAPED 0x0003 #define JK_OPT_FWDURIPROXY 0x0004 #define JK_OPT_FWDURIDEFAULT JK_OPT_FWDURIPROXY #define JK_OPT_FWDDIRS 0x0008 /* Forward local instead remote address */ #define JK_OPT_FWDLOCAL 0x0010 #define JK_OPT_FLUSHPACKETS 0x0020 #define JK_OPT_FLUSHEADER 0x0040 #define JK_OPT_DISABLEREUSE 0x0080 #define JK_OPT_FWDCERTCHAIN 0x0100 #define JK_OPT_FWDKEYSIZE 0x0200 #define JK_OPT_REJECTUNSAFE 0x0400 /* Forward physical tcp peer address instead of * client address as provided e.g. by httpd mod_remoteip. */ #define JK_OPT_FWDPHYSICAL 0x0800 #define JK_OPT_COLLAPSEMASK 0x7000 #define JK_OPT_COLLAPSEALL 0x1000 #define JK_OPT_COLLAPSENONE 0x2000 #define JK_OPT_COLLAPSEUNMOUNT 0x4000 #define JK_OPT_DEFAULT (JK_OPT_FWDURIDEFAULT | JK_OPT_FWDKEYSIZE | JK_OPT_COLLAPSEUNMOUNT) /* Check for EBCDIC systems */ /* Check for Apache 2.0 running on an EBCDIC system */ #if APR_CHARSET_EBCDIC #include #define USE_CHARSET_EBCDIC #define jk_xlate_to_ascii(b, l) ap_xlate_proto_to_ascii(b, l) #define jk_xlate_from_ascii(b, l) ap_xlate_proto_from_ascii(b, l) #else /* APR_CHARSET_EBCDIC */ /* Check for Apache 1.3 running on an EBCDIC system */ #ifdef CHARSET_EBCDIC #define USE_CHARSET_EBCDIC #define jk_xlate_to_ascii(b, l) ebcdic2ascii(b, b, l) #define jk_xlate_from_ascii(b, l) ascii2ebcdic(b, b, l) #else /* CHARSET_EBCDIC */ /* We're in on an ASCII system */ #define jk_xlate_to_ascii(b, l) /* NOOP */ #define jk_xlate_from_ascii(b, l) /* NOOP */ #endif /* CHARSET_EBCDIC */ #endif /* APR_CHARSET_EBCDIC */ /* on i5/OS V5R4 HTTP/APR APIs and Datas are in UTF */ #if defined(AS400_UTF8) #undef USE_CHARSET_EBCDIC #define jk_xlate_to_ascii(b, l) /* NOOP */ #define jk_xlate_from_ascii(b, l) /* NOOP */ #endif /* jk_uint32_t defines a four byte word */ /* jk_uint64_t defines a eight byte word */ #if defined (WIN32) typedef unsigned int jk_uint32_t; #define JK_UINT32_T_FMT "u" #define JK_UINT32_T_HEX_FMT "x" typedef unsigned __int64 jk_uint64_t; #define JK_UINT64_T_FMT "I64u" #define JK_UINT64_T_HEX_FMT "I64x" #define JK_PID_T_FMT "d" #define JK_PTHREAD_T_FMT "d" #elif defined(AS400) || defined(NETWARE) typedef unsigned int jk_uint32_t; #define JK_UINT32_T_FMT "u" #define JK_UINT32_T_HEX_FMT "x" typedef unsigned long long jk_uint64_t; #define JK_UINT64_T_FMT "llu" #define JK_UINT64_T_HEX_FMT "llx" #define JK_PID_T_FMT "d" #define JK_PTHREAD_T_FMT "d" #else #include "jk_types.h" #endif #define JK_UINT32_T_FMT_LEN (sizeof(JK_UINT32_T_FMT) - 1) #define JK_UINT32_T_HEX_FMT_LEN (sizeof(JK_UINT32_T_HEX_FMT) - 1) #define JK_UINT64_T_FMT_LEN (sizeof(JK_UINT64_T_FMT) - 1) #define JK_UINT64_T_HEX_FMT_LEN (sizeof(JK_UINT64_T_HEX_FMT) - 1) #ifdef WIN32 /* For WIN32, emulate gettimeofday() using _ftime() */ #define gettimeofday(tv, tz) { struct _timeb tb; _ftime(&tb); \ (tv)->tv_sec = (long)tb.time; \ (tv)->tv_usec = tb.millitm * 1000; } #define HAVE_VSNPRINTF #define HAVE_SNPRINTF #define HAVE_SOCKADDR_STORAGE #define HAVE_AF_INET6 #define HAVE_GETADDRINFO #ifdef HAVE_APR #define snprintf apr_snprintf #define vsnprintf apr_vsnprintf #else /* define snprint to match windows version */ #define snprintf _snprintf #define vsnprintf _vsnprintf #endif #endif /* WIN32" */ /* Use apr snprintf() and vsnprintf() when needed */ #if defined(HAVE_APR) #if !defined(HAVE_SNPRINTF) #define snprintf apr_snprintf #endif #if !defined(HAVE_VSNPRINTF) #define vsnprintf apr_vsnprintf #endif #endif /* Use ap snprintf() and vsnprintf() when needed */ #if !defined(HAVE_APR) #if !defined(HAVE_SNPRINTF) #define snprintf ap_snprintf #endif #if !defined(HAVE_VSNPRINTF) #define vsnprintf ap_vsnprintf #endif #endif #if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) typedef SOCKET jk_sock_t; #define IS_VALID_SOCKET(s) ((s) != INVALID_SOCKET) #define JK_INVALID_SOCKET INVALID_SOCKET #else typedef int jk_sock_t; #define IS_VALID_SOCKET(s) ((s) > 0) #define JK_INVALID_SOCKET (-1) #endif #ifdef NETWARE #ifdef __NOVELL_LIBC__ #define MAX_PATH 511 #else #define MAX_PATH 255 #endif #endif #if defined(_MSC_VER) && (_MSC_VER > 1200) #define stat _stat #endif #ifdef AS400_UTF8 #define strcasecmp(a,b) apr_strnatcasecmp(a,b) #endif /* Atomics */ #if defined(WIN32) #define JK_ATOMIC_INCREMENT(x) InterlockedIncrement(x) #define JK_ATOMIC_DECREMENT(x) \ do {\ if (InterlockedDecrement(x) < 0) InterlockedIncrement(x);\ } while (0) #elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)) #define JK_ATOMIC_INCREMENT(x) __sync_add_and_fetch(x, 1) #define JK_ATOMIC_DECREMENT(x) \ do {\ if (__sync_sub_and_fetch(x, 1) < 0) __sync_add_and_fetch(x, 1);\ } while (0) #elif defined(HAVE_APR) #define JK_ATOMIC_INCREMENT(x) ((int)apr_atomic_inc32((volatile apr_uint32_t *)x) + 1) #define JK_ATOMIC_DECREMENT(x) \ do {\ /* apr_atomic_add32 returns the *old* value */\ apr_uint32_t y;\ y = apr_atomic_add32((volatile apr_uint32_t *)x, -1);\ if (y == 0 || y > INT_MAX) apr_atomic_inc32((volatile apr_uint32_t *)x);\ } while (0) #else #define JK_ATOMIC_MISSING #define JK_ATOMIC_INCREMENT(x) (++(*x)) #define JK_ATOMIC_DECREMENT(x) \ do {\ if (--(*x) < 0) (++(*x));\ } while (0) #endif /* IPV6 support */ #if defined(HAVE_APR) #define JK_HAVE_IPV6 APR_HAVE_IPV6 #define JK_INET APR_INET #define JK_INET6 APR_INET6 #define JK_UNSPEC APR_UNSPEC #else #if defined(WIN32) || defined(HAVE_AF_INET6) #define JK_HAVE_IPV6 1 #define JK_INET6 AF_INET6 #else #define JK_HAVE_IPV6 0 #define JK_INET6 0 #endif #define JK_INET AF_INET #if defined(AF_UNSPEC) #define JK_UNSPEC AF_UNSPEC #else #define JK_UNSPEC 0 #endif #endif typedef struct jk_sockaddr_t jk_sockaddr_t; struct jk_sockaddr_t { int family; int port; int salen; int ipaddr_len; /** This points to the IP address structure within the appropriate * sockaddr structure. */ void *ipaddr_ptr; /** Union of either IPv4 or IPv6 sockaddr. */ union { /** IPv4 sockaddr structure */ struct sockaddr_in sin; #if JK_HAVE_IPV6 /** IPv6 sockaddr structure */ struct sockaddr_in6 sin6; #endif /** Placeholder to ensure that the size of this union is not * dependent on whether JK_HAVE_IPV6 is defined. */ #ifdef HAVE_SOCKADDR_STORAGE struct sockaddr_storage sas; #else char sas[128]; #endif } sa; }; #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_GLOBAL_H */ tomcat-connectors-1.2.41-src/native/common/jk_nwmain.c0000644000000000000020000000525510516516102021216 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Netware Wrapper * * Author: Mike Anderson * * Version: $Revision: 466585 $ * ***************************************************************************/ #ifdef NETWARE /* * NATIVE_MAIN */ /* * INCLUDES */ #include /* Apache 2/APR uses NOVELL_LIBC which has a different way of handling * "library" nlms. If we aren't on LIBC, use the old method */ #ifndef __NOVELL_LIBC__ #include #include NETDB_DEFINE_CONTEXT /* * main () * * Main entry point -- don't do much more than I've provided * * Entry: * * Exit: * Nothing */ void main() { ExitThread(TSR_THREAD, 0); } #else /* __NOVELL_LIBC__ */ /* Since we are on LibC, we need to handle our own startup and shutdown */ #include #include "novsock2.h" int _NonAppStart (void *NLMHandle, void *errorScreen, const char *cmdLine, const char *loadDirPath, size_t uninitializedDataLength, void *NLMFileHandle, int (*readRoutineP) (int conn, void *fileHandle, size_t offset, size_t nbytes, size_t * bytesRead, void *buffer), size_t customDataOffset, size_t customDataSize, int messageCount, const char **messages) { #pragma unused(cmdLine) #pragma unused(loadDirPath) #pragma unused(uninitializedDataLength) #pragma unused(NLMFileHandle) #pragma unused(readRoutineP) #pragma unused(customDataOffset) #pragma unused(customDataSize) #pragma unused(messageCount) #pragma unused(messages) WSADATA wsaData; return WSAStartup((WORD) MAKEWORD(2, 0), &wsaData); } void _NonAppStop(void) { WSACleanup(); } int _NonAppCheckUnload(void) { return 0; } #endif /* __NOVELL_LIBC__ */ #endif tomcat-connectors-1.2.41-src/native/common/jk_msg_buff.h0000644000000000000020000001026212262062041021512 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Data marshaling. XDR like * * Author: Costin * * Author: Gal Shachor * * Version: $Revision: 1555407 $ * ***************************************************************************/ #ifndef JK_MSG_BUF_H #define JK_MSG_BUF_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* XXX replace all return values with error codes */ #define ERR_BAD_PACKET -5 /* RPC details: - one parameter - use a structure for more. The method is encoded as part of the request - one or no result - */ typedef struct jk_msg_buf_t jk_msg_buf_t; struct jk_msg_buf_t { jk_pool_t *pool; unsigned char *buf; int pos; int len; int maxlen; }; /* -------------------- Setup routines -------------------- */ /** Allocate a buffer. */ jk_msg_buf_t *jk_b_new(jk_pool_t *p); /** Set up a buffer with an existing buffer */ int jk_b_set_buffer(jk_msg_buf_t *msg, unsigned char *data, int buffSize); /* * Set up a buffer with a new buffer of buffSize */ int jk_b_set_buffer_size(jk_msg_buf_t *msg, int buffSize); /* * Finalize the buffer before sending - set length fields, etc */ void jk_b_end(jk_msg_buf_t *msg, int protoh); /* * Recycle the buffer - z for a new invocation */ void jk_b_reset(jk_msg_buf_t *msg); /* -------------------- Real encoding -------------------- */ int jk_b_append_byte(jk_msg_buf_t *msg, unsigned char val); int jk_b_append_bytes(jk_msg_buf_t *msg, const unsigned char *param, int len); int jk_b_append_int(jk_msg_buf_t *msg, unsigned short val); int jk_b_append_long(jk_msg_buf_t *msg, unsigned long val); int jk_b_append_string(jk_msg_buf_t *msg, const char *param); #if defined(AS400) && !defined(AS400_UTF8) int jk_b_append_asciistring(jk_msg_buf_t *msg, const char *param); #endif int jk_b_append_bytes(jk_msg_buf_t *msg, const unsigned char *param, int len); /* -------------------- Decoding -------------------- */ /** Get a byte from the current position */ unsigned char jk_b_get_byte(jk_msg_buf_t *msg); /** Get an int from the current position */ unsigned short jk_b_get_int(jk_msg_buf_t *msg); /** Get a long from the current position */ unsigned long jk_b_get_long(jk_msg_buf_t *msg); /** Get a String from the current position */ char *jk_b_get_string(jk_msg_buf_t *msg); /** Get Bytes from the current position */ int jk_b_get_bytes(jk_msg_buf_t *msg, unsigned char *buf, int len); /** Get a byte from an arbitrary position */ unsigned char jk_b_pget_byte(jk_msg_buf_t *msg, int pos); /** Get an int from an arbitrary position */ unsigned short jk_b_pget_int(jk_msg_buf_t *msg, int pos); /** Get a long from an arbitrary position */ unsigned long jk_b_pget_long(jk_msg_buf_t *msg, int pos); /* --------------------- Help ------------------------ */ void jk_dump_buff(jk_logger_t *l, const char *file, int line, const char *funcname, int level, char *what, jk_msg_buf_t *msg); /** Copy a msg buf into another one */ int jk_b_copy(jk_msg_buf_t *smsg, jk_msg_buf_t *dmsg); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_MSG_BUF_H */ tomcat-connectors-1.2.41-src/native/common/config.h.in0000644000000000000020000000620612555256561021134 0ustar rootbin/* common/config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have IPv6 support */ #undef HAVE_AF_INET6 /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Have flock() */ #undef HAVE_FLOCK /* Have getaddrinfo() */ #undef HAVE_GETADDRINFO /* Have gethostbyname_r() */ #undef HAVE_GETHOSTBYNAME_R /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the header file. */ #undef HAVE_NETDB_H /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Have poll() */ #undef HAVE_POLL /* Define to 1 if you have the header file. */ #undef HAVE_POLL_H /* Have snprintf() */ #undef HAVE_SNPRINTF /* Define to 1 if you have struct sockaddr_storage */ #undef HAVE_SOCKADDR_STORAGE /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_FILIO_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Have vsnprintf() */ #undef HAVE_VSNPRINTF /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* The size of `char', as computed by sizeof. */ #undef SIZEOF_CHAR /* The size of `int', as computed by sizeof. */ #undef SIZEOF_INT /* The size of `long', as computed by sizeof. */ #undef SIZEOF_LONG /* The size of `longlong', as computed by sizeof. */ #undef SIZEOF_LONGLONG /* The size of `long double', as computed by sizeof. */ #undef SIZEOF_LONG_DOUBLE /* The size of `long long', as computed by sizeof. */ #undef SIZEOF_LONG_LONG /* The size of pid_t */ #undef SIZEOF_PID_T /* The size of pthread_t */ #undef SIZEOF_PTHREAD_T /* The size of `short', as computed by sizeof. */ #undef SIZEOF_SHORT /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* Define to use SOCK_CLOEXEC with socket() */ #undef USE_SOCK_CLOEXEC /* Define to use SO_RCVTIMEO with setsockopt() */ #undef USE_SO_RCVTIMEO /* Define to use SO_SNDTIMEO with setsockopt() */ #undef USE_SO_SNDTIMEO /* Version number of package */ #undef VERSION tomcat-connectors-1.2.41-src/native/common/jk_version.h0000644000000000000020000000620112555245760021425 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: JK version header file * * Version: $Revision: 1692773 $ * ***************************************************************************/ #ifndef __JK_VERSION_H #define __JK_VERSION_H /************** START OF AREA TO MODIFY BEFORE RELEASING *************/ #define JK_VERMAJOR 1 #define JK_VERMINOR 2 #define JK_VERFIX 41 /* set JK_VERISRELEASE to 1 when release (do not forget to commit!) */ #define JK_VERISRELEASE 1 /* Beta number */ #define JK_VERBETA 0 #define JK_BETASTRING "0" /* Release candidate */ #define JK_VERRC 0 #define JK_RCSTRING "0" /************** END OF AREA TO MODIFY BEFORE RELEASING *************/ #if !defined(PACKAGE) #if defined(JK_ISAPI) #define PACKAGE "isapi_redirector" #define JK_DLL_SUFFIX "dll" #elif defined(JK_NSAPI) #define PACKAGE "nsapi_redirector" #define JK_DLL_SUFFIX "dll" #else #define PACKAGE "mod_jk" #define JK_DLL_SUFFIX "so" #endif #endif /* Build JK_EXPOSED_VERSION and JK_VERSION */ #define JK_EXPOSED_VERSION_INT PACKAGE "/" JK_VERSTRING #if (JK_VERBETA != 0) #define JK_EXPOSED_VERSION JK_EXPOSED_VERSION_INT "-beta-" JK_BETASTRING #else #undef JK_VERBETA #define JK_VERBETA 255 #if (JK_VERRC != 0) #define JK_EXPOSED_VERSION JK_EXPOSED_VERSION_INT "-rc-" JK_RCSTRING #elif (JK_VERISRELEASE == 1) #define JK_EXPOSED_VERSION JK_EXPOSED_VERSION_INT #else #define JK_EXPOSED_VERSION JK_EXPOSED_VERSION_INT "-dev" #endif #endif #define JK_FULL_EXPOSED_VERSION JK_EXPOSED_VERSION #define JK_MAKEVERSION(major, minor, fix, beta) \ (((major) << 24) + ((minor) << 16) + ((fix) << 8) + (beta)) #define JK_VERSION JK_MAKEVERSION(JK_VERMAJOR, JK_VERMINOR, JK_VERFIX, JK_VERBETA) /** Properly quote a value as a string in the C preprocessor */ #define JK_STRINGIFY(n) JK_STRINGIFY_HELPER(n) /** Helper macro for JK_STRINGIFY */ #define JK_STRINGIFY_HELPER(n) #n #define JK_VERSTRING \ JK_STRINGIFY(JK_VERMAJOR) "." \ JK_STRINGIFY(JK_VERMINOR) "." \ JK_STRINGIFY(JK_VERFIX) /* macro for Win32 .rc files using numeric csv representation */ #define JK_VERSIONCSV JK_VERMAJOR ##, \ ##JK_VERMINOR ##, \ ##JK_VERFIX #endif /* __JK_VERSION_H */ tomcat-connectors-1.2.41-src/native/common/jk_connect.h0000644000000000000020000000527412465671172021402 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Socket connections header file * * Author: Gal Shachor * * Version: $Revision: 1658173 $ * ***************************************************************************/ #ifndef JK_CONNECT_H #define JK_CONNECT_H #include "jk_logger.h" #include "jk_global.h" #if !defined(WIN32) && !(defined(NETWARE) && defined(__NOVELL_LIBC__)) #define closesocket close #endif #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define JK_SOCKET_EOF (-2) void jk_clone_sockaddr(jk_sockaddr_t *out, jk_sockaddr_t *in); int jk_resolve(const char *host, int port, jk_sockaddr_t *rc, void *pool, int prefer_ipv6, jk_logger_t *l); jk_sock_t jk_open_socket(jk_sockaddr_t *addr, jk_sockaddr_t *source, int keepalive, int timeout, int connect_timeout, int sock_buf, jk_logger_t *l); int jk_close_socket(jk_sock_t sd, jk_logger_t *l); int jk_shutdown_socket(jk_sock_t sd, jk_logger_t *l); int jk_tcp_socket_sendfull(jk_sock_t sd, const unsigned char *b, int len, jk_logger_t *l); int jk_tcp_socket_recvfull(jk_sock_t sd, unsigned char *b, int len, jk_logger_t *l); char *jk_dump_hinfo(jk_sockaddr_t *saddr, char *buf, size_t size); char *jk_dump_sinfo(jk_sock_t sd, char *buf, size_t size); int jk_is_input_event(jk_sock_t sd, int timeout, jk_logger_t *l); int jk_is_socket_connected(jk_sock_t sd, jk_logger_t *l); /*** * i5/OS V5R4 need ASCII<->EBCDIC translation for inet_addr() call */ #if !defined(AS400_UTF8) #define jk_inet_addr inet_addr #endif #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_CONNECT_H */ tomcat-connectors-1.2.41-src/native/common/jk_url.h0000644000000000000020000000543212451326232020534 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: URL manipulation subroutines header file. (mod_proxy) * * Version: $Revision: 500534 $ * ***************************************************************************/ #ifndef _JK_URL_H #define _JK_URL_H #include "jk_global.h" #include "jk_pool.h" #include "jk_util.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* * Do a canonical encoding of the url x. * String y contains the result and is pre-allocated * for at least maxlen bytes, including a '\0' terminator. */ int jk_canonenc(const char *x, char *y, int maxlen); /** * Unescapes a URL, leaving reserved characters intact. * @param escaped Optional buffer to write the encoded string, can be * NULL, in which case the URL decoding does not actually take place * but the result length of the decoded URL will be returned. * @param url String to be unescaped * @param slen The length of the original url, or -1 to decode until * a terminating '\0' is seen * @param forbid Optional list of forbidden characters, in addition to * 0x00 * @param reserved Optional list of reserved characters that will be * left unescaped * @param plus If non zero, '+' is converted to ' ' as per * application/x-www-form-urlencoded encoding * @param len If set, the length of the escaped string will be returned * @return JK_TRUE on success, JK_FALSE if no characters are * decoded or the string is NULL, if a bad escape sequence is * found, or if a character on the forbid list is found. * Implementation copied from APR 1.5.x. */ int jk_unescape_url(char *const escaped, const char *const url, size_t slen, const char *const forbid, const char *const reserved, const int plus, size_t *len); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _JK_URL_H */ tomcat-connectors-1.2.41-src/native/common/jk_sockbuf.c0000644000000000000020000001215710516516102021360 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Simple buffer object to handle buffered socket IO * * Author: Gal Shachor * * Version: $Revision: 466585 $ * ***************************************************************************/ #include "jk_global.h" #include "jk_sockbuf.h" static int fill_buffer(jk_sockbuf_t *sb); int jk_sb_open(jk_sockbuf_t *sb, jk_sock_t sd) { if (sb && sd >= 0) { sb->end = 0; sb->start = 0; sb->sd = sd; return JK_TRUE; } return JK_FALSE; } int jk_sb_write(jk_sockbuf_t *sb, const void *buf, unsigned sz) { if (sb && buf && sz) { if ((SOCKBUF_SIZE - sb->end) >= sz) { memcpy(sb->buf + sb->end, buf, sz); sb->end += sz; } else { if (!jk_sb_flush(sb)) { return JK_FALSE; } if (sz > SOCKBUF_SIZE) { return (send(sb->sd, (char *)buf, sz, 0) == (int)sz); } memcpy(sb->buf + sb->end, buf, sz); sb->end += sz; } return JK_TRUE; } return JK_FALSE; } int jk_sb_flush(jk_sockbuf_t *sb) { if (sb) { int save_out = sb->end; sb->end = sb->start = 0; if (save_out) { return send(sb->sd, sb->buf, save_out, 0) == save_out; } return JK_TRUE; } return JK_FALSE; } int jk_sb_read(jk_sockbuf_t *sb, char **buf, unsigned sz, unsigned *ac) { if (sb && buf && ac) { unsigned avail; *ac = 0; *buf = NULL; if (sb->end == sb->start) { sb->end = sb->start = 0; if (fill_buffer(sb) < 0) { return JK_FALSE; } } *buf = sb->buf + sb->start; avail = sb->end - sb->start; if (avail > sz) { *ac = sz; } else { *ac = avail; } sb->start += *ac; return JK_TRUE; } return JK_FALSE; } int jk_sb_gets(jk_sockbuf_t *sb, char **ps) { int ret; if (sb) { while (1) { unsigned i; for (i = sb->start; i < sb->end; i++) { if (JK_LF == sb->buf[i]) { if (i > sb->start && JK_CR == sb->buf[i - 1]) { sb->buf[i - 1] = '\0'; } else { sb->buf[i] = '\0'; } *ps = sb->buf + sb->start; sb->start = (i + 1); return JK_TRUE; } } if ((ret = fill_buffer(sb)) < 0) { return JK_FALSE; } else if (ret == 0) { *ps = sb->buf + sb->start; if ((SOCKBUF_SIZE - sb->end) > 0) { sb->buf[sb->end] = '\0'; } else { sb->buf[sb->end - 1] = '\0'; } return JK_TRUE; } } } return JK_FALSE; } /* * Read data from the socket into the associated buffer, and update the * start and end indices. May move the data currently in the buffer. If * new data is read into the buffer (or if it is already full), returns 1. * If EOF is received on the socket, returns 0. In case of error returns * -1. */ static int fill_buffer(jk_sockbuf_t *sb) { int ret; /* * First move the current data to the beginning of the buffer */ if (sb->start < sb->end) { if (sb->start > 0) { unsigned to_copy = sb->end - sb->start; memmove(sb->buf, sb->buf + sb->start, to_copy); sb->start = 0; sb->end = to_copy; } } else { sb->start = sb->end = 0; } /* * In the unlikely case where the buffer is already full, we won't be * reading anything and we'd be calling recv with a 0 count. */ if ((SOCKBUF_SIZE - sb->end) > 0) { /* * Now, read more data */ ret = recv(sb->sd, sb->buf + sb->end, SOCKBUF_SIZE - sb->end, 0); /* 0 is EOF/SHUTDOWN, -1 is SOCK_ERROR */ if (ret <= 0) { return ret; } sb->end += ret; } return 1; } tomcat-connectors-1.2.41-src/native/common/jk_ajp12_worker.h0000644000000000000020000000326110516516102022233 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: ajpv1.2 worker header file * * Author: Gal Shachor * * Version: $Revision: 466585 $ * ***************************************************************************/ #ifndef JK_AJP12_WORKER_H #define JK_AJP12_WORKER_H #include "jk_logger.h" #include "jk_service.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define JK_AJP12_WORKER_NAME ("ajp12") #define JK_AJP12_WORKER_TYPE (1) int JK_METHOD ajp12_worker_factory(jk_worker_t **w, const char *name, jk_logger_t *l); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_AJP12_WORKER_H */ tomcat-connectors-1.2.41-src/native/common/jk_service.h0000644000000000000020000005024512477544555021416 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Definitions of the objects used during the service step. * * These are the web server (ws) the worker and the connection* * JVM connection point * * Author: Gal Shachor * * Author: Dan Milstein * * Author: Henri Gomez * * Version: $Revision: 1665454 $ * ***************************************************************************/ #ifndef JK_SERVICE_H #define JK_SERVICE_H #include "jk_global.h" #include "jk_logger.h" #include "jk_pool.h" #include "jk_map.h" #include "jk_uri_worker_map.h" #include "jk_msg_buff.h" #define JK_RETRIES 2 #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* * Env Information to be provided to worker at init time * With AJP14 support we need to have access to many informations * about web-server, uri to worker map.... */ struct jk_worker_env { /* The original configuration map */ jk_map_t *init_data; /* The URI to WORKER map, will be feeded by AJP14 autoconf feature */ jk_uri_worker_map_t *uri_to_worker; unsigned int num_of_workers; char **worker_list; /* Web-Server we're running on (Apache/IIS/NES) */ char *server_name; /* Virtual server handled - "*" is all virtual */ char *virtual; /* Optional APR pool used for configuration */ void *pool; }; typedef struct jk_worker_env jk_worker_env_t; struct jk_ws_service; struct jk_endpoint; struct jk_worker; typedef struct jk_ws_service jk_ws_service_t; typedef struct jk_endpoint jk_endpoint_t; typedef struct jk_worker jk_worker_t; struct svc_extension { /* reply_timeout overwrite */ int reply_timeout; /* Whether to ignore session routing info */ int sticky_ignore; /* Whether the request is stateless and should not * influence session load balancing */ int stateless; /* activation state overwrites for load balancers */ /* Dynamically allocated array with one entry per lb member. */ int *activation; /* fail_on_status overwrites */ /* Number of elements in the array fail_on_status. */ int fail_on_status_size; /* Dynamically allocated array with one entry per status. */ int *fail_on_status; /* Use server error pages for responses >= 400. */ int use_server_error_pages; /* session_cookie overwrite */ char *session_cookie; /* session_path overwrite */ char *session_path; /* Whether mod_jk should set the session cookie itself */ int set_session_cookie; /* An optional PATH to add the the set session cookie */ char *session_cookie_path; }; typedef struct svc_extension svc_extension_t; /* * The web server service 'class'. An instance of this class is created * for each request which is forwarded from the web server to the servlet * container. Contains the basic information about the request * (e.g. protocol, req_uri, etc), and also contains a series of methods * which provide access to core web server functionality (start_response, * read, write). This class might be more accurately called ws_request. * * As with all the core jk classes, this is essentially an abstract base * class which is implemented/extended by classes which are specific to a * particular web server. By using an abstract base class in this manner, * workers can be written for different protocols (e.g. ajp12, ajp13, ajp14) * without the workers having to worry about which web server they are * talking to. * * This particular OO-in-C system uses a 'ws_private' pointer to point to * the platform-specific data. So in the subclasses, the methods do most * of their work by getting their hands on the ws_private pointer and then * using that to get at the correctly formatted data and functions for * their platform. * * Try imagining this as a 'public abstract class', and the ws_private * pointer as a sort of extra 'this' reference. Or imagine that you are * seeing the internal vtables of your favorite OO language. Whatever * works for you. * * See apache1.3/mod_jk.c and iis/jk_isapi_plugin.c for examples. */ struct jk_ws_service { /* * A 'this' pointer which is used by the subclasses of this class to * point to data which is specific to a given web server platform * (e.g. Apache or IIS). */ void *ws_private; /* * Provides memory management. All data specific to this request is * allocated within this pool, which can then be reclaimed at the end * of the request handling cycle. * * Alive as long as the request is alive. */ jk_pool_t *pool; /* * CGI Environment needed by servlets */ const char *method; const char *protocol; char *req_uri; const char *remote_addr; const char *remote_port; const char *remote_host; const char *remote_user; const char *auth_type; const char *query_string; const char *server_name; const char *local_addr; unsigned server_port; char *server_software; jk_uint64_t content_length; /* 64 bit integer that represents the content */ /* length should be 0 if unknown. */ unsigned is_chunked; /* 1 if content length is unknown (chunked rq) */ unsigned no_more_chunks; /* 1 if last chunk has been read */ jk_uint64_t content_read; /* number of bytes read */ /* * SSL information * * is_ssl - True if request is in ssl connection * ssl_protocol- Name of the SSL protocol (SSLv3, TLSv1, TLSv1.1, TLSv1.2) * ssl_cert - If available, base64 ASN.1 encoded client certificates. * ssl_cert_len - Length of ssl_cert, 0 if certificates are not available. * ssl_cipher - The ssl cipher suite in use. * ssl_session - The ssl session string * * In some servers it is impossible to extract all this information, in this * case, we are passing NULL. */ int is_ssl; char *ssl_protocol; char *ssl_cert; unsigned ssl_cert_len; char *ssl_cipher; char *ssl_session; /* * SSL extra information for Servlet 2.3 API * * ssl_key_size - ssl key size in use */ int ssl_key_size; /* * Headers, names and values. */ char **headers_names; /* Names of the request headers */ char **headers_values; /* Values of the request headers */ unsigned num_headers; /* Number of request headers */ /* * Request attributes. * * These attributes that were extracted from the web server and are * sent to Tomcat. * * The developer should be able to read them from the ServletRequest * attributes. Tomcat is required to append org.apache.tomcat. to * these attrinbute names. */ char **attributes_names; /* Names of the request attributes */ char **attributes_values; /* Values of the request attributes */ unsigned num_attributes; /* Number of request attributes */ /* * Response headers, names and values. * These are additional headers that we want to add to * the headers send to us from tomcat. * Example: a stickyness cookie header */ char **resp_headers_names; /* Names of the response headers */ char **resp_headers_values; /* Values of the response headers */ unsigned num_resp_headers; /* Number of response headers */ /* * JK_TRUE iff handled by a load balancer, the request * contained a route and it is the route of the current worker. */ int sticky; /* * The route is in use when the adapter load balance among * several workers. It is the ID of a specific target in the load balance * group. We are using this variable to implement target session * affinity */ const char *route; /* * Activation state of the worker in the load balancer. * Will be forwarded as a request attribute. */ const char *activation; /* Temp solution for auth. For native1 it'll be sent on each request, if an option is present. For native2 it'll be sent with the first request. On java side, both cases will work. For tomcat3.2 or a version that doesn't support secret - don't set the secret, and it'll work. */ const char *secret; /* * Area to get POST data for fail-over recovery in POST */ jk_msg_buf_t *reco_buf; int reco_status; /* * If set call flush after each write */ int flush_packets; /* * If set call flush after AJP13_SEND_HEADERS. */ int flush_header; /* * service extensions */ svc_extension_t extension; /* * JK_TRUE if response headers have been sent back */ int response_started; /* * JK_TRUE if response should not be send to the client */ int response_blocked; /* * HTTP status sent from container. */ int http_response_status; /* Uri worker map. Added for virtual host support */ jk_uri_worker_map_t *uw_map; /* * Callbacks into the web server. For each, the first argument is * essentially a 'this' pointer. All return JK_TRUE on success * and JK_FALSE on failure. */ /* * Send the response headers to the browser. */ int (JK_METHOD * start_response) (jk_ws_service_t *s, int status, const char *reason, const char *const *header_names, const char *const *header_values, unsigned num_of_headers); /* * 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. */ int (JK_METHOD * read) (jk_ws_service_t *s, void *buffer, unsigned len, unsigned *actually_read); /* * Write a chunk of response data back to the browser. */ int (JK_METHOD * write) (jk_ws_service_t *s, const void *buffer, unsigned len); /* * Flush a chunk of response data back to the browser. */ void (JK_METHOD * flush) (jk_ws_service_t *s); /* * Done with sending response back to the browser. */ void (JK_METHOD * done) (jk_ws_service_t *s); /* * If set do not reuse socket after each full response */ int disable_reuse; /* * Add more data to log facilities. */ void (JK_METHOD * add_log_items) (jk_ws_service_t *s, const char *const *log_names, const char *const *log_values, unsigned num_of_items); /* * Iterate through all vhosts */ void *(JK_METHOD * next_vhost) (void *d); /* * String representation of a vhost */ void (JK_METHOD * vhost_to_text) (void *d, char *buf, size_t len); /* * Get uw_map associated with a vhost */ jk_uri_worker_map_t *(JK_METHOD * vhost_to_uw_map) (void *d); }; /* * The endpoint 'class', which represents one end of a connection to the * servlet engine. Basically, supports nothing other than forwarding the * request to the servlet engine. Endpoints can be persistent (as with * ajp13/ajp14, where a single connection is reused many times), or can last for a * single request (as with ajp12, where a new connection is created for * every request). * * An endpoint for a given protocol is obtained by the web server plugin * from a worker object for that protocol. See below for details. * * As with all the core jk classes, this is essentially an abstract base * class which is implemented/extended by classes which are specific to a * particular protocol. By using an abstract base class in this manner, * plugins can be written for different servers (e.g. IIS, Apache) without * the plugins having to worry about which protocol they are talking. * * This particular OO-in-C system uses a 'endpoint_private' pointer to * point to the protocol-specific data/functions. So in the subclasses, the * methods do most of their work by getting their hands on the * endpoint_private pointer and then using that to get at the functions for * their protocol. * * Try imagining this as a 'public abstract class', and the * endpoint_private pointer as a sort of extra 'this' reference. Or * imagine that you are seeing the internal vtables of your favorite OO * language. Whatever works for you. * * See jk_ajp13_worker.c/jk_ajp14_worker.c and jk_ajp12_worker.c for examples. */ struct jk_endpoint { jk_uint64_t rd; jk_uint64_t wr; /* * Flag to pass back recoverability status from * a load balancer member to the load balancer itself. * Depending on the configuration and request status * recovery is not allowed. */ int recoverable; /* * A 'this' pointer which is used by the subclasses of this class to * point to data/functions which are specific to a given protocol * (e.g. ajp12 or ajp13 or ajp14). */ void *endpoint_private; /* * Forward a request to the servlet engine. The request is described * by the jk_ws_service_t object. * is_error is either 0 meaning recoverable or set to * the HTTP error code. */ int (JK_METHOD * service) (jk_endpoint_t *e, jk_ws_service_t *s, jk_logger_t *l, int *is_error); /* * Called when this particular endpoint has finished processing a * request. For some protocols (e.g. ajp12), this frees the memory * associated with the endpoint. For others (e.g. ajp13/ajp14), this can * return the endpoint to a cache of already opened endpoints. * * Note that the first argument is *not* a 'this' pointer, but is * rather a pointer to a 'this' pointer. This is necessary, because * we may need to free this object. */ int (JK_METHOD * done) (jk_endpoint_t **p, jk_logger_t *l); }; /* * The worker 'class', which represents something to which the web server * can delegate requests. * * This can mean communicating with a particular servlet engine instance, * using a particular protocol. A single web server instance may have * multiple workers communicating with a single servlet engine (it could be * using ajp12 for some requests and ajp13/ajp14 for others). Or, a single web * server instance could have multiple workers communicating with different * servlet engines using the same protocol (it could be load balancing * among many engines, using ajp13/ajp14 for all communication). * * There is also a load balancing worker (jk_lb_worker.c), which itself * manages a group of workers. * * Web servers are configured to forward requests to a given worker. To * handle those requests, the worker's get_endpoint method is called, and * then the service() method of that endpoint is called. * * As with all the core jk classes, this is essentially an abstract base * class which is implemented/extended by classes which are specific to a * particular protocol (or request-handling system). By using an abstract * base class in this manner, plugins can be written for different servers * (e.g. IIS, Apache) without the plugins having to worry about which * protocol they are talking. * * This particular OO-in-C system uses a 'worker_private' pointer to * point to the protocol-specific data/functions. So in the subclasses, the * methods do most of their work by getting their hands on the * worker_private pointer and then using that to get at the functions for * their protocol. * * Try imagining this as a 'public abstract class', and the * worker_private pointer as a sort of extra 'this' reference. Or * imagine that you are seeing the internal vtables of your favorite OO * language. Whatever works for you. * * See jk_ajp14_worker.c, jk_ajp13_worker.c and jk_ajp12_worker.c for examples. */ struct jk_worker { jk_worker_env_t *we; /* * A 'this' pointer which is used by the subclasses of this class to * point to data/functions which are specific to a given protocol * (e.g. ajp12 or ajp13 or ajp14). */ void *worker_private; int type; /* * For all of the below (except destroy), the first argument is * essentially a 'this' pointer. */ /* * Given a worker which is in the process of being created, and a list * of configuration options (or 'properties'), check to see if it the * options are. This will always be called before the init() method. * The init/validate distinction is a bit hazy to me. * See jk_ajp13_worker.c/jk_ajp14_worker.c and jk_worker.c->wc_create_worker() */ int (JK_METHOD * validate) (jk_worker_t *w, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l); /* * Update worker either from jk_status or reloading from workers.properties */ int (JK_METHOD * update) (jk_worker_t *w, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l); /* * Do whatever initialization needs to be done to start this worker up. * Configuration options are passed in via the props parameter. */ int (JK_METHOD * init) (jk_worker_t *w, jk_map_t *props, jk_worker_env_t *we, jk_logger_t *l); /* * Obtain an endpoint to service a particular request. A pointer to * the endpoint is stored in pend. */ int (JK_METHOD * get_endpoint) (jk_worker_t *w, jk_endpoint_t **pend, jk_logger_t *l); /* * Shutdown this worker. The first argument is not a 'this' pointer, * but rather a pointer to 'this', so that the object can be free'd (I * think -- though that doesn't seem to be happening. Hmmm). */ int (JK_METHOD * destroy) (jk_worker_t **w, jk_logger_t *l); /* * Maintain this worker. */ int (JK_METHOD * maintain) (jk_worker_t *w, time_t now, int global, jk_logger_t *l); /* * Shut this worker down. */ int (JK_METHOD * shutdown) (jk_worker_t *w, jk_logger_t *l); }; /* * Essentially, an abstract base class (or factory class) with a single * method -- think of it as createWorker() or the Factory Method Design * Pattern. There is a different worker_factory function for each of the * different types of workers. The set of all these functions is created * at startup from the list in jk_worker_list.h, and then the correct one * is chosen in jk_worker.c->wc_create_worker(). See jk_worker.c and * jk_ajp13_worker.c/jk_ajp14_worker.c for examples. * * This allows new workers to be written without modifing the plugin code * for the various web servers (since the only link is through * jk_worker_list.h). */ typedef int (JK_METHOD * worker_factory) (jk_worker_t **w, const char *name, jk_logger_t *l); void jk_init_ws_service(jk_ws_service_t *s); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_SERVICE_H */ tomcat-connectors-1.2.41-src/native/common/jk_url.c0000644000000000000020000002306112451326232020525 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: URL manipulation subroutines. (ported from mod_proxy). * * Version: $Revision: 531816 $ * ***************************************************************************/ #include "jk_global.h" #include "jk_url.h" static void jk_c2hex(int ch, char *x) { #if !CHARSET_EBCDIC int i; x[0] = '%'; i = (ch & 0xF0) >> 4; if (i >= 10) { x[1] = ('A' - 10) + i; } else { x[1] = '0' + i; } i = ch & 0x0F; if (i >= 10) { x[2] = ('A' - 10) + i; } else { x[2] = '0' + i; } #else /*CHARSET_EBCDIC*/ static const char ntoa[] = { "0123456789ABCDEF" }; char buf[1]; ch &= 0xFF; buf[0] = ch; jk_xlate_to_ascii(buf, 1); x[0] = '%'; x[1] = ntoa[(buf[0] >> 4) & 0x0F]; x[2] = ntoa[buf[0] & 0x0F]; x[3] = '\0'; #endif /*CHARSET_EBCDIC*/ } /* * Convert a URL-encoded string to canonical form. * It encodes those which must be encoded, and does not touch * those which must not be touched. * String x must be '\0'-terminated. * String y must be pre-allocated with len maxlen * (including the terminating '\0'). */ int jk_canonenc(const char *x, char *y, int maxlen) { int i, j; int ch = x[0]; char *allowed; /* characters which should not be encoded */ char *reserved; /* characters which much not be en/de-coded */ /* * N.B. in addition to :@&=, this allows ';' in an http path * and '?' in an ftp path -- this may be revised */ allowed = "~$-_.+!*'(),;:@&="; reserved = "/"; for (i = 0, j = 0; ch != '\0' && j < maxlen; i++, j++, ch=x[i]) { /* always handle '/' first */ if (strchr(reserved, ch)) { y[j] = ch; continue; } /* recode it, if necessary */ if (!jk_isalnum(ch) && !strchr(allowed, ch)) { if (j+2= 'A') ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0')); digit *= 16; digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 : (what[1] - '0')); #else /*USE_CHARSET_EBCDIC*/ char xstr[5]; xstr[0]='0'; xstr[1]='x'; xstr[2]=what[0]; xstr[3]=what[1]; xstr[4]='\0'; digit = convert_a2e[0xFF & strtol(xstr, NULL, 16)]; #endif /*USE_CHARSET_EBCDIC*/ return (digit); } #define jk_isxdigit(c) (isxdigit(((unsigned char)(c)))) /** * Unescapes a URL, leaving reserved characters intact. * @param unescaped Optional buffer to write the encoded string, can be * NULL, in which case the URL decoding does not actually take place * but the result length of the decoded URL will be returned. * @param url String to be unescaped * @param slen The length of the original url, or -1 to decode until * a terminating '\0' is seen * @param forbid Optional list of forbidden characters, in addition to * 0x00 * @param reserved Optional list of reserved characters that will be * left unescaped * @param plus If non zero, '+' is converted to ' ' as per * application/x-www-form-urlencoded encoding * @param len If set, the length of the unescaped string will be returned * @return JK_TRUE on success, JK_FALSE if no characters are * decoded or the string is NULL, if a bad escape sequence is * found, or if a character on the forbid list is found. * Implementation copied from APR 1.5.x. */ int jk_unescape_url(char *const unescaped, const char *const url, size_t slen, const char *const forbid, const char *const reserved, const int plus, size_t *len) { size_t size = 1; int found = 0; const char *s = (const char *) url; char *d = (char *) unescaped; register int badesc, badpath; if (!url) { return JK_FALSE; } badesc = 0; badpath = 0; if (s) { if (d) { for (; *s && slen; ++s, d++, slen--) { if (plus && *s == '+') { *d = ' '; found = 1; } else if (*s != '%') { *d = *s; } else { if (!jk_isxdigit(*(s + 1)) || !jk_isxdigit(*(s + 2))) { badesc = 1; *d = '%'; } else { char decoded; decoded = x2c(s + 1); if ((decoded == '\0') || (forbid && strchr(forbid, decoded))) { badpath = 1; *d = decoded; s += 2; slen -= 2; } else if (reserved && strchr(reserved, decoded)) { *d++ = *s++; *d++ = *s++; *d = *s; size += 2; } else { *d = decoded; s += 2; slen -= 2; found = 1; } } } size++; } *d = '\0'; } else { for (; *s && slen; ++s, slen--) { if (plus && *s == '+') { found = 1; } else if (*s != '%') { /* character unchanged */ } else { if (!jk_isxdigit(*(s + 1)) || !jk_isxdigit(*(s + 2))) { badesc = 1; } else { char decoded; decoded = x2c(s + 1); if ((decoded == '\0') || (forbid && strchr(forbid, decoded))) { badpath = 1; s += 2; slen -= 2; } else if (reserved && strchr(reserved, decoded)) { s += 2; slen -= 2; size += 2; } else { s += 2; slen -= 2; found = 1; } } } size++; } } } if (len) { *len = size; } if (badesc) { return JK_FALSE; } else if (badpath) { return JK_FALSE; } else if (!found) { return JK_TRUE; } return JK_TRUE; } tomcat-connectors-1.2.41-src/native/common/jk_uri_worker_map.c0000644000000000000020000013415712453003760022761 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: URI to worker map object. * * * * Author: Gal Shachor * * Author: Mladen Turk * * Version: $Revision: 1649849 $ * ***************************************************************************/ #include "jk_pool.h" #include "jk_util.h" #include "jk_map.h" #include "jk_mt.h" #include "jk_uri_worker_map.h" #include "jk_worker.h" #include "jk_lb_worker.h" #ifdef WIN32 #define JK_STRCMP strcasecmp #define JK_STRNCMP strnicmp #else #define JK_STRCMP strcmp #define JK_STRNCMP strncmp #endif #define JK_UWMAP_EXTENSION_REPLY_TIMEOUT "reply_timeout=" #define JK_UWMAP_EXTENSION_STICKY_IGNORE "sticky_ignore=" #define JK_UWMAP_EXTENSION_STATELESS "stateless=" #define JK_UWMAP_EXTENSION_ACTIVE "active=" #define JK_UWMAP_EXTENSION_DISABLED "disabled=" #define JK_UWMAP_EXTENSION_STOPPED "stopped=" #define JK_UWMAP_EXTENSION_FAIL_ON_STATUS "fail_on_status=" #define JK_UWMAP_EXTENSION_USE_SRV_ERRORS "use_server_errors=" #define JK_UWMAP_EXTENSION_SESSION_COOKIE "session_cookie=" #define JK_UWMAP_EXTENSION_SESSION_PATH "session_path=" #define JK_UWMAP_EXTENSION_SET_SESSION_COOKIE "set_session_cookie=" #define JK_UWMAP_EXTENSION_SESSION_COOKIE_PATH "session_cookie_path=" #define IND_SWITCH(x) (((x)+1) % 2) #define IND_THIS(x) ((x)[uw_map->index]) #define IND_NEXT(x) ((x)[IND_SWITCH(uw_map->index)]) #define STRNULL_FOR_NULL(x) ((x) ? (x) : "(null)") static volatile int map_id_counter = 0; static const char *uri_worker_map_source_type[] = { "unknown", SOURCE_TYPE_TEXT_WORKERDEF, SOURCE_TYPE_TEXT_JKMOUNT, SOURCE_TYPE_TEXT_URIMAP, SOURCE_TYPE_TEXT_DISCOVER, NULL }; /* Return the string representation of the uwr source */ const char *uri_worker_map_get_source(uri_worker_record_t *uwr, jk_logger_t *l) { return uri_worker_map_source_type[uwr->source_type]; } /* Return the string representation of the uwr match type */ char *uri_worker_map_get_match(uri_worker_record_t *uwr, char *buf, jk_logger_t *l) { unsigned int match; buf[0] = '\0'; match = uwr->match_type; if (match & MATCH_TYPE_DISABLED) strcat(buf, "Disabled "); /* deprecated if (match & MATCH_TYPE_STOPPED) strcat(buf, "Stopped "); */ if (match & MATCH_TYPE_NO_MATCH) strcat(buf, "Unmount "); if (match & MATCH_TYPE_EXACT) strcat(buf, "Exact"); else if (match & MATCH_TYPE_WILDCHAR_PATH) strcat(buf, "Wildchar"); /* deprecated else if (match & MATCH_TYPE_CONTEXT) strcat(buf, "Context"); else if (match & MATCH_TYPE_CONTEXT_PATH) strcat(buf, "Context Path"); else if (match & MATCH_TYPE_SUFFIX) strcat(buf, "Suffix"); else if (match & MATCH_TYPE_GENERAL_SUFFIX) return "General Suffix"; */ else strcat(buf, "Unknown"); return buf; } /* * Given context uri, count the number of path tokens. * * Servlet specification 2.4, SRV.11.1 says * The container will recursively try tomatch the longest * path-prefix. This is done by stepping down the path tree a * directory at a time, using the / character as a path * separator. The longest match determines the servlet selected. * * The implication seems to be `most uri path elements is most exact'. * This is a little helper function to count uri tokens, so we can * keep the worker map sorted with most specific first. */ static int worker_count_context_uri_tokens(const char * context) { const char * c = context; int count = 0; while (c && *c) { if ('/' == *c++) count++; } return count; } static int worker_compare(const void *elem1, const void *elem2) { uri_worker_record_t *e1 = *(uri_worker_record_t **)elem1; uri_worker_record_t *e2 = *(uri_worker_record_t **)elem2; int e1_tokens = 0; int e2_tokens = 0; e1_tokens = worker_count_context_uri_tokens(e1->context); e2_tokens = worker_count_context_uri_tokens(e2->context); if (e1_tokens != e2_tokens) { return (e2_tokens - e1_tokens); } /* given the same number of URI tokens, use character * length as a tie breaker */ if(e2->context_len != e1->context_len) return ((int)e2->context_len - (int)e1->context_len); return ((int)e2->source_type - (int)e1->source_type); } static void worker_qsort(jk_uri_worker_map_t *uw_map) { /* Sort remaining args using Quicksort algorithm: */ qsort((void *)IND_NEXT(uw_map->maps), IND_NEXT(uw_map->size), sizeof(uri_worker_record_t *), worker_compare ); } /* Dump the map contents - only call if debug log is active. */ static void uri_worker_map_dump(jk_uri_worker_map_t *uw_map, const char *reason, jk_logger_t *l) { JK_TRACE_ENTER(l); if (uw_map) { int i, off; if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "uri map dump %s: id=%d, index=%d file='%s' reject_unsafe=%d " "collapse_slashes=%d reload=%d modified=%d checked=%d", reason, uw_map->id, uw_map->index, STRNULL_FOR_NULL(uw_map->fname), uw_map->reject_unsafe, uw_map->collapse_slashes, uw_map->reload, uw_map->modified, uw_map->checked); } for (i = 0; i <= 1; i++) { jk_log(l, JK_LOG_DEBUG, "generation %d: size=%d nosize=%d capacity=%d", i, uw_map->size[i], uw_map->nosize[i], uw_map->capacity[i], uw_map->maps[i]); } off = uw_map->index; for (i = 0; i <= 1; i++) { char buf[32]; int k; unsigned int j; k = (i + off) % 2; for (j = 0; j < uw_map->size[k]; j++) { uri_worker_record_t *uwr = uw_map->maps[k][j]; if (uwr && JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "%s (%d) map #%d: uri=%s worker=%s context=%s " "source=%s type=%s len=%d", i ? "NEXT" : "THIS", i, j, STRNULL_FOR_NULL(uwr->uri), STRNULL_FOR_NULL(uwr->worker_name), STRNULL_FOR_NULL(uwr->context), STRNULL_FOR_NULL(uri_worker_map_get_source(uwr,l)), STRNULL_FOR_NULL(uri_worker_map_get_match(uwr,buf,l)), uwr->context_len); } } } } JK_TRACE_EXIT(l); } int uri_worker_map_alloc(jk_uri_worker_map_t **uw_map_p, jk_map_t *init_data, jk_logger_t *l) { int i; JK_TRACE_ENTER(l); if (uw_map_p) { int rc; jk_uri_worker_map_t *uw_map; *uw_map_p = (jk_uri_worker_map_t *)calloc(1, sizeof(jk_uri_worker_map_t)); uw_map = *uw_map_p; JK_INIT_CS(&(uw_map->cs), rc); if (rc == JK_FALSE) { jk_log(l, JK_LOG_ERROR, "creating thread lock (errno=%d)", errno); JK_TRACE_EXIT(l); return JK_FALSE; } jk_open_pool(&(uw_map->p), uw_map->buf, sizeof(jk_pool_atom_t) * BIG_POOL_SIZE); for (i = 0; i <= 1; i++) { jk_open_pool(&(uw_map->p_dyn[i]), uw_map->buf_dyn[i], sizeof(jk_pool_atom_t) * BIG_POOL_SIZE); uw_map->size[i] = 0; uw_map->nosize[i] = 0; uw_map->capacity[i] = 0; uw_map->maps[i] = NULL; } uw_map->id = 0; uw_map->index = 0; uw_map->fname = NULL; uw_map->reject_unsafe = 0; uw_map->collapse_slashes = JK_COLLAPSE_DEFAULT; uw_map->reload = JK_URIMAP_DEF_RELOAD; uw_map->modified = 0; uw_map->checked = 0; if (init_data) rc = uri_worker_map_open(uw_map, init_data, l); if (rc == JK_TRUE) uw_map->id = ++map_id_counter; JK_TRACE_EXIT(l); return rc; } JK_LOG_NULL_PARAMS(l); JK_TRACE_EXIT(l); return JK_FALSE; } static int uri_worker_map_close(jk_uri_worker_map_t *uw_map, jk_logger_t *l) { JK_TRACE_ENTER(l); if (uw_map) { JK_DELETE_CS(&uw_map->cs); jk_close_pool(&uw_map->p_dyn[0]); jk_close_pool(&uw_map->p_dyn[1]); jk_close_pool(&uw_map->p); JK_TRACE_EXIT(l); return JK_TRUE; } JK_LOG_NULL_PARAMS(l); JK_TRACE_EXIT(l); return JK_FALSE; } int uri_worker_map_free(jk_uri_worker_map_t **uw_map, jk_logger_t *l) { JK_TRACE_ENTER(l); if (uw_map && *uw_map) { uri_worker_map_close(*uw_map, l); free(*uw_map); *uw_map = NULL; JK_TRACE_EXIT(l); return JK_TRUE; } else JK_LOG_NULL_PARAMS(l); JK_TRACE_EXIT(l); return JK_FALSE; } /* * Ensure there will be memory in context info to store Context Bases */ #define UW_INC_SIZE 4 /* 4 URI->WORKER STEP */ static int uri_worker_map_realloc(jk_uri_worker_map_t *uw_map) { if (IND_NEXT(uw_map->size) == IND_NEXT(uw_map->capacity)) { uri_worker_record_t **uwr; int capacity = IND_NEXT(uw_map->capacity) + UW_INC_SIZE; uwr = (uri_worker_record_t **) jk_pool_alloc(&IND_NEXT(uw_map->p_dyn), sizeof(uri_worker_record_t *) * capacity); if (!uwr) return JK_FALSE; if (IND_NEXT(uw_map->capacity) && IND_NEXT(uw_map->maps)) memcpy(uwr, IND_NEXT(uw_map->maps), sizeof(uri_worker_record_t *) * IND_NEXT(uw_map->capacity)); IND_NEXT(uw_map->maps) = uwr; IND_NEXT(uw_map->capacity) = capacity; } return JK_TRUE; } /* * Delete all entries of a given source type */ static int uri_worker_map_clear(jk_uri_worker_map_t *uw_map, jk_logger_t *l) { uri_worker_record_t *uwr = NULL; unsigned int i; unsigned int new_size = 0; unsigned int new_nosize = 0; JK_TRACE_ENTER(l); IND_NEXT(uw_map->maps) = (uri_worker_record_t **) jk_pool_alloc(&(IND_NEXT(uw_map->p_dyn)), sizeof(uri_worker_record_t *) * IND_THIS(uw_map->size)); IND_NEXT(uw_map->capacity) = IND_THIS(uw_map->size); IND_NEXT(uw_map->size) = 0; IND_NEXT(uw_map->nosize) = 0; for (i = 0; i < IND_THIS(uw_map->size); i++) { uwr = IND_THIS(uw_map->maps)[i]; if (uwr->source_type == SOURCE_TYPE_URIMAP) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "deleting map rule '%s=%s' source '%s'", uwr->context, uwr->worker_name, uri_worker_map_get_source(uwr, l)); } else { IND_NEXT(uw_map->maps)[new_size] = uwr; new_size++; if (uwr->match_type & MATCH_TYPE_NO_MATCH) new_nosize++; } } IND_NEXT(uw_map->size) = new_size; IND_NEXT(uw_map->nosize) = new_nosize; JK_TRACE_EXIT(l); return JK_TRUE; } static void extract_activation(jk_pool_t *p, lb_worker_t *lb, int *activations, char *workers, int activation, jk_logger_t *l) { unsigned int i; char *worker; #ifdef _MT_CODE_PTHREAD char *lasts; #endif JK_TRACE_ENTER(l); worker = jk_pool_strdup(p, workers); #ifdef _MT_CODE_PTHREAD for (worker = strtok_r(worker, ", ", &lasts); worker; worker = strtok_r(NULL, ", ", &lasts)) { #else for (worker = strtok(worker, ", "); worker; worker = strtok(NULL, ", ")) { #endif for (i = 0; i < lb->num_of_workers; i++) { if (!strcmp(worker, lb->lb_workers[i].name)) { if (activations[i] != JK_LB_ACTIVATION_UNSET) jk_log(l, JK_LOG_WARNING, "inconsistent activation overwrite for member %s " "of load balancer %s: '%s' replaced by '%s'", worker, lb->name, jk_lb_get_activation_direct(activations[i], l), jk_lb_get_activation_direct(activation, l)); activations[i] = activation; break; } } if (i >= lb->num_of_workers) jk_log(l, JK_LOG_WARNING, "could not find member %s of load balancer %s", worker, lb->name); } JK_TRACE_EXIT(l); } static void extension_fix_fail_on_status(jk_pool_t *p, const char *name, rule_extension_t *extensions, jk_logger_t *l) { unsigned int i; int j; int cnt = 1; char *status; #ifdef _MT_CODE_PTHREAD char *lasts; #endif JK_TRACE_ENTER(l); for (i = 0; i < (unsigned int)strlen(extensions->fail_on_status_str); i++) { if (extensions->fail_on_status_str[i] == ',' || extensions->fail_on_status_str[i] == ' ') cnt++; } extensions->fail_on_status_size = cnt; status = jk_pool_strdup(p, extensions->fail_on_status_str); extensions->fail_on_status = (int *)jk_pool_alloc(p, extensions->fail_on_status_size * sizeof(int)); if (!extensions->fail_on_status) { jk_log(l, JK_LOG_ERROR, "can't alloc extensions fail_on_status list for worker (%s)", name); JK_TRACE_EXIT(l); return; } else if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Allocated fail_on_status array of size %d for worker (%s)", extensions->fail_on_status_size, name); for (j=0; jfail_on_status_size; j++) { extensions->fail_on_status[j] = 0; } cnt = 0; #ifdef _MT_CODE_PTHREAD for (status = strtok_r(status, ", ", &lasts); status; status = strtok_r(NULL, ", ", &lasts)) { #else for (status = strtok(status, ", "); status; status = strtok(NULL, ", ")) { #endif extensions->fail_on_status[cnt] = atoi(status); cnt++; } JK_TRACE_EXIT(l); } static int extension_fix_activation(jk_pool_t *p, const char *name, jk_worker_t *jw, rule_extension_t *extensions, jk_logger_t *l) { JK_TRACE_ENTER(l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Checking extension for worker %s of type %s (%d)", name, wc_get_name_for_type(jw->type,l), jw->type); if (jw->type == JK_LB_WORKER_TYPE && (extensions->active || extensions->disabled || extensions->stopped)) { int j; lb_worker_t *lb = (lb_worker_t *)jw->worker_private; if (!extensions->activation) { extensions->activation_size = lb->num_of_workers; extensions->activation = (int *)jk_pool_alloc(p, extensions->activation_size * sizeof(int)); if (!extensions->activation) { jk_log(l, JK_LOG_ERROR, "can't alloc extensions activation list"); JK_TRACE_EXIT(l); return JK_FALSE; } else if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Allocated activations array of size %d for lb worker %s", extensions->activation_size, name); for (j=0; jactivation_size; j++) { extensions->activation[j] = JK_LB_ACTIVATION_UNSET; } } if (extensions->active) extract_activation(p, lb, extensions->activation, extensions->active, JK_LB_ACTIVATION_ACTIVE, l); if (extensions->disabled) extract_activation(p, lb, extensions->activation, extensions->disabled, JK_LB_ACTIVATION_DISABLED, l); if (extensions->stopped) extract_activation(p, lb, extensions->activation, extensions->stopped, JK_LB_ACTIVATION_STOPPED, l); } else if (extensions->active) { jk_log(l, JK_LOG_WARNING, "Worker %s is not of type lb, activation extension " JK_UWMAP_EXTENSION_ACTIVE " for %s ignored", name, extensions->active); } else if (extensions->disabled) { jk_log(l, JK_LOG_WARNING, "Worker %s is not of type lb, activation extension " JK_UWMAP_EXTENSION_DISABLED " for %s ignored", name, extensions->disabled); } else if (extensions->stopped) { jk_log(l, JK_LOG_WARNING, "Worker %s is not of type lb, activation extension " JK_UWMAP_EXTENSION_STOPPED " for %s ignored", name, extensions->stopped); } JK_TRACE_EXIT(l); return JK_TRUE; } static void extension_fix_session(jk_pool_t *p, const char *name, jk_worker_t *jw, rule_extension_t *extensions, jk_logger_t *l) { if (jw->type != JK_LB_WORKER_TYPE && extensions->session_cookie) { jk_log(l, JK_LOG_WARNING, "Worker %s is not of type lb, extension " JK_UWMAP_EXTENSION_SESSION_COOKIE " for %s ignored", name, extensions->session_cookie); } if (jw->type != JK_LB_WORKER_TYPE && extensions->session_path) { jk_log(l, JK_LOG_WARNING, "Worker %s is not of type lb, extension " JK_UWMAP_EXTENSION_SESSION_PATH " for %s ignored", name, extensions->session_path); } if (jw->type != JK_LB_WORKER_TYPE && extensions->set_session_cookie) { jk_log(l, JK_LOG_WARNING, "Worker %s is not of type lb, extension " JK_UWMAP_EXTENSION_SET_SESSION_COOKIE " for %s ignored", name, extensions->set_session_cookie ? "'true'" : "'false'"); } if (jw->type != JK_LB_WORKER_TYPE && extensions->session_cookie_path) { jk_log(l, JK_LOG_WARNING, "Worker %s is not of type lb, extension " JK_UWMAP_EXTENSION_SESSION_COOKIE_PATH " for %s ignored", name, extensions->session_cookie_path); } } void extension_fix(jk_pool_t *p, const char *name, rule_extension_t *extensions, jk_logger_t *l) { jk_worker_t *jw = wc_get_worker_for_name(name, l); if(!jw) { jk_log(l, JK_LOG_ERROR, "Could not find worker with name '%s' in uri map post processing.", name); return; } if (!extension_fix_activation(p, name, jw, extensions, l)) return; if (extensions->fail_on_status_str) { extension_fix_fail_on_status(p, name, extensions, l); } extension_fix_session(p, name, jw, extensions, l); } void uri_worker_map_switch(jk_uri_worker_map_t *uw_map, jk_logger_t *l) { int new_index; JK_TRACE_ENTER(l); if (uw_map) { new_index = IND_SWITCH(uw_map->index); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Switching uri worker map from index %d to index %d", uw_map->index, new_index); uw_map->index = new_index; jk_reset_pool(&(IND_NEXT(uw_map->p_dyn))); } JK_TRACE_EXIT(l); } void uri_worker_map_ext(jk_uri_worker_map_t *uw_map, jk_logger_t *l) { unsigned int i; JK_TRACE_ENTER(l); for (i = 0; i < IND_NEXT(uw_map->size); i++) { uri_worker_record_t *uwr = IND_NEXT(uw_map->maps)[i]; jk_pool_t *p; if(uwr->match_type & MATCH_TYPE_NO_MATCH) continue; if (uwr->source_type == SOURCE_TYPE_URIMAP) p = &IND_NEXT(uw_map->p_dyn); else p = &uw_map->p; extension_fix(p, uwr->worker_name, &uwr->extensions, l); } if (JK_IS_DEBUG_LEVEL(l)) uri_worker_map_dump(uw_map, "after extension stripping", l); JK_TRACE_EXIT(l); return; } /* Parse rule extensions */ void parse_rule_extensions(char *rule, rule_extension_t *extensions, jk_logger_t *l) { char *param; #ifdef _MT_CODE_PTHREAD char *lasts = NULL; #endif extensions->reply_timeout = -1; extensions->sticky_ignore = JK_FALSE; extensions->stateless = JK_FALSE; extensions->active = NULL; extensions->disabled = NULL; extensions->stopped = NULL; extensions->activation_size = 0; extensions->activation = NULL; extensions->fail_on_status_size = 0; extensions->fail_on_status = NULL; extensions->fail_on_status_str = NULL; extensions->use_server_error_pages = 0; extensions->session_cookie = NULL; extensions->session_path = NULL; extensions->set_session_cookie = JK_FALSE; extensions->session_cookie_path = NULL; #ifdef _MT_CODE_PTHREAD param = strtok_r(rule, ";", &lasts); #else param = strtok(rule, ";"); #endif if (param) { #ifdef _MT_CODE_PTHREAD for (param = strtok_r(NULL, ";", &lasts); param; param = strtok_r(NULL, ";", &lasts)) { #else for (param = strtok(NULL, ";"); param; param = strtok(NULL, ";")) { #endif if (!strncmp(param, JK_UWMAP_EXTENSION_REPLY_TIMEOUT, strlen(JK_UWMAP_EXTENSION_REPLY_TIMEOUT))) { extensions->reply_timeout = atoi(param + strlen(JK_UWMAP_EXTENSION_REPLY_TIMEOUT)); } else if (!strncmp(param, JK_UWMAP_EXTENSION_STICKY_IGNORE, strlen(JK_UWMAP_EXTENSION_STICKY_IGNORE))) { int val = atoi(param + strlen(JK_UWMAP_EXTENSION_STICKY_IGNORE)); if (val) { extensions->sticky_ignore = JK_TRUE; } else { extensions->sticky_ignore = JK_FALSE; } } else if (!strncmp(param, JK_UWMAP_EXTENSION_STATELESS, strlen(JK_UWMAP_EXTENSION_STATELESS))) { int val = atoi(param + strlen(JK_UWMAP_EXTENSION_STATELESS)); if (val) { extensions->stateless = JK_TRUE; } else { extensions->stateless = JK_FALSE; } } else if (!strncmp(param, JK_UWMAP_EXTENSION_USE_SRV_ERRORS, strlen(JK_UWMAP_EXTENSION_USE_SRV_ERRORS))) { extensions->use_server_error_pages = atoi(param + strlen(JK_UWMAP_EXTENSION_USE_SRV_ERRORS)); } else if (!strncmp(param, JK_UWMAP_EXTENSION_ACTIVE, strlen(JK_UWMAP_EXTENSION_ACTIVE))) { if (extensions->active) jk_log(l, JK_LOG_WARNING, "rule extension '" JK_UWMAP_EXTENSION_ACTIVE "' only allowed once"); else extensions->active = param + strlen(JK_UWMAP_EXTENSION_ACTIVE); } else if (!strncmp(param, JK_UWMAP_EXTENSION_DISABLED, strlen(JK_UWMAP_EXTENSION_DISABLED))) { if (extensions->disabled) jk_log(l, JK_LOG_WARNING, "rule extension '" JK_UWMAP_EXTENSION_DISABLED "' only allowed once"); else extensions->disabled = param + strlen(JK_UWMAP_EXTENSION_DISABLED); } else if (!strncmp(param, JK_UWMAP_EXTENSION_STOPPED, strlen(JK_UWMAP_EXTENSION_STOPPED))) { if (extensions->stopped) jk_log(l, JK_LOG_WARNING, "rule extension '" JK_UWMAP_EXTENSION_STOPPED "' only allowed once"); else extensions->stopped = param + strlen(JK_UWMAP_EXTENSION_STOPPED); } else if (!strncmp(param, JK_UWMAP_EXTENSION_FAIL_ON_STATUS, strlen(JK_UWMAP_EXTENSION_FAIL_ON_STATUS))) { if (extensions->fail_on_status_str) jk_log(l, JK_LOG_WARNING, "rule extension '" JK_UWMAP_EXTENSION_FAIL_ON_STATUS "' only allowed once"); else extensions->fail_on_status_str = param + strlen(JK_UWMAP_EXTENSION_FAIL_ON_STATUS); } else if (!strncmp(param, JK_UWMAP_EXTENSION_SESSION_COOKIE, strlen(JK_UWMAP_EXTENSION_SESSION_COOKIE))) { if (extensions->session_cookie) jk_log(l, JK_LOG_WARNING, "extension '" JK_UWMAP_EXTENSION_SESSION_COOKIE "' in uri worker map only allowed once"); else extensions->session_cookie = param + strlen(JK_UWMAP_EXTENSION_SESSION_COOKIE); } else if (!strncmp(param, JK_UWMAP_EXTENSION_SESSION_PATH, strlen(JK_UWMAP_EXTENSION_SESSION_PATH))) { if (extensions->session_path) jk_log(l, JK_LOG_WARNING, "extension '" JK_UWMAP_EXTENSION_SESSION_PATH "' in uri worker map only allowed once"); else { // Check if the session identifier starts with semicolon. if (!strcmp(param, JK_UWMAP_EXTENSION_SESSION_PATH)) { #ifdef _MT_CODE_PTHREAD param = strtok_r(NULL, ";", &lasts); #else param = strtok(NULL, ";"); #endif extensions->session_path = param; } else extensions->session_path = param + strlen(JK_UWMAP_EXTENSION_SESSION_PATH); } } else if (!strncmp(param, JK_UWMAP_EXTENSION_SET_SESSION_COOKIE, strlen(JK_UWMAP_EXTENSION_SET_SESSION_COOKIE))) { if (extensions->set_session_cookie) jk_log(l, JK_LOG_WARNING, "extension '" JK_UWMAP_EXTENSION_SET_SESSION_COOKIE "' in uri worker map only allowed once"); else { int val = atoi(param + strlen(JK_UWMAP_EXTENSION_SET_SESSION_COOKIE)); if (val) { extensions->set_session_cookie = JK_TRUE; } else { extensions->set_session_cookie = JK_FALSE; } } } else if (!strncmp(param, JK_UWMAP_EXTENSION_SESSION_COOKIE_PATH, strlen(JK_UWMAP_EXTENSION_SESSION_COOKIE_PATH))) { if (extensions->session_cookie_path) jk_log(l, JK_LOG_WARNING, "extension '" JK_UWMAP_EXTENSION_SESSION_COOKIE_PATH "' in uri worker map only allowed once"); else extensions->session_cookie_path = param + strlen(JK_UWMAP_EXTENSION_SESSION_COOKIE_PATH); } else { jk_log(l, JK_LOG_WARNING, "unknown rule extension '%s'", param); } } } } /* Add new entry to NEXT generation */ int uri_worker_map_add(jk_uri_worker_map_t *uw_map, const char *puri, const char *worker, unsigned int source_type, jk_logger_t *l) { uri_worker_record_t *uwr = NULL; char *uri; jk_pool_t *p; unsigned int match_type = 0; JK_TRACE_ENTER(l); if (*puri == '-') { /* Disable urimap. * This way you can disable already mounted * context. */ match_type = MATCH_TYPE_DISABLED; puri++; } if (*puri == '!') { match_type |= MATCH_TYPE_NO_MATCH; puri++; } if (uri_worker_map_realloc(uw_map) == JK_FALSE) { JK_TRACE_EXIT(l); return JK_FALSE; } if (source_type == SOURCE_TYPE_URIMAP) p = &IND_NEXT(uw_map->p_dyn); else p = &uw_map->p; uwr = (uri_worker_record_t *)jk_pool_alloc(p, sizeof(uri_worker_record_t)); if (!uwr) { jk_log(l, JK_LOG_ERROR, "can't alloc map entry"); JK_TRACE_EXIT(l); return JK_FALSE; } uri = jk_pool_strdup(p, puri); if (!uri || !worker) { jk_log(l, JK_LOG_ERROR, "can't alloc uri/worker strings"); JK_TRACE_EXIT(l); return JK_FALSE; } if (*uri == '/') { char *w = jk_pool_strdup(p, worker); parse_rule_extensions(w, &uwr->extensions, l); uwr->source_type = source_type; uwr->worker_name = w; uwr->uri = uri; uwr->context = uri; uwr->context_len = strlen(uwr->context); if (strchr(uri, '*') || strchr(uri, '?')) { /* Something like * /context/ * /user/ * * /context/ *.suffix */ match_type |= MATCH_TYPE_WILDCHAR_PATH; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "wildchar rule '%s=%s' source '%s' was added", uwr->context, uwr->worker_name, uri_worker_map_get_source(uwr, l)); } else { /* Something like: JkMount /login/j_security_check ajp13 */ match_type |= MATCH_TYPE_EXACT; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "exact rule '%s=%s' source '%s' was added", uwr->context, uwr->worker_name, uri_worker_map_get_source(uwr, l)); } } else { /* * JFC: please check... * Not sure what to do, but I try to prevent problems. * I have fixed jk_mount_context() in apaches/mod_jk.c so we should * not arrive here when using Apache. */ jk_log(l, JK_LOG_ERROR, "invalid context '%s': does not begin with '/'", uri); JK_TRACE_EXIT(l); return JK_FALSE; } uwr->match_type = match_type; IND_NEXT(uw_map->maps)[IND_NEXT(uw_map->size)] = uwr; IND_NEXT(uw_map->size)++; if (match_type & MATCH_TYPE_NO_MATCH) { /* If we split the mappings this one will be calculated */ IND_NEXT(uw_map->nosize)++; } worker_qsort(uw_map); JK_TRACE_EXIT(l); return JK_TRUE; } int uri_worker_map_open(jk_uri_worker_map_t *uw_map, jk_map_t *init_data, jk_logger_t *l) { int rc = JK_TRUE; JK_TRACE_ENTER(l); if (uw_map) { int sz = jk_map_size(init_data); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "rule map size is %d", sz); if (sz > 0) { int i; for (i = 0; i < sz; i++) { const char *u = jk_map_name_at(init_data, i); const char *w = jk_map_value_at(init_data, i); /* Multiple mappings like : * /servlets-examples|/ * * will create two mappings: * /servlets-examples * and: * /servlets-examples/ * */ if (strchr(u, '|')) { char *s, *r = strdup(u); s = strchr(r, '|'); *(s++) = '\0'; /* Add first mapping */ if (!uri_worker_map_add(uw_map, r, w, SOURCE_TYPE_JKMOUNT, l)) { jk_log(l, JK_LOG_ERROR, "invalid mapping rule %s->%s", r, w); rc = JK_FALSE; } for (; *s; s++) *(s - 1) = *s; *(s - 1) = '\0'; /* add second mapping */ if (!uri_worker_map_add(uw_map, r, w, SOURCE_TYPE_JKMOUNT, l)) { jk_log(l, JK_LOG_ERROR, "invalid mapping rule %s->%s", r, w); rc = JK_FALSE; } free(r); } else if (!uri_worker_map_add(uw_map, u, w, SOURCE_TYPE_JKMOUNT, l)) { jk_log(l, JK_LOG_ERROR, "invalid mapping rule %s->%s", u, w); rc = JK_FALSE; break; } if (rc == JK_FALSE) break; } } if (rc == JK_FALSE) { jk_log(l, JK_LOG_ERROR, "there was an error, freeing buf"); jk_close_pool(&uw_map->p_dyn[0]); jk_close_pool(&uw_map->p_dyn[1]); jk_close_pool(&uw_map->p); } else if (JK_IS_DEBUG_LEVEL(l)) uri_worker_map_dump(uw_map, "after map open", l); } JK_TRACE_EXIT(l); return rc; } static int find_match(jk_uri_worker_map_t *uw_map, const char *url, jk_logger_t *l) { unsigned int i; JK_TRACE_ENTER(l); for (i = 0; i < IND_THIS(uw_map->size); i++) { uri_worker_record_t *uwr = IND_THIS(uw_map->maps)[i]; /* Check for match types */ if ((uwr->match_type & MATCH_TYPE_DISABLED) || (uwr->match_type & MATCH_TYPE_NO_MATCH)) continue; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Attempting to map context URI '%s=%s' source '%s'", uwr->context, uwr->worker_name, uri_worker_map_get_source(uwr, l)); if (uwr->match_type & MATCH_TYPE_WILDCHAR_PATH) { /* Map is already sorted by context_len */ if (jk_wildchar_match(url, uwr->context, #ifdef WIN32 0 #else 0 #endif ) == 0) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Found a wildchar match '%s=%s'", uwr->context, uwr->worker_name); JK_TRACE_EXIT(l); return i; } } else if (JK_STRNCMP(uwr->context, url, uwr->context_len) == 0) { if (strlen(url) == uwr->context_len) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Found an exact match '%s=%s'", uwr->context, uwr->worker_name); JK_TRACE_EXIT(l); return i; } } } JK_TRACE_EXIT(l); return -1; } static int is_nomatch(jk_uri_worker_map_t *uw_map, const char *uri, int match, jk_logger_t *l) { unsigned int i; const char *worker = IND_THIS(uw_map->maps)[match]->worker_name; JK_TRACE_ENTER(l); for (i = 0; i < IND_THIS(uw_map->size); i++) { uri_worker_record_t *uwr = IND_THIS(uw_map->maps)[i]; /* Check only nomatch mappings */ if (!(uwr->match_type & MATCH_TYPE_NO_MATCH) || (uwr->match_type & MATCH_TYPE_DISABLED)) continue; /* Check only matching workers */ if (strcmp(uwr->worker_name, worker) && strcmp(uwr->worker_name, "*")) continue; if (uwr->match_type & MATCH_TYPE_WILDCHAR_PATH) { /* Map is already sorted by context_len */ if (jk_wildchar_match(uri, uwr->context, #ifdef WIN32 0 #else 0 #endif ) == 0) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Found a wildchar no match '%s=%s' source '%s'", uwr->context, uwr->worker_name, uri_worker_map_get_source(uwr, l)); JK_TRACE_EXIT(l); return JK_TRUE; } } else if (JK_STRNCMP(uwr->context, uri, uwr->context_len) == 0) { if (strlen(uri) == uwr->context_len) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Found an exact no match '%s=%s' source '%s'", uwr->context, uwr->worker_name, uri_worker_map_get_source(uwr, l)); JK_TRACE_EXIT(l); return JK_TRUE; } } } JK_TRACE_EXIT(l); return JK_FALSE; } const char *map_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, const char *uri, const char *vhost, rule_extension_t **extensions, int *index, jk_logger_t *l) { unsigned int i; unsigned int vhost_len; int reject_unsafe; int collapse_slashes; int rv = -1; char url[JK_MAX_URI_LEN+1]; JK_TRACE_ENTER(l); if (!uw_map || !uri || !extensions) { JK_LOG_NULL_PARAMS(l); JK_TRACE_EXIT(l); return NULL; } *extensions = NULL; if (index) *index = -1; if (*uri != '/') { if (*uri == '*' && *(uri+1) == '\0') { /* Most likely an "OPTIONS *" request */ if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "Uri %s can't be mapped.", uri); } } else { jk_log(l, JK_LOG_WARNING, "Uri %s is invalid. Uri must start with /", uri); } JK_TRACE_EXIT(l); return NULL; } if (uw_map->fname) { uri_worker_map_update(uw_map, 0, l); if (!IND_THIS(uw_map->size)) { jk_log(l, JK_LOG_INFO, "No worker maps defined for %s.", uw_map->fname); JK_TRACE_EXIT(l); return NULL; } } reject_unsafe = uw_map->reject_unsafe; collapse_slashes = uw_map->collapse_slashes; vhost_len = 0; /* * In case we got a vhost, we prepend a slash * and the vhost to the url in order to enable * vhost mapping rules especially for IIS. */ if (vhost) { int off = 0; /* Add leading '/' if necessary */ if (vhost[0] != '/') { url[0] = '/'; off = 1; } /* Size including leading slash. */ vhost_len = (unsigned int)strlen(vhost); if (vhost_len + off >= JK_MAX_URI_LEN) { vhost_len = 0; jk_log(l, JK_LOG_WARNING, "Host prefix %s for URI %s is invalid and will be ignored." " It must be smaller than %d chars", vhost, JK_MAX_URI_LEN - off); } else { strncpy(&url[off], vhost, vhost_len + 1); } vhost_len += off; } /* Make the copy of the provided uri and strip * everything after the first ';' char. */ for (i = 0; i < strlen(uri); i++) { if (i == JK_MAX_URI_LEN) { jk_log(l, JK_LOG_WARNING, "URI %s is invalid. URI must be smaller than %d chars", uri, JK_MAX_URI_LEN); JK_TRACE_EXIT(l); return NULL; } if (uri[i] == ';') break; else { url[i + vhost_len] = uri[i]; if (reject_unsafe && (uri[i] == '%' || uri[i] == '\\')) { jk_log(l, JK_LOG_INFO, "Potentially unsafe request url '%s' rejected", uri); JK_TRACE_EXIT(l); return NULL; } } } url[i + vhost_len] = '\0'; if (JK_IS_DEBUG_LEVEL(l)) { char *url_rewrite = strstr(uri, JK_PATH_SESSION_IDENTIFIER); if (url_rewrite) jk_log(l, JK_LOG_DEBUG, "Found session identifier '%s' in url '%s'", url_rewrite, uri); } if (collapse_slashes == JK_COLLAPSE_ALL) { /* Remove multiple slashes * No need to copy url, because it is local and * the unchanged url is no longer needed */ jk_no2slash(url); } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Attempting to map URI '%s' from %d maps", url, IND_THIS(uw_map->size)); rv = find_match(uw_map, url, l); /* If this doesn't find a match, try without the vhost. */ if (rv < 0 && vhost_len) { rv = find_match(uw_map, &url[vhost_len], l); } /* In case we found a match, check for the unmounts. */ if (rv >= 0 && IND_THIS(uw_map->nosize)) { int rc; if (collapse_slashes == JK_COLLAPSE_UNMOUNT) { /* Remove multiple slashes when looking for * unmount to prevent trivial unmount bypass attack. * No need to copy url, because it is local and * the unchanged url is no longer needed */ jk_no2slash(url); } /* Again first including vhost. */ rc = is_nomatch(uw_map, url, rv, l); /* If no unmount was found, try without vhost. */ if (!rc && vhost_len) rc = is_nomatch(uw_map, &url[vhost_len], rv, l); if (rc) { if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "Denying match for worker %s by nomatch rule", IND_THIS(uw_map->maps)[rv]->worker_name); } rv = -1; } } if (rv >= 0) { *extensions = &(IND_THIS(uw_map->maps)[rv]->extensions); if (index) *index = rv; JK_TRACE_EXIT(l); return IND_THIS(uw_map->maps)[rv]->worker_name; } JK_TRACE_EXIT(l); return NULL; } rule_extension_t *get_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, int index) { if (index >= 0) { return &(IND_THIS(uw_map->maps)[index]->extensions); } else { return NULL; } } const char *map_uri_to_worker(jk_uri_worker_map_t *uw_map, const char *uri, const char *vhost, jk_logger_t *l) { rule_extension_t *ext; return map_uri_to_worker_ext(uw_map, uri, vhost, &ext, NULL, l); } int uri_worker_map_load(jk_uri_worker_map_t *uw_map, jk_logger_t *l) { int rc = JK_FALSE; jk_map_t *map; jk_map_alloc(&map); if (jk_map_read_properties(map, NULL, uw_map->fname, &uw_map->modified, JK_MAP_HANDLE_NORMAL, l)) { int i; if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Loading urimaps from %s with reload check interval %d seconds", uw_map->fname, uw_map->reload); uri_worker_map_clear(uw_map, l); for (i = 0; i < jk_map_size(map); i++) { const char *u = jk_map_name_at(map, i); const char *w = jk_map_value_at(map, i); /* Multiple mappings like : * /servlets-examples|/ * * will create two mappings: * /servlets-examples * and: * /servlets-examples/ * */ if (strchr(u, '|')) { char *s, *r = strdup(u); s = strchr(r, '|'); *(s++) = '\0'; /* Add first mapping */ if (!uri_worker_map_add(uw_map, r, w, SOURCE_TYPE_URIMAP, l)) { jk_log(l, JK_LOG_ERROR, "invalid mapping rule %s->%s", r, w); } for (; *s; s++) *(s - 1) = *s; *(s - 1) = '\0'; /* add second mapping */ if (!uri_worker_map_add(uw_map, r, w, SOURCE_TYPE_URIMAP, l)) { jk_log(l, JK_LOG_ERROR, "invalid mapping rule %s->%s", r, w); } free(r); } else if (!uri_worker_map_add(uw_map, u, w, SOURCE_TYPE_URIMAP, l)) { jk_log(l, JK_LOG_ERROR, "invalid mapping rule %s->%s", u, w); } } uw_map->checked = time(NULL); if (JK_IS_DEBUG_LEVEL(l)) uri_worker_map_dump(uw_map, "after file load", l); rc = JK_TRUE; } else { jk_log(l, JK_LOG_ERROR, "Failed to load uri_worker_map file %s (errno=%d, err=%s).", uw_map->fname, errno, strerror(errno)); } jk_map_free(&map); return rc; } int uri_worker_map_update(jk_uri_worker_map_t *uw_map, int force, jk_logger_t *l) { int rc = JK_TRUE; time_t now = time(NULL); if (force || (uw_map->reload > 0 && difftime(now, uw_map->checked) > uw_map->reload)) { struct stat statbuf; uw_map->checked = now; if ((rc = jk_stat(uw_map->fname, &statbuf)) == -1) { jk_log(l, JK_LOG_ERROR, "Unable to stat the %s (errno=%d)", uw_map->fname, errno); return JK_FALSE; } if (statbuf.st_mtime == uw_map->modified) { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "File %s is not modified", uw_map->fname); return JK_TRUE; } JK_ENTER_CS(&uw_map->cs); /* Check if some other thread updated status */ if (statbuf.st_mtime == uw_map->modified) { JK_LEAVE_CS(&uw_map->cs); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "File %s is not modified", uw_map->fname); return JK_TRUE; } rc = uri_worker_map_load(uw_map, l); uri_worker_map_ext(uw_map, l); uri_worker_map_switch(uw_map, l); JK_LEAVE_CS(&uw_map->cs); jk_log(l, JK_LOG_INFO, "Reloaded urimaps from %s", uw_map->fname); } return JK_TRUE; } tomcat-connectors-1.2.41-src/native/common/jk_util.c0000644000000000000020000017430712465671172020725 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Utility functions (mainly configuration) * * Author: Gal Shachor * * Author: Henri Gomez * * Author: Rainer Jung * * Version: $Revision: 1658173 $ * ***************************************************************************/ #include "jk_util.h" #include "jk_ajp12_worker.h" #include "jk_ajp13_worker.h" #include "jk_ajp14_worker.h" #include "jk_lb_worker.h" #include "jk_mt.h" #define SYSPROPS_OF_WORKER "sysprops" #define STDERR_OF_WORKER "stderr" #define STDOUT_OF_WORKER "stdout" #define SECRET_OF_WORKER "secret" #define MX_OF_WORKER "mx" #define MS_OF_WORKER "ms" #define CP_OF_WORKER "class_path" #define BRIDGE_OF_WORKER "bridge" #define JVM_OF_WORKER "jvm_lib" #define LIBPATH_OF_WORKER "ld_path" #define CMD_LINE_OF_WORKER "cmd_line" #define NATIVE_LIB_OF_WORKER "native_lib" #define REFERENCE_OF_WORKER "reference" #define HOST_OF_WORKER "host" #define SOURCE_OF_WORKER "source" #define PORT_OF_WORKER "port" #define TYPE_OF_WORKER "type" #define CACHE_OF_WORKER_DEPRECATED "cachesize" #define CACHE_OF_WORKER "connection_pool_size" #define CACHE_OF_WORKER_MIN "connection_pool_minsize" #define CACHE_TIMEOUT_DEPRECATED "cache_timeout" #define CACHE_TIMEOUT_OF_WORKER "connection_pool_timeout" #define CACHE_ACQUIRE_OF_WORKER "connection_acquire_timeout" #define RECOVERY_OPTS_OF_WORKER "recovery_options" #define CONNECT_TIMEOUT_OF_WORKER "connect_timeout" #define PREPOST_TIMEOUT_OF_WORKER "prepost_timeout" #define REPLY_TIMEOUT_OF_WORKER "reply_timeout" #define SOCKET_TIMEOUT_OF_WORKER "socket_timeout" #define SOCKET_CONNECT_TIMEOUT_OF_WORKER "socket_connect_timeout" #define PING_TIMEOUT_OF_WORKER "ping_timeout" #define PING_MODE_OF_WORKER "ping_mode" #define SOCKET_BUFFER_OF_WORKER "socket_buffer" #define SOCKET_KEEPALIVE_OF_WORKER "socket_keepalive" #define CONN_PING_INTERVAL_OF_WORKER "connection_ping_interval" #define RECYCLE_TIMEOUT_DEPRECATED "recycle_timeout" #define LOAD_FACTOR_OF_WORKER "lbfactor" #define DISTANCE_OF_WORKER "distance" #define BALANCED_WORKERS_DEPRECATED "balanced_workers" #define BALANCE_WORKERS "balance_workers" #define STICKY_SESSION "sticky_session" #define STICKY_SESSION_FORCE "sticky_session_force" #define SESSION_COOKIE_OF_WORKER "session_cookie" #define SESSION_PATH_OF_WORKER "session_path" #define SET_SESSION_COOKIE "set_session_cookie" #define SESSION_COOKIE_PATH_OF_WORKER "session_cookie_path" #define LOCAL_WORKER_DEPRECATED "local_worker" #define LOCAL_WORKER_ONLY_DEPRECATED "local_worker_only" #define JVM_ROUTE_OF_WORKER_DEPRECATED "jvm_route" #define ROUTE_OF_WORKER "route" #define DOMAIN_OF_WORKER "domain" #define REDIRECT_OF_WORKER "redirect" #define MOUNT_OF_WORKER "mount" #define METHOD_OF_WORKER "method" #define LOCK_OF_WORKER "lock" #define IS_WORKER_DISABLED_DEPRECATED "disabled" #define IS_WORKER_STOPPED_DEPRECATED "stopped" #define ACTIVATION_OF_WORKER "activation" #define WORKER_RECOVER_TIME "recover_time" #define WORKER_ERROR_ESCALATION_TIME "error_escalation_time" #define MAX_REPLY_TIMEOUTS_OF_WORKER "max_reply_timeouts" #define RETRY_INTERVAL_OF_WORKER "retry_interval" #define BUSY_LIMIT_OF_WORKER "busy_limit" #define WORKER_MAX_PACKET_SIZE "max_packet_size" #define STYLE_SHEET_OF_WORKER "css" #define NAMESPACE_OF_WORKER "ns" #define XML_NAMESPACE_OF_WORKER "xmlns" #define XML_DOCTYPE_OF_WORKER "doctype" #define PROP_PREFIX_OF_WORKER "prefix" #define READ_ONLY_OF_WORKER "read_only" #define USER_OF_WORKER "user" #define USER_CASE_OF_WORKER "user_case_insensitive" #define GOOD_RATING_OF_WORKER "good" #define BAD_RATING_OF_WORKER "bad" #define PREFER_IPV6_ADDRESS "prefer_ipv6" #define DEFAULT_WORKER_TYPE JK_AJP13_WORKER_NAME #define SECRET_KEY_OF_WORKER "secretkey" #define RETRIES_OF_WORKER "retries" #define STATUS_FAIL_OF_WORKER "fail_on_status" #define DEFAULT_WORKER JK_AJP13_WORKER_NAME #define WORKER_LIST_PROPERTY_NAME "worker.list" #define LIST_PROPERTY_NAME "list" #define WORKER_MAINTAIN_PROPERTY_NAME "worker.maintain" #define MAINTAIN_PROPERTY_NAME "maintain" #define DEFAULT_MAINTAIN_TIME 60 #define DEFAULT_LB_FACTOR 1 #define DEFAULT_DISTANCE 0 #define TOMCAT32_BRIDGE_NAME "tomcat32" #define TOMCAT33_BRIDGE_NAME "tomcat33" #define TOMCAT40_BRIDGE_NAME "tomcat40" #define TOMCAT41_BRIDGE_NAME "tomcat41" #define TOMCAT50_BRIDGE_NAME "tomcat5" #define LOG_BUFFER_SIZE 1024 /* * Our longest worker attribute name is below 30 bytes. * Add space for "worker.", another ".", the * worker name and the final '\0'. */ #define JK_MAX_ATTRIBUTE_NAME_LEN (30) #define PARAM_BUFFER_SIZE (JK_MAX_NAME_LEN + 8 + JK_MAX_ATTRIBUTE_NAME_LEN + 1) #define MAKE_WORKER_PARAM(P) \ { \ size_t remain = PARAM_BUFFER_SIZE; \ strcpy(buf, "worker."); remain -= strlen("worker."); \ strncat(buf, wname, remain); remain -= strlen(wname); \ strncat(buf, ".", remain); remain -= 1; \ strncat(buf, P, remain); \ } /* * define the log format, we're using by default the one from error.log * * [Mon Mar 26 19:44:48.123 2001] [jk_uri_worker_map.c (155)]: Into jk_uri_worker_map_t::uri_worker_map_alloc * log format used by apache in error.log */ #define JK_TIME_CONV_MILLI "%Q" #define JK_TIME_CONV_MICRO "%q" #define JK_TIME_PATTERN_MILLI "000" #define JK_TIME_PATTERN_MICRO "000000" #define JK_TIME_FORMAT_NONE "[%a %b %d %H:%M:%S %Y] " #define JK_TIME_FORMAT_MILLI "[%a %b %d %H:%M:%S." JK_TIME_CONV_MILLI " %Y] " #define JK_TIME_FORMAT_MICRO "[%a %b %d %H:%M:%S." JK_TIME_CONV_MICRO " %Y] " #define JK_TIME_SUBSEC_NONE 0 #define JK_TIME_SUBSEC_MILLI 1 #define JK_TIME_SUBSEC_MICRO 2 /* Visual C++ Toolkit 2003 support */ #if defined (_MSC_VER) && (_MSC_VER == 1310) extern long _ftol(double); /* defined by VC6 C libs */ extern long _ftol2(double dblSource) { return _ftol(dblSource); } #endif static const char *list_properties[] = { BALANCE_WORKERS, MOUNT_OF_WORKER, USER_OF_WORKER, GOOD_RATING_OF_WORKER, BAD_RATING_OF_WORKER, STATUS_FAIL_OF_WORKER, LIST_PROPERTY_NAME, NULL }; static const char *unique_properties[] = { SECRET_OF_WORKER, REFERENCE_OF_WORKER, HOST_OF_WORKER, SOURCE_OF_WORKER, PORT_OF_WORKER, TYPE_OF_WORKER, CACHE_OF_WORKER_DEPRECATED, CACHE_OF_WORKER, CACHE_OF_WORKER_MIN, CACHE_TIMEOUT_DEPRECATED, CACHE_TIMEOUT_OF_WORKER, CACHE_ACQUIRE_OF_WORKER, RECOVERY_OPTS_OF_WORKER, CONNECT_TIMEOUT_OF_WORKER, PREPOST_TIMEOUT_OF_WORKER, PING_TIMEOUT_OF_WORKER, PING_MODE_OF_WORKER, REPLY_TIMEOUT_OF_WORKER, SOCKET_TIMEOUT_OF_WORKER, SOCKET_CONNECT_TIMEOUT_OF_WORKER, SOCKET_BUFFER_OF_WORKER, SOCKET_KEEPALIVE_OF_WORKER, CONN_PING_INTERVAL_OF_WORKER, RECYCLE_TIMEOUT_DEPRECATED, LOAD_FACTOR_OF_WORKER, STICKY_SESSION, STICKY_SESSION_FORCE, SESSION_COOKIE_OF_WORKER, SESSION_PATH_OF_WORKER, SET_SESSION_COOKIE, SESSION_COOKIE_PATH_OF_WORKER, LOCAL_WORKER_DEPRECATED, LOCAL_WORKER_ONLY_DEPRECATED, JVM_ROUTE_OF_WORKER_DEPRECATED, ROUTE_OF_WORKER, DOMAIN_OF_WORKER, REDIRECT_OF_WORKER, METHOD_OF_WORKER, LOCK_OF_WORKER, IS_WORKER_DISABLED_DEPRECATED, IS_WORKER_STOPPED_DEPRECATED, ACTIVATION_OF_WORKER, WORKER_RECOVER_TIME, WORKER_ERROR_ESCALATION_TIME, MAX_REPLY_TIMEOUTS_OF_WORKER, RETRY_INTERVAL_OF_WORKER, BUSY_LIMIT_OF_WORKER, WORKER_MAX_PACKET_SIZE, STYLE_SHEET_OF_WORKER, READ_ONLY_OF_WORKER, RETRIES_OF_WORKER, WORKER_MAINTAIN_PROPERTY_NAME, NAMESPACE_OF_WORKER, XML_NAMESPACE_OF_WORKER, XML_DOCTYPE_OF_WORKER, PROP_PREFIX_OF_WORKER, USER_CASE_OF_WORKER, PREFER_IPV6_ADDRESS, NULL }; static const char *deprecated_properties[] = { SYSPROPS_OF_WORKER, STDERR_OF_WORKER, STDOUT_OF_WORKER, MX_OF_WORKER, MS_OF_WORKER, CP_OF_WORKER, BRIDGE_OF_WORKER, JVM_OF_WORKER, LIBPATH_OF_WORKER, CMD_LINE_OF_WORKER, NATIVE_LIB_OF_WORKER, CACHE_OF_WORKER_DEPRECATED, CACHE_TIMEOUT_DEPRECATED, RECYCLE_TIMEOUT_DEPRECATED, BALANCED_WORKERS_DEPRECATED, JVM_ROUTE_OF_WORKER_DEPRECATED, LOCAL_WORKER_DEPRECATED, LOCAL_WORKER_ONLY_DEPRECATED, IS_WORKER_DISABLED_DEPRECATED, IS_WORKER_STOPPED_DEPRECATED, NULL }; static const char *supported_properties[] = { SYSPROPS_OF_WORKER, STDERR_OF_WORKER, STDOUT_OF_WORKER, SECRET_OF_WORKER, MX_OF_WORKER, MS_OF_WORKER, CP_OF_WORKER, BRIDGE_OF_WORKER, JVM_OF_WORKER, LIBPATH_OF_WORKER, CMD_LINE_OF_WORKER, NATIVE_LIB_OF_WORKER, REFERENCE_OF_WORKER, HOST_OF_WORKER, SOURCE_OF_WORKER, PORT_OF_WORKER, TYPE_OF_WORKER, CACHE_OF_WORKER_DEPRECATED, CACHE_OF_WORKER, CACHE_OF_WORKER_MIN, CACHE_TIMEOUT_DEPRECATED, CACHE_TIMEOUT_OF_WORKER, CACHE_ACQUIRE_OF_WORKER, RECOVERY_OPTS_OF_WORKER, CONNECT_TIMEOUT_OF_WORKER, PREPOST_TIMEOUT_OF_WORKER, PING_TIMEOUT_OF_WORKER, PING_MODE_OF_WORKER, REPLY_TIMEOUT_OF_WORKER, SOCKET_TIMEOUT_OF_WORKER, SOCKET_CONNECT_TIMEOUT_OF_WORKER, SOCKET_BUFFER_OF_WORKER, SOCKET_KEEPALIVE_OF_WORKER, CONN_PING_INTERVAL_OF_WORKER, RECYCLE_TIMEOUT_DEPRECATED, LOAD_FACTOR_OF_WORKER, DISTANCE_OF_WORKER, BALANCED_WORKERS_DEPRECATED, BALANCE_WORKERS, STICKY_SESSION, STICKY_SESSION_FORCE, SESSION_COOKIE_OF_WORKER, SESSION_PATH_OF_WORKER, SET_SESSION_COOKIE, SESSION_COOKIE_PATH_OF_WORKER, LOCAL_WORKER_DEPRECATED, LOCAL_WORKER_ONLY_DEPRECATED, JVM_ROUTE_OF_WORKER_DEPRECATED, ROUTE_OF_WORKER, DOMAIN_OF_WORKER, REDIRECT_OF_WORKER, MOUNT_OF_WORKER, METHOD_OF_WORKER, LOCK_OF_WORKER, IS_WORKER_DISABLED_DEPRECATED, IS_WORKER_STOPPED_DEPRECATED, ACTIVATION_OF_WORKER, WORKER_RECOVER_TIME, WORKER_ERROR_ESCALATION_TIME, MAX_REPLY_TIMEOUTS_OF_WORKER, RETRY_INTERVAL_OF_WORKER, BUSY_LIMIT_OF_WORKER, WORKER_MAX_PACKET_SIZE, STYLE_SHEET_OF_WORKER, NAMESPACE_OF_WORKER, XML_NAMESPACE_OF_WORKER, XML_DOCTYPE_OF_WORKER, PROP_PREFIX_OF_WORKER, READ_ONLY_OF_WORKER, USER_OF_WORKER, USER_CASE_OF_WORKER, GOOD_RATING_OF_WORKER, BAD_RATING_OF_WORKER, SECRET_KEY_OF_WORKER, RETRIES_OF_WORKER, STATUS_FAIL_OF_WORKER, LIST_PROPERTY_NAME, MAINTAIN_PROPERTY_NAME, PREFER_IPV6_ADDRESS, NULL }; static const char *jk_level_verbs[] = { "[" JK_LOG_TRACE_VERB "] ", "[" JK_LOG_DEBUG_VERB "] ", "[" JK_LOG_INFO_VERB "] ", "[" JK_LOG_WARN_VERB "] ", "[" JK_LOG_ERROR_VERB "] ", "[" JK_LOG_EMERG_VERB "] ", NULL }; const char *jk_get_bool(int v) { if (v == 0) return "False"; else return "True"; } int jk_get_bool_code(const char *v, int def) { if (!v) { return def; } if (!strcasecmp(v, "off") || *v == 'F' || *v == 'f' || *v == 'N' || *v == 'n' || (*v == '0' && *(v + 1) == '\0')) { return JK_FALSE; } if (!strcasecmp(v, "on") || *v == 'T' || *v == 't' || *v == 'Y' || *v == 'y' || (*v == '1' && *(v + 1) == '\0')) { return JK_TRUE; } return def; } /* Sleep for 100ms */ void jk_sleep(int ms) { #ifdef OS2 DosSleep(ms); #elif defined(BEOS) snooze(ms * 1000); #elif defined(NETWARE) delay(ms); #elif defined(WIN32) Sleep(ms); #else struct timeval tv; tv.tv_usec = (ms % 1000) * 1000; tv.tv_sec = ms / 1000; select(0, NULL, NULL, NULL, &tv); #endif } /* Replace the first occurence of a sub second time format character * by a series of zero digits with the right precision. * We format our timestamp with strftime, but this can not handle * sub second timestamps. * So we first patch the milliseconds or microseconds literally into * the format string, and then pass it on the strftime. * In order to do that efficiently, we prepare a format string, that * already has placeholder digits for the sub second time stamp * and we save the position and time precision of this placeholder. */ void jk_set_time_fmt(jk_logger_t *l, const char *jk_log_fmt) { if (l) { char *s; if (!jk_log_fmt) { #ifndef NO_GETTIMEOFDAY jk_log_fmt = JK_TIME_FORMAT_MILLI; #else jk_log_fmt = JK_TIME_FORMAT_NONE; #endif } l->log_fmt_type = JK_TIME_SUBSEC_NONE; l->log_fmt_offset = 0; l->log_fmt_size = 0; l->log_fmt = jk_log_fmt; /* Look for the first occurence of JK_TIME_CONV_MILLI */ if ((s = strstr(jk_log_fmt, JK_TIME_CONV_MILLI))) { size_t offset = s - jk_log_fmt; size_t len = strlen(JK_TIME_PATTERN_MILLI); /* If we don't have enough space in our fixed-length char array, * we simply stick to the default format, ignoring JK_TIME_CONV_MILLI. * Otherwise we replace the first occurence of * JK_TIME_CONV_MILLI by JK_TIME_PATTERN_MILLI. */ if (offset + len < JK_TIME_MAX_SIZE) { l->log_fmt_type = JK_TIME_SUBSEC_MILLI; l->log_fmt_offset = offset; strncpy(l->log_fmt_subsec, jk_log_fmt, offset); strncpy(l->log_fmt_subsec + offset, JK_TIME_PATTERN_MILLI, len); strncpy(l->log_fmt_subsec + offset + len, s + strlen(JK_TIME_CONV_MILLI), JK_TIME_MAX_SIZE - offset - len - 1); /* Now we put a stop mark into the string to make it's length * at most JK_TIME_MAX_SIZE-1 plus terminating '\0'. */ l->log_fmt_subsec[JK_TIME_MAX_SIZE-1] = '\0'; l->log_fmt_size = strlen(l->log_fmt_subsec); } /* Look for the first occurence of JK_TIME_CONV_MICRO */ } else if ((s = strstr(jk_log_fmt, JK_TIME_CONV_MICRO))) { size_t offset = s - jk_log_fmt; size_t len = strlen(JK_TIME_PATTERN_MICRO); /* If we don't have enough space in our fixed-length char array, * we simply stick to the default format, ignoring JK_TIME_CONV_MICRO. * Otherwise we replace the first occurence of JK_TIME_CONV_MICRO * by JK_TIME_PATTERN_MICRO. */ if (offset + len < JK_TIME_MAX_SIZE) { l->log_fmt_type = JK_TIME_SUBSEC_MICRO; l->log_fmt_offset = offset; strncpy(l->log_fmt_subsec, jk_log_fmt, offset); strncpy(l->log_fmt_subsec + offset, JK_TIME_PATTERN_MICRO, len); strncpy(l->log_fmt_subsec + offset + len, s + strlen(JK_TIME_CONV_MICRO), JK_TIME_MAX_SIZE - offset - len - 1); /* Now we put a stop mark into the string to make it's length * at most JK_TIME_MAX_SIZE-1 plus terminating '\0'. */ l->log_fmt_subsec[JK_TIME_MAX_SIZE-1] = '\0'; l->log_fmt_size = strlen(l->log_fmt_subsec); } } jk_log(l, JK_LOG_DEBUG, "Pre-processed log time stamp format is '%s'", l->log_fmt_type == JK_TIME_SUBSEC_NONE ? l->log_fmt : l->log_fmt_subsec); } } static int set_time_str(char *str, int len, jk_logger_t *l) { time_t t; struct tm *tms; #ifdef _MT_CODE_PTHREAD struct tm res; #endif int done; /* We want to use a fixed maximum size buffer here. * If we would dynamically adjust it to the real format * string length, we could support longer format strings, * but we would have to allocate and free for each log line. */ char log_fmt[JK_TIME_MAX_SIZE]; if (!l || !l->log_fmt) { return 0; } log_fmt[0] = '\0'; #ifndef NO_GETTIMEOFDAY if ( l->log_fmt_type != JK_TIME_SUBSEC_NONE ) { struct timeval tv; int rc = 0; #ifdef WIN32 gettimeofday(&tv, NULL); #else rc = gettimeofday(&tv, NULL); #endif if (rc == 0) { /* We need this subsec buffer, because we convert * the integer with sprintf(), but we don't * want to write the terminating '\0' into our * final log format string. */ char subsec[7]; t = tv.tv_sec; strncpy(log_fmt, l->log_fmt_subsec, l->log_fmt_size + 1); if (l->log_fmt_type == JK_TIME_SUBSEC_MILLI) { sprintf(subsec, "%03d", (int)(tv.tv_usec/1000)); strncpy(log_fmt + l->log_fmt_offset, subsec, 3); } else if (l->log_fmt_type == JK_TIME_SUBSEC_MICRO) { sprintf(subsec, "%06d", (int)(tv.tv_usec)); strncpy(log_fmt + l->log_fmt_offset, subsec, 6); } } else { t = time(NULL); } } else { t = time(NULL); } #else t = time(NULL); #endif #ifdef _MT_CODE_PTHREAD tms = localtime_r(&t, &res); #else tms = localtime(&t); #endif if (log_fmt[0]) done = (int)strftime(str, len, log_fmt, tms); else done = (int)strftime(str, len, l->log_fmt, tms); return done; } static int JK_METHOD log_to_file(jk_logger_t *l, int level, int used, char *what) { if (l && (l->level <= level || level == JK_LOG_REQUEST_LEVEL) && l->logger_private && what) { jk_file_logger_t *p = l->logger_private; if (p->logfile) { what[used++] = '\n'; what[used] = '\0'; #if defined(JK_LOG_LOCKING) #if defined(WIN32) && defined(_MSC_VER) LockFile((HANDLE)_get_osfhandle(_fileno(p->logfile)), 0, 0, 1, 0); #endif #endif fputs(what, p->logfile); /* [V] Flush the dam' thing! */ fflush(p->logfile); #if defined(JK_LOG_LOCKING) #if defined(WIN32) && defined(_MSC_VER) UnlockFile((HANDLE)_get_osfhandle(_fileno(p->logfile)), 0, 0, 1, 0); #endif #endif } return JK_TRUE; } return JK_FALSE; } int jk_parse_log_level(const char *level) { if (!strcasecmp(level, JK_LOG_TRACE_VERB)) return JK_LOG_TRACE_LEVEL; if (!strcasecmp(level, JK_LOG_DEBUG_VERB)) return JK_LOG_DEBUG_LEVEL; if (!strcasecmp(level, JK_LOG_INFO_VERB)) return JK_LOG_INFO_LEVEL; if (!strcasecmp(level, JK_LOG_WARN_VERB)) return JK_LOG_WARNING_LEVEL; if (!strcasecmp(level, JK_LOG_ERROR_VERB)) return JK_LOG_ERROR_LEVEL; if (!strcasecmp(level, JK_LOG_EMERG_VERB)) return JK_LOG_EMERG_LEVEL; return JK_LOG_DEF_LEVEL; } int jk_open_file_logger(jk_logger_t **l, const char *file, int level) { if (l && file) { jk_logger_t *rc = (jk_logger_t *)malloc(sizeof(jk_logger_t)); jk_file_logger_t *p = (jk_file_logger_t *) malloc(sizeof(jk_file_logger_t)); if (rc && p) { rc->log = log_to_file; rc->level = level; rc->logger_private = p; #if defined(AS400) && !defined(AS400_UTF8) p->logfile = fopen(file, "a+, o_ccsid=0"); #elif defined(WIN32) && defined(_MSC_VER) p->logfile = fopen(file, "a+c"); #else p->logfile = fopen(file, "a+"); #endif if (p->logfile) { *l = rc; jk_set_time_fmt(rc, NULL); return JK_TRUE; } } if (rc) { free(rc); } if (p) { free(p); } *l = NULL; } return JK_FALSE; } int jk_attach_file_logger(jk_logger_t **l, int fd, int level) { if (l && fd >= 0) { jk_logger_t *rc = (jk_logger_t *)malloc(sizeof(jk_logger_t)); jk_file_logger_t *p = (jk_file_logger_t *) malloc(sizeof(jk_file_logger_t)); if (rc && p) { rc->log = log_to_file; rc->level = level; rc->logger_private = p; #if defined(AS400) && !defined(AS400_UTF8) p->logfile = fdopen(fd, "a+, o_ccsid=0"); #elif defined(WIN32) && defined(_MSC_VER) p->logfile = fdopen(fd, "a+c"); #else p->logfile = fdopen(fd, "a+"); #endif if (p->logfile) { *l = rc; jk_set_time_fmt(rc, NULL); return JK_TRUE; } } if (rc) { free(rc); } if (p) { free(p); } *l = NULL; } return JK_FALSE; } int jk_close_file_logger(jk_logger_t **l) { if (l && *l) { jk_file_logger_t *p = (*l)->logger_private; if (p) { fflush(p->logfile); fclose(p->logfile); free(p); } free(*l); *l = NULL; return JK_TRUE; } return JK_FALSE; } int jk_log(jk_logger_t *l, const char *file, int line, const char *funcname, int level, const char *fmt, ...) { int rc = 0; /* * Need to reserve space for terminating zero byte * and platform specific line endings added during the call * to the output routing. */ static int usable_size = LOG_BUFFER_SIZE - 3; if (!l || !file || !fmt) { return -1; } if ((l->level <= level) || (level == JK_LOG_REQUEST_LEVEL)) { #ifdef NETWARE /* On NetWare, this can get called on a thread that has a limited stack so */ /* we will allocate and free the temporary buffer in this function */ char *buf; #else char buf[LOG_BUFFER_SIZE]; #endif char *f = (char *)(file + strlen(file) - 1); va_list args; int used = 0; while (f != file && '\\' != *f && '/' != *f) { f--; } if (f != file) { f++; } #ifdef NETWARE buf = (char *)malloc(LOG_BUFFER_SIZE); if (NULL == buf) return -1; #endif used = set_time_str(buf, usable_size, l); if (line) { /* line==0 only used for request log item */ /* Log [pid:threadid] for all levels except REQUEST. * This information helps to correlate lines from different logs. * Performance is no issue, because with production log levels * we only call it often, if we have a lot of errors */ rc = snprintf(buf + used, usable_size - used, "[%" JK_PID_T_FMT ":%" JK_PTHREAD_T_FMT "] ", getpid(), jk_gettid()); used += rc; if (rc < 0 ) { strcpy(buf, "Logging failed in pid/tid formatting"); l->log(l, level, strlen(buf), buf); return 0; } rc = (int)strlen(jk_level_verbs[level]); if (usable_size - used >= rc) { strncpy(buf + used, jk_level_verbs[level], rc); used += rc; } else { strcpy(buf, "Logging failed in log level formatting"); l->log(l, level, strlen(buf), buf); return 0; /* [V] not sure what to return... */ } if (funcname) { rc = (int)strlen(funcname); if (usable_size - used >= rc + 2) { strncpy(buf + used, funcname, rc); used += rc; strncpy(buf + used, "::", 2); used += 2; } else { strcpy(buf, "Logging failed in function name formatting"); l->log(l, level, strlen(buf), buf); return 0; /* [V] not sure what to return... */ } } rc = (int)strlen(f); if (usable_size - used >= rc) { strncpy(buf + used, f, rc); used += rc; } else { strcpy(buf, "Logging failed in source file name formatting"); l->log(l, level, strlen(buf), buf); return 0; /* [V] not sure what to return... */ } rc = snprintf(buf + used, usable_size - used, " (%d): ", line); used += rc; if (rc < 0 || usable_size - used < 0) { strcpy(buf, "Logging failed in line number formatting"); l->log(l, level, strlen(buf), buf); return 0; /* [V] not sure what to return... */ } } va_start(args, fmt); rc = vsnprintf(buf + used, usable_size - used, fmt, args); va_end(args); /* Depending on the snprintf implementation used, * "rc == usable_size - used" can indicate not enough space in buffer */ if (rc < usable_size - used) { used += rc; } else { used = usable_size; buf[used - 1] = '.'; buf[used - 2] = '.'; buf[used - 3] = '.'; } l->log(l, level, used, buf); #ifdef NETWARE free(buf); #endif } return rc; } int jk_check_attribute_length(const char *name, const char *value, jk_logger_t *l) { size_t len = strlen(value); if (len > JK_MAX_NAME_LEN) { jk_log(l, JK_LOG_ERROR, "Worker %s '%s' is %d bytes too long, " "a maximum of %d bytes is supported", name, value, len - JK_MAX_NAME_LEN, JK_MAX_NAME_LEN); return JK_FALSE; } return JK_TRUE; } const char *jk_get_worker_type(jk_map_t *m, const char *wname) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return NULL; } MAKE_WORKER_PARAM(TYPE_OF_WORKER); return jk_map_get_string(m, buf, DEFAULT_WORKER_TYPE); } const char *jk_get_worker_route(jk_map_t *m, const char *wname, const char *def) { char buf[PARAM_BUFFER_SIZE]; const char *v; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(ROUTE_OF_WORKER); v = jk_map_get_string(m, buf, def); if (v) { return v; } /* Try old jvm_route directive */ MAKE_WORKER_PARAM(JVM_ROUTE_OF_WORKER_DEPRECATED); return jk_map_get_string(m, buf, def); } const char *jk_get_worker_domain(jk_map_t *m, const char *wname, const char *def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(DOMAIN_OF_WORKER); return jk_map_get_string(m, buf, def); } const char *jk_get_worker_redirect(jk_map_t *m, const char *wname, const char *def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(REDIRECT_OF_WORKER); return jk_map_get_string(m, buf, def); } const char *jk_get_worker_secret(jk_map_t *m, const char *wname) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return NULL; } MAKE_WORKER_PARAM(SECRET_OF_WORKER); return jk_map_get_string(m, buf, NULL); } const char *jk_get_worker_host(jk_map_t *m, const char *wname, const char *def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return NULL; } MAKE_WORKER_PARAM(HOST_OF_WORKER); return jk_map_get_string(m, buf, def); } const char *jk_get_worker_source(jk_map_t *m, const char *wname, const char *def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return NULL; } MAKE_WORKER_PARAM(SOURCE_OF_WORKER); return jk_map_get_string(m, buf, def); } int jk_get_worker_port(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(PORT_OF_WORKER); return jk_map_get_int(m, buf, def); } int jk_get_worker_prefer_ipv6(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(PREFER_IPV6_ADDRESS); return jk_map_get_bool(m, buf, def); } static int def_cache_size = -1; int jk_get_worker_def_cache_size(int protocol) { if (def_cache_size < 1) { if (protocol == AJP14_PROTO) def_cache_size = AJP14_DEF_CACHE_SZ; else def_cache_size = AJP13_DEF_CACHE_SZ; } return def_cache_size; } void jk_set_worker_def_cache_size(int sz) { def_cache_size = sz; } int jk_get_worker_cache_size(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; int rv; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(CACHE_OF_WORKER); if ((rv = jk_map_get_int(m, buf, -1)) >= 0) return rv; MAKE_WORKER_PARAM(CACHE_OF_WORKER_DEPRECATED); return jk_map_get_int(m, buf, def); } int jk_get_worker_cache_size_min(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(CACHE_OF_WORKER_MIN); return jk_map_get_int(m, buf, def); } int jk_get_worker_cache_acquire_timeout(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(CACHE_ACQUIRE_OF_WORKER); return jk_map_get_int(m, buf, def); } int jk_get_worker_socket_timeout(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(SOCKET_TIMEOUT_OF_WORKER); return jk_map_get_int(m, buf, def); } int jk_get_worker_socket_connect_timeout(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(SOCKET_CONNECT_TIMEOUT_OF_WORKER); return jk_map_get_int(m, buf, def); } int jk_get_worker_recover_timeout(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(WORKER_RECOVER_TIME); return jk_map_get_int(m, buf, def); } int jk_get_worker_error_escalation_time(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(WORKER_ERROR_ESCALATION_TIME); return jk_map_get_int(m, buf, def); } int jk_get_worker_max_reply_timeouts(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(MAX_REPLY_TIMEOUTS_OF_WORKER); return jk_map_get_int(m, buf, def); } int jk_get_worker_retry_interval(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(RETRY_INTERVAL_OF_WORKER); return jk_map_get_int(m, buf, def); } int jk_get_worker_busy_limit(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(BUSY_LIMIT_OF_WORKER); return jk_map_get_int(m, buf, def); } int jk_get_worker_socket_buffer(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; int i; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(SOCKET_BUFFER_OF_WORKER); i = jk_map_get_int(m, buf, 0); if (i > 0 && i < def) i = def; return i; } int jk_get_worker_socket_keepalive(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(SOCKET_KEEPALIVE_OF_WORKER); return jk_map_get_bool(m, buf, def); } int jk_get_worker_conn_ping_interval(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(CONN_PING_INTERVAL_OF_WORKER); return jk_map_get_int(m, buf, def); } int jk_get_worker_cache_timeout(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; int rv; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(CACHE_TIMEOUT_OF_WORKER); if ((rv = jk_map_get_int(m, buf, -1)) >= 0) return rv; MAKE_WORKER_PARAM(CACHE_TIMEOUT_DEPRECATED); return jk_map_get_int(m, buf, def); } int jk_get_worker_connect_timeout(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(CONNECT_TIMEOUT_OF_WORKER); return jk_map_get_int(m, buf, def); } int jk_get_worker_prepost_timeout(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(PREPOST_TIMEOUT_OF_WORKER); return jk_map_get_int(m, buf, def); } int jk_get_worker_ping_timeout(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(PING_TIMEOUT_OF_WORKER); return jk_map_get_int(m, buf, def); } int jk_get_worker_ping_mode(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; char mode[100]; const char *v; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(PING_MODE_OF_WORKER); jk_ajp_get_cping_text(def, mode); v = jk_map_get_string(m, buf, mode); return jk_ajp_get_cping_mode(v, def); } int jk_get_worker_reply_timeout(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(REPLY_TIMEOUT_OF_WORKER); return jk_map_get_int(m, buf, def); } int jk_get_worker_recycle_timeout(jk_map_t *m, const char *wname, int def) { return def; } int jk_get_worker_retries(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; int rv; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(RETRIES_OF_WORKER); rv = jk_map_get_int(m, buf, def); if (rv < 1) rv = 1; return rv; } int jk_get_worker_recovery_opts(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(RECOVERY_OPTS_OF_WORKER); return jk_map_get_int(m, buf, def); } const char *jk_get_worker_secret_key(jk_map_t *m, const char *wname) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return NULL; } MAKE_WORKER_PARAM(SECRET_KEY_OF_WORKER); return jk_map_get_string(m, buf, NULL); } int jk_get_worker_list(jk_map_t *m, char ***list, unsigned *num_of_workers) { if (m && list && num_of_workers) { char **ar = jk_map_get_string_list(m, WORKER_LIST_PROPERTY_NAME, num_of_workers, DEFAULT_WORKER); if (ar) { *list = ar; return JK_TRUE; } *list = NULL; *num_of_workers = 0; } return JK_FALSE; } int jk_get_is_worker_disabled(jk_map_t *m, const char *wname) { int def = JK_FALSE; char buf[PARAM_BUFFER_SIZE]; if (m && wname) { MAKE_WORKER_PARAM(IS_WORKER_DISABLED_DEPRECATED); return jk_map_get_bool(m, buf, def); } return JK_TRUE; } int jk_get_is_worker_stopped(jk_map_t *m, const char *wname) { int def = JK_FALSE; char buf[PARAM_BUFFER_SIZE]; if (m && wname) { MAKE_WORKER_PARAM(IS_WORKER_STOPPED_DEPRECATED); return jk_map_get_bool(m, buf, def); } return JK_TRUE; } int jk_get_worker_activation(jk_map_t *m, const char *wname) { char buf[PARAM_BUFFER_SIZE]; const char *v; if (!m || !wname) { return JK_LB_ACTIVATION_ACTIVE; } MAKE_WORKER_PARAM(ACTIVATION_OF_WORKER); v = jk_map_get_string(m, buf, NULL); if (v) return jk_lb_get_activation_code(v); if (jk_get_is_worker_stopped(m, wname)) return JK_LB_ACTIVATION_STOPPED; if (jk_get_is_worker_disabled(m, wname)) return JK_LB_ACTIVATION_DISABLED; return JK_LB_ACTIVATION_DEF; } int jk_get_lb_factor(jk_map_t *m, const char *wname) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return DEFAULT_LB_FACTOR; } MAKE_WORKER_PARAM(LOAD_FACTOR_OF_WORKER); return jk_map_get_int(m, buf, DEFAULT_LB_FACTOR); } int jk_get_distance(jk_map_t *m, const char *wname) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return DEFAULT_DISTANCE; } MAKE_WORKER_PARAM(DISTANCE_OF_WORKER); return jk_map_get_int(m, buf, DEFAULT_DISTANCE); } int jk_get_is_sticky_session(jk_map_t *m, const char *wname) { int def = JK_TRUE; char buf[PARAM_BUFFER_SIZE]; if (m && wname) { MAKE_WORKER_PARAM(STICKY_SESSION); return jk_map_get_bool(m, buf, def); } return def; } int jk_get_is_sticky_session_force(jk_map_t *m, const char *wname) { int def = JK_FALSE; char buf[PARAM_BUFFER_SIZE]; if (m && wname) { MAKE_WORKER_PARAM(STICKY_SESSION_FORCE); return jk_map_get_bool(m, buf, def); } return def; } int jk_get_lb_method(jk_map_t *m, const char *wname) { char buf[PARAM_BUFFER_SIZE]; const char *v; if (!m || !wname) { return JK_LB_METHOD_DEF; } MAKE_WORKER_PARAM(METHOD_OF_WORKER); v = jk_map_get_string(m, buf, JK_LB_METHOD_DEF); return jk_lb_get_method_code(v); } int jk_get_lb_lock(jk_map_t *m, const char *wname) { char buf[PARAM_BUFFER_SIZE]; const char *v; if (!m || !wname) { return JK_LB_LOCK_DEF; } MAKE_WORKER_PARAM(LOCK_OF_WORKER); v = jk_map_get_string(m, buf, JK_LB_LOCK_DEF); return jk_lb_get_lock_code(v); } int jk_get_max_packet_size(jk_map_t *m, const char *wname) { char buf[PARAM_BUFFER_SIZE]; int sz; if (!m || !wname) { return AJP13_DEF_PACKET_SIZE; } MAKE_WORKER_PARAM(WORKER_MAX_PACKET_SIZE); sz = jk_map_get_int(m, buf, AJP13_DEF_PACKET_SIZE); sz = JK_ALIGN(sz, AJP13_PACKET_SIZE_ALIGN); if (sz < AJP13_DEF_PACKET_SIZE) sz = AJP13_DEF_PACKET_SIZE; else if (sz > AJP13_MAX_PACKET_SIZE) sz = AJP13_MAX_PACKET_SIZE; return sz; } int jk_get_worker_fail_on_status(jk_map_t *m, const char *wname, int **list, unsigned int *list_size) { char buf[PARAM_BUFFER_SIZE]; int *ar; if (!m || !wname || !list || !list_size) { return 0; } MAKE_WORKER_PARAM(STATUS_FAIL_OF_WORKER); ar = jk_map_get_int_list(m, buf, list_size, NULL); if (ar) { *list = ar; return JK_TRUE; } *list = NULL; *list_size = 0; return JK_FALSE; } int jk_get_worker_user_case_insensitive(jk_map_t *m, const char *wname) { int def = JK_FALSE; char buf[PARAM_BUFFER_SIZE]; if (m && wname) { MAKE_WORKER_PARAM(USER_CASE_OF_WORKER); return jk_map_get_bool(m, buf, def); } return def; } const char *jk_get_worker_style_sheet(jk_map_t *m, const char *wname, const char *def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(STYLE_SHEET_OF_WORKER); return jk_map_get_string(m, buf, def); } const char *jk_get_worker_name_space(jk_map_t *m, const char *wname, const char *def) { const char *rc; char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(NAMESPACE_OF_WORKER); rc = jk_map_get_string(m, buf, def); if (*rc == '-') return ""; else return rc; } const char *jk_get_worker_xmlns(jk_map_t *m, const char *wname, const char *def) { const char *rc; char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(XML_NAMESPACE_OF_WORKER); rc = jk_map_get_string(m, buf, def); if (*rc == '-') return ""; else return rc; } const char *jk_get_worker_xml_doctype(jk_map_t *m, const char *wname, const char *def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(XML_DOCTYPE_OF_WORKER); return jk_map_get_string(m, buf, def); } const char *jk_get_worker_prop_prefix(jk_map_t *m, const char *wname, const char *def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return def; } MAKE_WORKER_PARAM(PROP_PREFIX_OF_WORKER); return jk_map_get_string(m, buf, def); } int jk_get_is_read_only(jk_map_t *m, const char *wname) { int def = JK_FALSE; char buf[PARAM_BUFFER_SIZE]; if (m && wname) { MAKE_WORKER_PARAM(READ_ONLY_OF_WORKER); return jk_map_get_bool(m, buf, def); } return def; } int jk_get_worker_user_list(jk_map_t *m, const char *wname, char ***list, unsigned int *num) { char buf[PARAM_BUFFER_SIZE]; if (m && list && num && wname) { char **ar = NULL; MAKE_WORKER_PARAM(USER_OF_WORKER); ar = jk_map_get_string_list(m, buf, num, NULL); if (ar) { *list = ar; return JK_TRUE; } *list = NULL; *num = 0; } return JK_FALSE; } int jk_get_worker_good_rating(jk_map_t *m, const char *wname, char ***list, unsigned int *num) { char buf[PARAM_BUFFER_SIZE]; if (m && list && num && wname) { char **ar = NULL; MAKE_WORKER_PARAM(GOOD_RATING_OF_WORKER); ar = jk_map_get_string_list(m, buf, num, NULL); if (ar) { *list = ar; return JK_TRUE; } *list = NULL; *num = 0; } return JK_FALSE; } int jk_get_worker_bad_rating(jk_map_t *m, const char *wname, char ***list, unsigned int *num) { char buf[PARAM_BUFFER_SIZE]; if (m && list && num && wname) { char **ar = NULL; MAKE_WORKER_PARAM(BAD_RATING_OF_WORKER); ar = jk_map_get_string_list(m, buf, num, NULL); if (ar) { *list = ar; return JK_TRUE; } *list = NULL; *num = 0; } return JK_FALSE; } int jk_get_lb_worker_list(jk_map_t *m, const char *wname, char ***list, unsigned int *num_of_workers) { char buf[PARAM_BUFFER_SIZE]; if (m && list && num_of_workers && wname) { char **ar = NULL; MAKE_WORKER_PARAM(BALANCE_WORKERS); ar = jk_map_get_string_list(m, buf, num_of_workers, NULL); if (ar) { *list = ar; return JK_TRUE; } /* Try old balanced_workers directive */ MAKE_WORKER_PARAM(BALANCED_WORKERS_DEPRECATED); ar = jk_map_get_string_list(m, buf, num_of_workers, NULL); if (ar) { *list = ar; return JK_TRUE; } *list = NULL; *num_of_workers = 0; } return JK_FALSE; } int jk_get_worker_mount_list(jk_map_t *m, const char *wname, char ***list, unsigned int *num_of_maps) { char buf[PARAM_BUFFER_SIZE]; if (m && list && num_of_maps && wname) { char **ar = NULL; MAKE_WORKER_PARAM(MOUNT_OF_WORKER); ar = jk_map_get_string_list(m, buf, num_of_maps, NULL); if (ar) { *list = ar; return JK_TRUE; } *list = NULL; *num_of_maps = 0; } return JK_FALSE; } int jk_get_worker_maintain_time(jk_map_t *m) { return jk_map_get_int(m, WORKER_MAINTAIN_PROPERTY_NAME, DEFAULT_MAINTAIN_TIME); } int jk_get_worker_mx(jk_map_t *m, const char *wname, unsigned *mx) { char buf[PARAM_BUFFER_SIZE]; if (m && mx && wname) { int i; MAKE_WORKER_PARAM(MX_OF_WORKER); i = jk_map_get_int(m, buf, -1); if (-1 != i) { *mx = (unsigned)i; return JK_TRUE; } } return JK_FALSE; } int jk_get_worker_ms(jk_map_t *m, const char *wname, unsigned *ms) { char buf[PARAM_BUFFER_SIZE]; if (m && ms && wname) { int i; MAKE_WORKER_PARAM(MS_OF_WORKER); i = jk_map_get_int(m, buf, -1); if (-1 != i) { *ms = (unsigned)i; return JK_TRUE; } } return JK_FALSE; } int jk_get_worker_classpath(jk_map_t *m, const char *wname, const char **cp) { char buf[PARAM_BUFFER_SIZE]; if (m && cp && wname) { MAKE_WORKER_PARAM(CP_OF_WORKER); *cp = jk_map_get_string(m, buf, NULL); if (*cp) { return JK_TRUE; } } return JK_FALSE; } int jk_get_worker_bridge_type(jk_map_t *m, const char *wname, unsigned *bt) { char buf[PARAM_BUFFER_SIZE]; const char *type; if (m && bt && wname) { MAKE_WORKER_PARAM(BRIDGE_OF_WORKER); type = jk_map_get_string(m, buf, NULL); if (type) { if (!strcasecmp(type, TOMCAT32_BRIDGE_NAME)) *bt = TC32_BRIDGE_TYPE; else if (!strcasecmp(type, TOMCAT33_BRIDGE_NAME)) *bt = TC33_BRIDGE_TYPE; else if (!strcasecmp(type, TOMCAT40_BRIDGE_NAME)) *bt = TC40_BRIDGE_TYPE; else if (!strcasecmp(type, TOMCAT41_BRIDGE_NAME)) *bt = TC41_BRIDGE_TYPE; else if (!strcasecmp(type, TOMCAT50_BRIDGE_NAME)) *bt = TC50_BRIDGE_TYPE; return JK_TRUE; } } return JK_FALSE; } int jk_get_worker_jvm_path(jk_map_t *m, const char *wname, const char **vm_path) { char buf[PARAM_BUFFER_SIZE]; if (m && vm_path && wname) { MAKE_WORKER_PARAM(JVM_OF_WORKER); *vm_path = jk_map_get_string(m, buf, NULL); if (*vm_path) { return JK_TRUE; } } return JK_FALSE; } /* [V] This is unused. currently. */ int jk_get_worker_callback_dll(jk_map_t *m, const char *wname, const char **cb_path) { char buf[PARAM_BUFFER_SIZE]; if (m && cb_path && wname) { MAKE_WORKER_PARAM(NATIVE_LIB_OF_WORKER); *cb_path = jk_map_get_string(m, buf, NULL); if (*cb_path) { return JK_TRUE; } } return JK_FALSE; } int jk_get_worker_cmd_line(jk_map_t *m, const char *wname, const char **cmd_line) { char buf[PARAM_BUFFER_SIZE]; if (m && cmd_line && wname) { MAKE_WORKER_PARAM(CMD_LINE_OF_WORKER); *cmd_line = jk_map_get_string(m, buf, NULL); if (*cmd_line) { return JK_TRUE; } } return JK_FALSE; } int jk_stat(const char *f, struct stat * statbuf) { int rc; /** * i5/OS V5R4 expect filename in ASCII for fopen but required them in EBCDIC for stat() */ #ifdef AS400_UTF8 char *ptr; ptr = (char *)malloc(strlen(f) + 1); jk_ascii2ebcdic((char *)f, ptr); rc = stat(ptr, statbuf); free(ptr); #else rc = stat(f, statbuf); #endif return (rc); } int jk_file_exists(const char *f) { if (f) { struct stat st; if ((0 == jk_stat(f, &st)) && (st.st_mode & S_IFREG)) return JK_TRUE; } return JK_FALSE; } static int jk_is_some_property(const char *prp_name, const char *suffix, const char *sep) { if (prp_name && suffix && sep) { size_t prp_name_len = strlen(prp_name); size_t suffix_len = strlen(suffix); size_t sep_len = strlen(sep); size_t sep_off = sep_len + suffix_len; if (prp_name_len >= sep_off) { if (!strncmp(prp_name + prp_name_len - sep_off, sep, sep_len) && !strncmp(prp_name + prp_name_len - suffix_len, suffix, suffix_len)) { return JK_TRUE; } } } return JK_FALSE; } int jk_is_path_property(const char *prp_name) { return jk_is_some_property(prp_name, "path", "_"); } int jk_is_cmd_line_property(const char *prp_name) { return jk_is_some_property(prp_name, CMD_LINE_OF_WORKER, "."); } int jk_is_list_property(const char *prp_name) { const char **props = &list_properties[0]; while (*props) { if (jk_is_some_property(prp_name, *props, ".")) return JK_TRUE; props++; } return JK_FALSE; } int jk_is_unique_property(const char *prp_name) { const char **props = &unique_properties[0]; while (*props) { if (jk_is_some_property(prp_name, *props, ".")) return JK_TRUE; props++; } return JK_FALSE; } int jk_is_deprecated_property(const char *prp_name) { const char **props = &deprecated_properties[0]; while (*props) { if (jk_is_some_property(prp_name, *props, ".")) return JK_TRUE; props++; } return JK_FALSE; } int jk_check_buffer_size() { const char **props; size_t len = 0; size_t max_len = 0; props = &supported_properties[0]; while (*props) { len = strlen(*props); if (len > max_len) max_len = len; props++; } return JK_MAX_ATTRIBUTE_NAME_LEN - max_len; } /* * Check that property is a valid one (to prevent user typos). * Only property starting with worker. */ int jk_is_valid_property(const char *prp_name) { const char **props; /* Any property not starting with "worker." is "valid". * It is interpreted as the definition of a custom variable. */ if (memcmp(prp_name, "worker.", 7)) return JK_TRUE; props = &supported_properties[0]; while (*props) { if (jk_is_some_property(prp_name, *props, ".")) return JK_TRUE; props++; } return JK_FALSE; } int jk_get_worker_stdout(jk_map_t *m, const char *wname, const char **stdout_name) { char buf[PARAM_BUFFER_SIZE]; if (m && stdout_name && wname) { MAKE_WORKER_PARAM(STDOUT_OF_WORKER); *stdout_name = jk_map_get_string(m, buf, NULL); if (*stdout_name) { return JK_TRUE; } } return JK_FALSE; } int jk_get_worker_stderr(jk_map_t *m, const char *wname, const char **stderr_name) { char buf[PARAM_BUFFER_SIZE]; if (m && stderr_name && wname) { MAKE_WORKER_PARAM(STDERR_OF_WORKER); *stderr_name = jk_map_get_string(m, buf, NULL); if (*stderr_name) { return JK_TRUE; } } return JK_FALSE; } int jk_get_worker_sysprops(jk_map_t *m, const char *wname, const char **sysprops) { char buf[PARAM_BUFFER_SIZE]; if (m && sysprops && wname) { MAKE_WORKER_PARAM(SYSPROPS_OF_WORKER); *sysprops = jk_map_get_string(m, buf, NULL); if (*sysprops) { return JK_TRUE; } } return JK_FALSE; } int jk_get_worker_libpath(jk_map_t *m, const char *wname, const char **libpath) { char buf[PARAM_BUFFER_SIZE]; if (m && libpath && wname) { MAKE_WORKER_PARAM(LIBPATH_OF_WORKER); *libpath = jk_map_get_string(m, buf, NULL); if (*libpath) { return JK_TRUE; } } return JK_FALSE; } const char *jk_get_lb_session_cookie(jk_map_t *m, const char *wname, const char *def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return NULL; } MAKE_WORKER_PARAM(SESSION_COOKIE_OF_WORKER); return jk_map_get_string(m, buf, def); } const char *jk_get_lb_session_path(jk_map_t *m, const char *wname, const char *def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return NULL; } MAKE_WORKER_PARAM(SESSION_PATH_OF_WORKER); return jk_map_get_string(m, buf, def); } int jk_get_lb_set_session_cookie(jk_map_t *m, const char *wname, int def) { char buf[PARAM_BUFFER_SIZE]; if (m && wname) { MAKE_WORKER_PARAM(SET_SESSION_COOKIE); return jk_map_get_bool(m, buf, def); } return def; } const char *jk_get_lb_session_cookie_path(jk_map_t *m, const char *wname, const char *def) { char buf[PARAM_BUFFER_SIZE]; if (!m || !wname) { return NULL; } MAKE_WORKER_PARAM(SESSION_COOKIE_PATH_OF_WORKER); return jk_map_get_string(m, buf, def); } int is_http_status_fail(unsigned int http_status_fail_num, int *http_status_fail, int status) { unsigned int i; int soft_status = -1 * status; for (i = 0; i < http_status_fail_num; i++) { if (http_status_fail[i] == status) return 1; if (http_status_fail[i] == soft_status) return -1; } return 0; } char **jk_parse_sysprops(jk_pool_t *p, const char *sysprops) { char **rc = NULL; #ifdef _MT_CODE_PTHREAD char *lasts; #endif if (p && sysprops) { char *prps = jk_pool_strdup(p, sysprops); if (prps && strlen(prps)) { unsigned num_of_prps; for (num_of_prps = 1; *sysprops; sysprops++) { if ('*' == *sysprops) { num_of_prps++; } } rc = jk_pool_alloc(p, (num_of_prps + 1) * sizeof(char *)); if (rc) { unsigned i = 0; #ifdef _MT_CODE_PTHREAD char *tmp = strtok_r(prps, "*", &lasts); #else char *tmp = strtok(prps, "*"); #endif while (tmp && i < num_of_prps) { rc[i] = tmp; #ifdef _MT_CODE_PTHREAD tmp = strtok_r(NULL, "*", &lasts); #else tmp = strtok(NULL, "*"); #endif i++; } rc[i] = NULL; } } } return rc; } void jk_append_libpath(jk_pool_t *p, const char *libpath) { char *env = NULL; char *current = getenv(PATH_ENV_VARIABLE); if (current) { env = jk_pool_alloc(p, strlen(PATH_ENV_VARIABLE) + strlen(current) + strlen(libpath) + 5); if (env) { sprintf(env, "%s=%s%c%s", PATH_ENV_VARIABLE, libpath, PATH_SEPERATOR, current); } } else { env = jk_pool_alloc(p, strlen(PATH_ENV_VARIABLE) + strlen(libpath) + 5); if (env) { sprintf(env, "%s=%s", PATH_ENV_VARIABLE, libpath); } } if (env) { putenv(env); } } void jk_init_ws_service(jk_ws_service_t *s) { memset(s, 0, sizeof(jk_ws_service_t)); s->server_port = 80; s->ssl_key_size = -1; s->activation = JK_LB_ACTIVATION_TEXT_ACTIVE; s->reco_status = RECO_NONE; s->extension.reply_timeout = -1; s->http_response_status = JK_HTTP_OK; } /* Match = 0, NoMatch = 1, Abort = -1 * Based loosely on sections of wildmat.c by Rich Salz */ int jk_wildchar_match(const char *str, const char *exp, int icase) { int x, y; for (x = 0, y = 0; exp[y]; ++y, ++x) { if (!str[x] && exp[y] != '*') return -1; if (exp[y] == '*') { while (exp[++y] == '*'); if (!exp[y]) return 0; while (str[x]) { int ret; if ((ret = jk_wildchar_match(&str[x++], &exp[y], icase)) != 1) return ret; } return -1; } else if (exp[y] != '?') { if (icase && (tolower(str[x]) != tolower(exp[y]))) return 1; else if (!icase && str[x] != exp[y]) return 1; } } return (str[x] != '\0'); } void jk_no2slash(char *name) { char *d, *s; s = d = name; while (*s) { if ((*d++ = *s) == '/') { do { ++s; } while (*s == '/'); } else { ++s; } } *d = '\0'; } #ifdef _MT_CODE_PTHREAD jk_pthread_t jk_gettid() { union { pthread_t tid; jk_uint64_t alignme; } u; #ifdef AS400 /* OS400 use 64 bits ThreadId */ pthread_id_np_t tid; #endif /* AS400 */ u.tid = pthread_self(); #ifdef AS400 /* Get only low 32 bits for now */ pthread_getunique_np(&(u.tid), &tid); return ((jk_uint32_t)(tid.intId.lo & 0xFFFFFFFF)); #else return ((jk_pthread_t)u.tid); #endif /* AS400 */ } #endif /*** * ASCII <-> EBCDIC conversions * * For now usefull only in i5/OS V5R4 where UTF and EBCDIC mode are mixed */ #ifdef AS400_UTF8 /* EBCDIC to ASCII translation table */ static u_char ebcdic_to_ascii[256] = { 0x00,0x01,0x02,0x03,0x20,0x09,0x20,0x7f, /* 00-07 */ 0x20,0x20,0x20,0x0b,0x0c,0x0d,0x0e,0x0f, /* 08-0f */ 0x10,0x11,0x12,0x13,0x20,0x0a,0x08,0x20, /* 10-17 */ 0x18,0x19,0x20,0x20,0x20,0x1d,0x1e,0x1f, /* 18-1f */ 0x20,0x20,0x1c,0x20,0x20,0x0a,0x17,0x1b, /* 20-27 */ 0x20,0x20,0x20,0x20,0x20,0x05,0x06,0x07, /* 28-2f */ 0x20,0x20,0x16,0x20,0x20,0x20,0x20,0x04, /* 30-37 */ 0x20,0x20,0x20,0x20,0x14,0x15,0x20,0x1a, /* 38-3f */ 0x20,0x20,0x83,0x84,0x85,0xa0,0xc6,0x86, /* 40-47 */ 0x87,0xa4,0xbd,0x2e,0x3c,0x28,0x2b,0x7c, /* 48-4f */ 0x26,0x82,0x88,0x89,0x8a,0xa1,0x8c,0x8b, /* 50-57 */ 0x8d,0xe1,0x21,0x24,0x2a,0x29,0x3b,0xaa, /* 58-5f */ 0x2d,0x2f,0xb6,0x8e,0xb7,0xb5,0xc7,0x8f, /* 60-67 */ 0x80,0xa5,0xdd,0x2c,0x25,0x5f,0x3e,0x3f, /* 68-6f */ 0x9b,0x90,0xd2,0xd3,0xd4,0xd6,0xd7,0xd8, /* 70-77 */ 0xde,0x60,0x3a,0x23,0x40,0x27,0x3d,0x22, /* 78-7f */ 0x9d,0x61,0x62,0x63,0x64,0x65,0x66,0x67, /* 80-87 */ 0x68,0x69,0xae,0xaf,0xd0,0xec,0xe7,0xf1, /* 88-8f */ 0xf8,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70, /* 90-97 */ 0x71,0x72,0xa6,0xa7,0x91,0xf7,0x92,0xcf, /* 98-9f */ 0xe6,0x7e,0x73,0x74,0x75,0x76,0x77,0x78, /* a8-a7 */ 0x79,0x7a,0xad,0xa8,0xd1,0xed,0xe8,0xa9, /* a8-af */ 0x5e,0x9c,0xbe,0xfa,0xb8,0x15,0x14,0xac, /* b0-b7 */ 0xab,0xf3,0x5b,0x5d,0xee,0xf9,0xef,0x9e, /* b8-bf */ 0x7b,0x41,0x42,0x43,0x44,0x45,0x46,0x47, /* c0-c7 */ 0x48,0x49,0xf0,0x93,0x94,0x95,0xa2,0xe4, /* c8-cf */ 0x7d,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50, /* d0-d7 */ 0x51,0x52,0xfb,0x96,0x81,0x97,0xa3,0x98, /* d8-df */ 0x5c,0xf6,0x53,0x54,0x55,0x56,0x57,0x58, /* e0-e7 */ 0x59,0x5a,0xfc,0xe2,0x99,0xe3,0xe0,0xe5, /* e8-ef */ 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37, /* f0-f7 */ 0x38,0x39,0xfd,0xea,0x9a,0xeb,0xe9,0xff /* f8-ff */ }; /* ASCII to EBCDIC translation table */ static u_char ascii_to_ebcdic[256] = { 0x00,0x01,0x02,0x03,0x37,0x2d,0x2e,0x2f, /* 00-07 */ 0x16,0x05,0x25,0x0b,0x0c,0x0d,0x0e,0x0f, /* 08-0f */ 0x10,0x11,0x12,0x13,0x3c,0x3d,0x32,0x26, /* 10-17 */ 0x18,0x19,0x3f,0x27,0x22,0x1d,0x1e,0x1f, /* 18-1f */ 0x40,0x5a,0x7f,0x7b,0x5b,0x6c,0x50,0x7d, /* 20-27 */ 0x4d,0x5d,0x5c,0x4e,0x6b,0x60,0x4b,0x61, /* 28-2f */ 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7, /* 30-37 */ 0xf8,0xf9,0x7a,0x5e,0x4c,0x7e,0x6e,0x6f, /* 38-3f */ 0x7c,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7, /* 40-47 */ 0xc8,0xc9,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6, /* 48-4f */ 0xd7,0xd8,0xd9,0xe2,0xe3,0xe4,0xe5,0xe6, /* 50-57 */ 0xe7,0xe8,0xe9,0xba,0xe0,0xbb,0xb0,0x6d, /* 58-5f */ 0x79,0x81,0x82,0x83,0x84,0x85,0x86,0x87, /* 60-67 */ 0x88,0x89,0x91,0x92,0x93,0x94,0x95,0x96, /* 68-6f */ 0x97,0x98,0x99,0xa2,0xa3,0xa4,0xa5,0xa6, /* 70-77 */ 0xa7,0xa8,0xa9,0xc0,0x4f,0xd0,0xa1,0x07, /* 78-7f */ 0x68,0xdc,0x51,0x42,0x43,0x44,0x47,0x48, /* 80-87 */ 0x52,0x53,0x54,0x57,0x56,0x58,0x63,0x67, /* 88-8f */ 0x71,0x9c,0x9e,0xcb,0xcc,0xcd,0xdb,0xdd, /* 90-97 */ 0xdf,0xec,0xfc,0x70,0xb1,0x80,0xbf,0x40, /* 98-9f */ 0x45,0x55,0xee,0xde,0x49,0x69,0x9a,0x9b, /* a8-a7 */ 0xab,0xaf,0x5f,0xb8,0xb7,0xaa,0x8a,0x8b, /* a8-af */ 0x40,0x40,0x40,0x40,0x40,0x65,0x62,0x64, /* b0-b7 */ 0xb4,0x40,0x40,0x40,0x40,0x4a,0xb2,0x40, /* b8-bf */ 0x40,0x40,0x40,0x40,0x40,0x40,0x46,0x66, /* c0-c7 */ 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x9f, /* c8-cf */ 0x8c,0xac,0x72,0x73,0x74,0x89,0x75,0x76, /* d0-d7 */ 0x77,0x40,0x40,0x40,0x40,0x6a,0x78,0x40, /* d8-df */ 0xee,0x59,0xeb,0xed,0xcf,0xef,0xa0,0x8e, /* e0-e7 */ 0xae,0xfe,0xfb,0xfd,0x8d,0xad,0xbc,0xbe, /* e8-ef */ 0xca,0x8f,0x40,0xb9,0xb6,0xb5,0xe1,0x9d, /* f0-f7 */ 0x90,0xbd,0xb3,0xda,0xea,0xfa,0x40,0x40 /* f8-ff */ }; void jk_ascii2ebcdic(char *src, char *dst) { char c; while ((c = *src++) != 0) { *dst++ = ascii_to_ebcdic[(unsigned int)c]; } *dst = 0; } void jk_ebcdic2ascii(char *src, char *dst) { char c; while ((c = *src++) != 0) { *dst++ = ebcdic_to_ascii[(unsigned int)c]; } *dst = 0; } #endif #if defined (WIN32) static PSECURITY_ATTRIBUTES pNullSA; static SECURITY_ATTRIBUTES stEmptySA; /* To share the objects with other processes, we need a 0 ACL * Code from MS KB Q106387 */ PSECURITY_ATTRIBUTES jk_get_sa_with_null_dacl() { DWORD rc = 0; PSECURITY_DESCRIPTOR pSD; if (pNullSA != NULL) { return pNullSA; } else { stEmptySA.nLength = (DWORD)sizeof(SECURITY_ATTRIBUTES); stEmptySA.lpSecurityDescriptor = 0; } if (!(pNullSA = LocalAlloc(LPTR, sizeof(SECURITY_ATTRIBUTES)))) { rc = GetLastError(); goto cleanup; } pNullSA->nLength = (DWORD)sizeof(SECURITY_ATTRIBUTES); pSD = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); if (pSD == 0) { rc = GetLastError(); goto cleanup; } pNullSA->lpSecurityDescriptor = pSD; if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) { rc = GetLastError(); goto cleanup; } if (!SetSecurityDescriptorDacl(pSD, TRUE, (PACL)0, FALSE)) { rc = GetLastError(); goto cleanup; } pNullSA->lpSecurityDescriptor = pSD; pNullSA->bInheritHandle = FALSE; SetLastError(0); return pNullSA; cleanup: if (pSD) LocalFree(pSD); if (pNullSA) LocalFree(pNullSA); pNullSA = &stEmptySA; pNullSA->bInheritHandle = FALSE; SetLastError(rc); return pNullSA; } #endif tomcat-connectors-1.2.41-src/native/common/jk_util.h0000644000000000000020000002340312465671172020720 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Various utility functions * * Author: Gal Shachor * * Author: Henri Gomez * * Author: Rainer Jung * * Version: $Revision: 1658173 $ * ***************************************************************************/ #ifndef _JK_UTIL_H #define _JK_UTIL_H #include "jk_global.h" #include "jk_logger.h" #include "jk_map.h" #include "jk_pool.h" #include "jk_service.h" #define JK_SLEEP_DEF (100) #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ const char *jk_get_bool(int v); int jk_get_bool_code(const char *v, int def); void jk_sleep(int ms); void jk_set_time_fmt(jk_logger_t *l, const char *jk_log_fmt); int jk_parse_log_level(const char *level); int jk_open_file_logger(jk_logger_t **l, const char *file, int level); int jk_attach_file_logger(jk_logger_t **l, int fd, int level); int jk_close_file_logger(jk_logger_t **l); int jk_log(jk_logger_t *l, const char *file, int line, const char *funcname, int level, const char *fmt, ...); int jk_check_attribute_length(const char *name, const char *value, jk_logger_t *l); const char *jk_get_worker_host(jk_map_t *m, const char *wname, const char *def); const char *jk_get_worker_source(jk_map_t *m, const char *wname, const char *def); const char *jk_get_worker_type(jk_map_t *m, const char *wname); int jk_get_worker_port(jk_map_t *m, const char *wname, int def); int jk_get_worker_prefer_ipv6(jk_map_t *m, const char *wname, int def); int jk_get_worker_cache_size(jk_map_t *m, const char *wname, int def); int jk_get_worker_cache_size_min(jk_map_t *m, const char *wname, int def); int jk_get_worker_cache_acquire_timeout(jk_map_t *m, const char *wname, int def); int jk_get_worker_socket_timeout(jk_map_t *m, const char *wname, int def); int jk_get_worker_socket_connect_timeout(jk_map_t *m, const char *wname, int def); int jk_get_worker_socket_buffer(jk_map_t *m, const char *wname, int def); int jk_get_worker_socket_keepalive(jk_map_t *m, const char *wname, int def); int jk_get_worker_conn_ping_interval(jk_map_t *m, const char *wname, int def); int jk_get_worker_cache_timeout(jk_map_t *m, const char *wname, int def); int jk_get_worker_recovery_opts(jk_map_t *m, const char *wname, int def); int jk_get_worker_connect_timeout(jk_map_t *m, const char *wname, int def); int jk_get_worker_reply_timeout(jk_map_t *m, const char *wname, int def); int jk_get_worker_prepost_timeout(jk_map_t *m, const char *wname, int def); int jk_get_worker_ping_timeout(jk_map_t *m, const char *wname, int def); int jk_get_worker_ping_mode(jk_map_t *m, const char *wname, int def); int jk_get_worker_recycle_timeout(jk_map_t *m, const char *wname, int def); int jk_get_worker_recover_timeout(jk_map_t *m, const char *wname, int def); int jk_get_worker_error_escalation_time(jk_map_t *m, const char *wname, int def); int jk_get_worker_max_reply_timeouts(jk_map_t *m, const char *wname, int def); int jk_get_worker_retry_interval(jk_map_t *m, const char *wname, int def); int jk_get_worker_busy_limit(jk_map_t *m, const char *wname, int def); const char *jk_get_worker_route(jk_map_t *m, const char *wname, const char *def); const char *jk_get_worker_domain(jk_map_t *m, const char *wname, const char *def); const char *jk_get_worker_redirect(jk_map_t *m, const char *wname, const char *def); const char *jk_get_worker_secret_key(jk_map_t *m, const char *wname); const char *jk_get_lb_session_cookie(jk_map_t *m, const char *wname, const char *def); const char *jk_get_lb_session_path(jk_map_t *m, const char *wname, const char *def); int jk_get_lb_set_session_cookie(jk_map_t *m, const char *wname, int def); const char *jk_get_lb_session_cookie_path(jk_map_t *m, const char *wname, const char *def); int jk_get_worker_retries(jk_map_t *m, const char *wname, int def); int jk_get_is_worker_disabled(jk_map_t *m, const char *wname); int jk_get_is_worker_stopped(jk_map_t *m, const char *wname); int jk_get_worker_activation(jk_map_t *m, const char *wname); int jk_get_worker_list(jk_map_t *m, char ***list, unsigned *num_of_workers); int jk_get_lb_factor(jk_map_t *m, const char *wname); int jk_get_distance(jk_map_t *m, const char *wname); int jk_get_is_sticky_session(jk_map_t *m, const char *wname); int jk_get_is_sticky_session_force(jk_map_t *m, const char *wname); int jk_get_lb_method(jk_map_t *m, const char *wname); int jk_get_lb_lock(jk_map_t *m, const char *wname); int jk_get_lb_worker_list(jk_map_t *m, const char *lb_wname, char ***list, unsigned int *num_of_workers); int jk_get_worker_mount_list(jk_map_t *m, const char *wname, char ***list, unsigned int *num_of_maps); const char *jk_get_worker_secret(jk_map_t *m, const char *wname); int jk_get_worker_mx(jk_map_t *m, const char *wname, unsigned *mx); int jk_get_worker_ms(jk_map_t *m, const char *wname, unsigned *ms); int jk_get_worker_classpath(jk_map_t *m, const char *wname, const char **cp); int jk_get_worker_bridge_type(jk_map_t *m, const char *wname, unsigned *bt); int jk_get_worker_jvm_path(jk_map_t *m, const char *wname, const char **vm_path); int jk_get_worker_callback_dll(jk_map_t *m, const char *wname, const char **cb_path); int jk_get_worker_cmd_line(jk_map_t *m, const char *wname, const char **cmd_line); int jk_file_exists(const char *f); int jk_is_list_property(const char *prp_name); int jk_is_path_property(const char *prp_name); int jk_is_cmd_line_property(const char *prp_name); int jk_is_unique_property(const char *prp_name); int jk_is_deprecated_property(const char *prp_name); int jk_check_buffer_size(); int jk_is_valid_property(const char *prp_name); int jk_get_worker_stdout(jk_map_t *m, const char *wname, const char **stdout_name); int jk_get_worker_stderr(jk_map_t *m, const char *wname, const char **stderr_name); int jk_get_worker_sysprops(jk_map_t *m, const char *wname, const char **sysprops); int jk_get_worker_libpath(jk_map_t *m, const char *wname, const char **libpath); char **jk_parse_sysprops(jk_pool_t *p, const char *sysprops); void jk_append_libpath(jk_pool_t *p, const char *libpath); void jk_set_worker_def_cache_size(int sz); int jk_get_worker_def_cache_size(int protocol); int jk_get_worker_maintain_time(jk_map_t *m); int jk_get_max_packet_size(jk_map_t *m, const char *wname); const char *jk_get_worker_style_sheet(jk_map_t *m, const char *wname, const char *def); int jk_get_is_read_only(jk_map_t *m, const char *wname); int jk_get_worker_user_list(jk_map_t *m, const char *wname, char ***list, unsigned int *num); int jk_get_worker_good_rating(jk_map_t *m, const char *wname, char ***list, unsigned int *num); int jk_get_worker_bad_rating(jk_map_t *m, const char *wname, char ***list, unsigned int *num); const char *jk_get_worker_name_space(jk_map_t *m, const char *wname, const char *def); const char *jk_get_worker_xmlns(jk_map_t *m, const char *wname, const char *def); const char *jk_get_worker_xml_doctype(jk_map_t *m, const char *wname, const char *def); const char *jk_get_worker_prop_prefix(jk_map_t *m, const char *wname, const char *def); int jk_get_worker_fail_on_status(jk_map_t *m, const char *wname, int **list, unsigned int *list_size); int jk_get_worker_user_case_insensitive(jk_map_t *m, const char *wname); int is_http_status_fail(unsigned int http_status_fail_num, int *http_status_fail, int status); int jk_wildchar_match(const char *str, const char *exp, int icase); void jk_no2slash(char *name); #define TC32_BRIDGE_TYPE 32 #define TC33_BRIDGE_TYPE 33 #define TC40_BRIDGE_TYPE 40 #define TC41_BRIDGE_TYPE 41 #define TC50_BRIDGE_TYPE 50 #ifdef AS400 #define S_IFREG _S_IFREG #ifdef AS400_UTF8 void jk_ascii2ebcdic(char *src, char *dst); void jk_ebcdic2ascii(char *src, char *dst); #endif /* AS400_UTF8 */ #endif /* i5/OS V5R4 need ASCII-EBCDIC conversion before stat() call */ /* added a stat() mapper function, jk_stat, for such purpose */ int jk_stat(const char *f, struct stat * statbuf); #if defined (WIN32) PSECURITY_ATTRIBUTES jk_get_sa_with_null_dacl(void); #endif #define jk_isspace(c) (isspace(((unsigned char)(c)))) #define jk_isalnum(c) (isalnum(((unsigned char)(c)))) #define jk_isdigit(c) (isdigit(((unsigned char)(c)))) #define jk_isalpha(c) (isalpha(((unsigned char)(c)))) #define jk_islower(c) (islower(((unsigned char)(c)))) #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _JK_UTIL_H */ tomcat-connectors-1.2.41-src/native/common/jk_status.h0000644000000000000020000000325410516516102021252 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Status worker header file * * Author: Mladen Turk * * Version: $Revision: 466585 $ * ***************************************************************************/ #ifndef JK_STATUS_H #define JK_STATUS_H #include "jk_logger.h" #include "jk_service.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define JK_STATUS_WORKER_NAME ("status") #define JK_STATUS_WORKER_TYPE (6) int JK_METHOD status_worker_factory(jk_worker_t **w, const char *name, jk_logger_t *l); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_STATUS_H */ tomcat-connectors-1.2.41-src/native/common/jk_map.h0000644000000000000020000000662012446650514020516 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Map object header file * * Author: Gal Shachor * * Version: $Revision: 1647863 $ * ***************************************************************************/ #ifndef JK_MAP_H #define JK_MAP_H #include "jk_pool.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define JK_MAP_HANDLE_NORMAL 0 #define JK_MAP_HANDLE_DUPLICATES 1 #define JK_MAP_HANDLE_RAW 2 struct jk_map { jk_pool_t p; jk_pool_atom_t buf[SMALL_POOL_SIZE]; const char **names; const void **values; unsigned int *keys; unsigned int capacity; unsigned int size; int id; }; typedef struct jk_map jk_map_t; int jk_map_alloc(jk_map_t **m); int jk_map_free(jk_map_t **m); int jk_map_open(jk_map_t *m); int jk_map_close(jk_map_t *m); void *jk_map_get(jk_map_t *m, const char *name, const void *def); int jk_map_get_id(jk_map_t *m, const char *name); int jk_map_get_int(jk_map_t *m, const char *name, int def); double jk_map_get_double(jk_map_t *m, const char *name, double def); int jk_map_get_bool(jk_map_t *m, const char *name, int def); const char *jk_map_get_string(jk_map_t *m, const char *name, const char *def); char **jk_map_get_string_list(jk_map_t *m, const char *name, unsigned *list_len, const char *def); int *jk_map_get_int_list(jk_map_t *m, const char *name, unsigned int *list_len, const char *def); int jk_map_add(jk_map_t *m, const char *name, const void *value); int jk_map_put(jk_map_t *m, const char *name, const void *value, void **old); int jk_map_read_property(jk_map_t *m, jk_map_t *env, const char *str, int treatment, jk_logger_t *l); int jk_map_read_properties(jk_map_t *m, jk_map_t *env, const char *f, time_t *modified, int treatment, jk_logger_t *l); int jk_map_size(jk_map_t *m); const char *jk_map_name_at(jk_map_t *m, int idex); void *jk_map_value_at(jk_map_t *m, int idex); void jk_map_dump(jk_map_t *m, jk_logger_t *l); int jk_map_copy(jk_map_t *src, jk_map_t *dst); int jk_map_resolve_references(jk_map_t *m, const char *prefix, int wildcard, int depth, jk_logger_t *l); int jk_map_inherit_properties(jk_map_t *m, const char *from, const char *to, jk_logger_t *l); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_MAP_H */ tomcat-connectors-1.2.41-src/native/common/jk_ajp14_worker.h0000644000000000000020000000352510516516102022240 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: ajpv14 worker header file * * Author: Henri Gomez * * Version: $Revision: 466585 $ * ***************************************************************************/ #ifndef JK_AJP14_WORKER_H #define JK_AJP14_WORKER_H #include "jk_pool.h" #include "jk_connect.h" #include "jk_util.h" #include "jk_msg_buff.h" #include "jk_ajp13.h" #include "jk_ajp14.h" #include "jk_logger.h" #include "jk_service.h" #include "jk_ajp13_worker.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define JK_AJP14_WORKER_NAME ("ajp14") #define JK_AJP14_WORKER_TYPE (3) int JK_METHOD ajp14_worker_factory(jk_worker_t **w, const char *name, jk_logger_t *l); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_AJP14_WORKER_H */ tomcat-connectors-1.2.41-src/native/common/jk_pool.h0000644000000000000020000000734311734266476020726 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Memory Pool object header file * * Author: Gal Shachor * * Version: $Revision: 1305756 $ * ***************************************************************************/ #ifndef _JK_POOL_H #define _JK_POOL_H #include "jk_global.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** * @file jk_pool.h * @brief Jk memory allocation * * Similar with apr_pools, but completely unsynchronized. * XXX use same names * */ /* * The pool atom (basic pool alocation unit) is an 8 byte long. * Each allocation (even for 1 byte) will return a round up to the * number of atoms. * * This is to help in alignment of 32/64 bit machines ... * G.S */ #ifdef WIN32 typedef __int64 jk_pool_atom_t; #elif defined(AIX) typedef long long jk_pool_atom_t; #elif defined(SOLARIS) typedef long long jk_pool_atom_t; #elif defined(LINUX) typedef long long jk_pool_atom_t; #elif defined(FREEBSD) typedef long long jk_pool_atom_t; #elif defined(OS2) typedef long long jk_pool_atom_t; #elif defined(NETWARE) typedef long long jk_pool_atom_t; #elif defined(HPUX11) typedef long long jk_pool_atom_t; #elif defined(IRIX) typedef long long jk_pool_atom_t; #elif defined(AS400) typedef void *jk_pool_atom_t; #else typedef long long jk_pool_atom_t; #endif /** * Alignment macros */ /* JK_ALIGN() is only to be used to align on a power of 2 boundary */ #define JK_ALIGN(size, boundary) \ (((size) + ((boundary) - 1)) & ~((boundary) - 1)) /** Default alignment */ #ifdef AS400 #define JK_ALIGN_DEFAULT(size) JK_ALIGN(size, 16) #else #define JK_ALIGN_DEFAULT(size) JK_ALIGN(size, 8) #endif /* * Pool size in number of pool atoms. */ #define TINY_POOL_SIZE 256 /* Tiny 1/4K atom pool. */ #define SMALL_POOL_SIZE 512 /* Small 1/2K atom pool. */ #define BIG_POOL_SIZE 2*SMALL_POOL_SIZE /* Bigger 1K atom pool. */ #define HUGE_POOL_SIZE 2*BIG_POOL_SIZE /* Huge 2K atom pool. */ /** jk pool structure */ struct jk_pool { size_t size; size_t pos; char *buf; size_t dyn_size; size_t dyn_pos; void **dynamic; }; typedef struct jk_pool jk_pool_t; void jk_open_pool(jk_pool_t *p, jk_pool_atom_t *buf, size_t size); void jk_close_pool(jk_pool_t *p); void jk_reset_pool(jk_pool_t *p); void *jk_pool_alloc(jk_pool_t *p, size_t sz); void *jk_pool_calloc(jk_pool_t *p, size_t sz); void *jk_pool_realloc(jk_pool_t *p, size_t sz, const void *old, size_t old_sz); char *jk_pool_strdup(jk_pool_t *p, const char *s); char *jk_pool_strcat(jk_pool_t *p, const char *s, const char *a); char *jk_pool_strcatv(jk_pool_t *p, ...); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _JK_POOL_H */ tomcat-connectors-1.2.41-src/native/common/jk_types.h.in0000644000000000000020000000405011340671766021511 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Platform specific, auto-detected types. * * Author: Rainer Jung * * Version: $Revision: 915199 $ * ***************************************************************************/ #ifndef JK_TYPES_H #define JK_TYPES_H /* GENERATED FILE WARNING! DO NOT EDIT jk_types.h * * You must modify jk_types.h.in instead. * */ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /* jk_uint32_t defines a four byte word */ typedef unsigned @int32_value@ jk_uint32_t; /* And JK_UINT32_T_FMT */ @uint32_t_fmt@ /* And JK_UINT32_T_HEX_FMT */ @uint32_t_hex_fmt@ /* jk_uint64_t defines a eight byte word */ typedef unsigned @int64_value@ jk_uint64_t; /* And JK_UINT64_T_FMT */ @uint64_t_fmt@ /* And JK_UINT64_T_HEX_FMT */ @uint64_t_hex_fmt@ /* And JK_PID_T_FMT */ @pid_t_fmt@ /* jk_pthread_t defines a eight byte word */ typedef unsigned @pthread_t_value@ jk_pthread_t; /* And JK_PTHREAD_T_FMT */ @pthread_t_fmt@ #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_TYPES_H */ tomcat-connectors-1.2.41-src/native/common/jk_lb_worker.h0000644000000000000020000002221112477544555021734 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: load balance worker header file * * Author: Gal Shachor * * Author: Rainer Jung * * Version: $Revision: 1665454 $ * ***************************************************************************/ #ifndef JK_LB_WORKER_H #define JK_LB_WORKER_H #include "jk_logger.h" #include "jk_service.h" #include "jk_mt.h" #include "jk_shm.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #define JK_LB_WORKER_NAME ("lb") #define JK_LB_WORKER_TYPE (5) #define JK_LB_SUB_WORKER_TYPE (7) #define JK_LB_DEF_DOMAIN_NAME ("unknown") #define JK_LB_METHOD_REQUESTS (0) #define JK_LB_METHOD_TRAFFIC (1) #define JK_LB_METHOD_BUSYNESS (2) #define JK_LB_METHOD_SESSIONS (3) #define JK_LB_METHOD_NEXT (4) #define JK_LB_METHOD_DEF (JK_LB_METHOD_REQUESTS) #define JK_LB_METHOD_MAX (JK_LB_METHOD_NEXT) #define JK_LB_METHOD_TEXT_REQUESTS ("Request") #define JK_LB_METHOD_TEXT_TRAFFIC ("Traffic") #define JK_LB_METHOD_TEXT_BUSYNESS ("Busyness") #define JK_LB_METHOD_TEXT_SESSIONS ("Sessions") #define JK_LB_METHOD_TEXT_NEXT ("Next") #define JK_LB_METHOD_TEXT_DEF (JK_LB_METHOD_TEXT_REQUESTS) #define JK_LB_LOCK_OPTIMISTIC (0) #define JK_LB_LOCK_PESSIMISTIC (1) #define JK_LB_LOCK_DEF (JK_LB_LOCK_OPTIMISTIC) #define JK_LB_LOCK_MAX (JK_LB_LOCK_PESSIMISTIC) #define JK_LB_LOCK_TEXT_OPTIMISTIC ("Optimistic") #define JK_LB_LOCK_TEXT_PESSIMISTIC ("Pessimistic") #define JK_LB_LOCK_TEXT_DEF (JK_LB_LOCK_TEXT_OPTIMISTIC) /* * The following definitions for state and activation * need to be kept in sync with the two macros * JK_WORKER_USABLE() and JK_WORKER_USABLE_STICKY() in jk_lb_worker.c. * Since we use ordered comparisons there instead of multiple * equal/unequal compares, order of the values is critical here. */ #define JK_LB_STATE_IDLE (0) #define JK_LB_STATE_OK (1) #define JK_LB_STATE_RECOVER (2) #define JK_LB_STATE_FORCE (3) #define JK_LB_STATE_BUSY (4) #define JK_LB_STATE_ERROR (5) #define JK_LB_STATE_PROBE (6) #define JK_LB_STATE_DEF (JK_LB_STATE_IDLE) #define JK_LB_STATE_TEXT_IDLE ("OK/IDLE") #define JK_LB_STATE_TEXT_OK ("OK") #define JK_LB_STATE_TEXT_RECOVER ("ERR/REC") #define JK_LB_STATE_TEXT_FORCE ("ERR/FRC") #define JK_LB_STATE_TEXT_BUSY ("OK/BUSY") #define JK_LB_STATE_TEXT_ERROR ("ERR") #define JK_LB_STATE_TEXT_PROBE ("ERR/PRB") #define JK_LB_STATE_TEXT_MAX (JK_LB_STATE_PROBE) #define JK_LB_STATE_TEXT_DEF (JK_LB_STATE_TEXT_IDLE) /* All JK_LB_ACTIVATION_* values must be single digit. */ /* Otherwise the string encoding of the activation array */ /* fails e.g. in the isapi redirector. */ /* JK_LB_ACTIVATION_UNSET is not allowed as an actual worker state. */ /* It will not work e.g. when the status worker tries to show the state. */ /* It is only used in rule extension data to indicate, that the */ /* activation state should not be overwritten. */ #define JK_LB_ACTIVATION_ACTIVE (0) #define JK_LB_ACTIVATION_DISABLED (1) #define JK_LB_ACTIVATION_STOPPED (2) #define JK_LB_ACTIVATION_UNSET (9) #define JK_LB_ACTIVATION_DEF (JK_LB_ACTIVATION_ACTIVE) #define JK_LB_ACTIVATION_MAX (JK_LB_ACTIVATION_STOPPED) #define JK_LB_ACTIVATION_TEXT_ACTIVE ("ACT") #define JK_LB_ACTIVATION_TEXT_DISABLED ("DIS") #define JK_LB_ACTIVATION_TEXT_STOPPED ("STP") #define JK_LB_ACTIVATION_TEXT_DEF (JK_LB_ACTIVATION_TEXT_ACTIVE) #define JK_LB_UINT64_STR_SZ (21) #define JK_LB_NOTES_COUNT (10) #define JK_NOTE_LB_FIRST_NAME ("JK_LB_FIRST_NAME") #define JK_NOTE_LB_FIRST_VALUE ("JK_LB_FIRST_VALUE") #define JK_NOTE_LB_FIRST_ACCESSED ("JK_LB_FIRST_ACCESSED") #define JK_NOTE_LB_FIRST_SESSIONS ("JK_LB_FIRST_SESSIONS") #define JK_NOTE_LB_FIRST_READ ("JK_LB_FIRST_READ") #define JK_NOTE_LB_FIRST_TRANSFERRED ("JK_LB_FIRST_TRANSFERRED") #define JK_NOTE_LB_FIRST_ERRORS ("JK_LB_FIRST_ERRORS") #define JK_NOTE_LB_FIRST_BUSY ("JK_LB_FIRST_BUSY") #define JK_NOTE_LB_FIRST_ACTIVATION ("JK_LB_FIRST_ACTIVATION") #define JK_NOTE_LB_FIRST_STATE ("JK_LB_FIRST_STATE") #define JK_NOTE_LB_LAST_NAME ("JK_LB_LAST_NAME") #define JK_NOTE_LB_LAST_VALUE ("JK_LB_LAST_VALUE") #define JK_NOTE_LB_LAST_ACCESSED ("JK_LB_LAST_ACCESSED") #define JK_NOTE_LB_LAST_SESSIONS ("JK_LB_LAST_SESSIONS") #define JK_NOTE_LB_LAST_READ ("JK_LB_LAST_READ") #define JK_NOTE_LB_LAST_TRANSFERRED ("JK_LB_LAST_TRANSFERRED") #define JK_NOTE_LB_LAST_ERRORS ("JK_LB_LAST_ERRORS") #define JK_NOTE_LB_LAST_BUSY ("JK_LB_LAST_BUSY") #define JK_NOTE_LB_LAST_ACTIVATION ("JK_LB_LAST_ACTIVATION") #define JK_NOTE_LB_LAST_STATE ("JK_LB_LAST_STATE") /* Time to wait before retry. */ #define WAIT_BEFORE_RECOVER (60) /* We divide load values by 2^x during global maintenance. */ /* The exponent x is JK_LB_DECAY_MULT*#MAINT_INTV_SINCE_LAST_MAINT */ #define JK_LB_DECAY_MULT (1) struct lb_sub_worker { jk_worker_t *worker; /* Shared memory worker data */ jk_shm_lb_sub_worker_t *s; char name[JK_SHM_STR_SIZ]; /* Sequence counter starting at 0 and increasing * every time we change the config */ volatile unsigned int sequence; /* route */ char route[JK_SHM_STR_SIZ]; /* worker domain */ char domain[JK_SHM_STR_SIZ]; /* worker redirect route */ char redirect[JK_SHM_STR_SIZ]; /* worker distance */ int distance; /* current activation state (config) of the worker */ int activation; /* Current lb factor */ int lb_factor; /* Current worker index */ int i; /* Current lb reciprocal factor */ jk_uint64_t lb_mult; }; typedef struct lb_sub_worker lb_sub_worker_t; struct lb_worker { jk_worker_t worker; /* Shared memory worker data */ jk_shm_lb_worker_t *s; char name[JK_SHM_STR_SIZ]; /* Sequence counter starting at 0 and increasing * every time we change the config */ volatile unsigned int sequence; jk_pool_t p; jk_pool_atom_t buf[TINY_POOL_SIZE]; JK_CRIT_SEC cs; lb_sub_worker_t *lb_workers; unsigned int num_of_workers; int sticky_session; int sticky_session_force; int recover_wait_time; int error_escalation_time; int max_reply_timeouts; int retries; int retry_interval; int lbmethod; int lblock; int maintain_time; unsigned int max_packet_size; unsigned int next_offset; /* Session cookie */ char session_cookie[JK_SHM_STR_SIZ]; /* Session path */ char session_path[JK_SHM_STR_SIZ]; int set_session_cookie; char session_cookie_path[JK_SHM_STR_SIZ]; }; typedef struct lb_worker lb_worker_t; int JK_METHOD lb_worker_factory(jk_worker_t **w, const char *name, jk_logger_t *l); const char *jk_lb_get_lock_direct(int lblock, jk_logger_t *l); const char *jk_lb_get_lock(lb_worker_t *p, jk_logger_t *l); int jk_lb_get_lock_code(const char *v); const char *jk_lb_get_method_direct(int lbmethod, jk_logger_t *l); const char *jk_lb_get_method(lb_worker_t *p, jk_logger_t *l); int jk_lb_get_method_code(const char *v); const char *jk_lb_get_state_direct(int state, jk_logger_t *l); const char *jk_lb_get_state(lb_sub_worker_t *p, jk_logger_t *l); int jk_lb_get_state_code(const char *v); const char *jk_lb_get_activation_direct(int activation, jk_logger_t *l); const char *jk_lb_get_activation(lb_sub_worker_t *p, jk_logger_t *l); int jk_lb_get_activation_code(const char *v); void reset_lb_values(lb_worker_t *p, jk_logger_t *l); void jk_lb_pull(lb_worker_t * p, int locked, jk_logger_t *l); void jk_lb_push(lb_worker_t * p, int locked, jk_logger_t *l); void update_mult(lb_worker_t * p, jk_logger_t *l); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_LB_WORKER_H */ tomcat-connectors-1.2.41-src/native/common/list.mk.in0000644000000000000020000000271111660656133021012 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ## Object needed for mod_jk for Apache-1.3 APACHE_OBJECTS= ${JK}jk_ajp12_worker${OEXT} ${JK}jk_connect${OEXT} \ ${JK}jk_msg_buff${OEXT} ${JK}jk_util${OEXT} \ ${JK}jk_ajp13${OEXT} ${JK}jk_pool${OEXT} \ ${JK}jk_worker${OEXT} ${JK}jk_ajp13_worker${OEXT} \ ${JK}jk_lb_worker${OEXT} ${JK}jk_sockbuf${OEXT} \ ${JK}jk_map${OEXT} ${JK}jk_uri_worker_map${OEXT} \ ${JK}jk_ajp14${OEXT} ${JK}jk_ajp14_worker${OEXT} \ ${JK}jk_md5${OEXT} ${JK}jk_shm${OEXT} \ ${JK}jk_ajp_common${OEXT} ${JK}jk_context${OEXT} \ ${JK}jk_url${OEXT} \ ${JK}jk_status${OEXT} tomcat-connectors-1.2.41-src/native/common/jk_logger.h0000644000000000000020000001217012452651236021214 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Logger object definitions * * Author: Gal Shachor * * Version: $Revision: 1649728 $ * ***************************************************************************/ #ifndef JK_LOGGER_H #define JK_LOGGER_H #include "jk_global.h" #ifdef __cplusplus extern "C" { #endif #define JK_TIME_MAX_SIZE (64) typedef struct jk_logger jk_logger_t; struct jk_logger { void *logger_private; int level; const char *log_fmt; /* the configured timestamp format for logging */ char log_fmt_subsec[JK_TIME_MAX_SIZE]; /* like log_fmt, but milli/micro seconds marker replaced, because strftime() doesn't handle those */ int log_fmt_type; /* do we want milli or microseconds */ size_t log_fmt_offset; /* at which position should we insert */ size_t log_fmt_size; /* how long is this format string */ int (JK_METHOD * log) (jk_logger_t *l, int level, int used, char *what); }; typedef struct jk_file_logger_t jk_file_logger_t; struct jk_file_logger_t { FILE *logfile; /* For Apache 2 APR piped logging */ void *jklogfp; /* For Apache 1.3 piped logging */ int log_fd; int is_piped; }; /* Level like Java tracing, but available only at compile time on DEBUG preproc define. */ #define JK_LOG_TRACE_LEVEL 0 #define JK_LOG_DEBUG_LEVEL 1 #define JK_LOG_INFO_LEVEL 2 #define JK_LOG_WARNING_LEVEL 3 #define JK_LOG_ERROR_LEVEL 4 #define JK_LOG_EMERG_LEVEL 5 #define JK_LOG_REQUEST_LEVEL 6 #define JK_LOG_DEF_LEVEL JK_LOG_INFO_LEVEL #define JK_LOG_TRACE_VERB "trace" #define JK_LOG_DEBUG_VERB "debug" #define JK_LOG_INFO_VERB "info" #define JK_LOG_WARN_VERB "warn" #define JK_LOG_ERROR_VERB "error" #define JK_LOG_EMERG_VERB "emerg" #define JK_LOG_DEF_VERB JK_LOG_INFO_VERB #if defined(__GNUC__) || (defined(_MSC_VER) && (_MSC_VER > 1200)) #define JK_LOG_TRACE __FILE__,__LINE__,__FUNCTION__,JK_LOG_TRACE_LEVEL #define JK_LOG_DEBUG __FILE__,__LINE__,__FUNCTION__,JK_LOG_DEBUG_LEVEL #define JK_LOG_ERROR __FILE__,__LINE__,__FUNCTION__,JK_LOG_ERROR_LEVEL #define JK_LOG_EMERG __FILE__,__LINE__,__FUNCTION__,JK_LOG_EMERG_LEVEL #define JK_LOG_INFO __FILE__,__LINE__,__FUNCTION__,JK_LOG_INFO_LEVEL #define JK_LOG_WARNING __FILE__,__LINE__,__FUNCTION__,JK_LOG_WARNING_LEVEL #else #define JK_LOG_TRACE __FILE__,__LINE__,NULL,JK_LOG_TRACE_LEVEL #define JK_LOG_DEBUG __FILE__,__LINE__,NULL,JK_LOG_DEBUG_LEVEL #define JK_LOG_ERROR __FILE__,__LINE__,NULL,JK_LOG_ERROR_LEVEL #define JK_LOG_EMERG __FILE__,__LINE__,NULL,JK_LOG_EMERG_LEVEL #define JK_LOG_INFO __FILE__,__LINE__,NULL,JK_LOG_INFO_LEVEL #define JK_LOG_WARNING __FILE__,__LINE__,NULL,JK_LOG_WARNING_LEVEL #endif #define JK_LOG_REQUEST __FILE__,0,NULL,JK_LOG_REQUEST_LEVEL #if defined(JK_PRODUCTION) /* TODO: all DEBUG messages should be compiled out * when this define is in place. */ #define JK_IS_PRODUCTION 1 #define JK_TRACE_ENTER(l) #define JK_TRACE_EXIT(l) #else #define JK_IS_PRODUCTION 0 #define JK_TRACE_ENTER(l) \ do { \ if ((l) && (l)->level == JK_LOG_TRACE_LEVEL) { \ int tmp_errno = errno; \ jk_log((l), JK_LOG_TRACE, "enter"); \ errno = tmp_errno; \ } } while (0) #define JK_TRACE_EXIT(l) \ do { \ if ((l) && (l)->level == JK_LOG_TRACE_LEVEL) { \ int tmp_errno = errno; \ jk_log((l), JK_LOG_TRACE, "exit"); \ errno = tmp_errno; \ } } while (0) #endif /* JK_PRODUCTION */ #define JK_LOG_NULL_PARAMS(l) jk_log((l), JK_LOG_ERROR, "NULL parameters") /* Debug level macro * It is more efficient to check the level prior * calling function that will not execute anyhow because of level */ #define JK_IS_DEBUG_LEVEL(l) ((l) && (l)->level < JK_LOG_INFO_LEVEL) #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_LOGGER_H */ tomcat-connectors-1.2.41-src/native/common/jk_shm.h0000644000000000000020000001714612477544555020550 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Shared Memory object header file * * Author: Mladen Turk * * Author: Rainer Jung * * Version: $Revision: 1665454 $ * ***************************************************************************/ #ifndef _JK_SHM_H #define _JK_SHM_H #include "jk_global.h" #include "jk_pool.h" #include "jk_util.h" #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ /** * @file jk_shm.h * @brief Jk shared memory management * * */ #define JK_SHM_MAJOR '1' #define JK_SHM_MINOR '3' #define JK_SHM_STR_SIZ (JK_ALIGN(JK_MAX_NAME_LEN + 1, 8)) #define JK_SHM_MAGIC '!', 'J', 'K', 'S', 'H', 'M', JK_SHM_MAJOR, JK_SHM_MINOR #define JK_SHM_MAGIC_SIZ 8 /* XXX: Check if adding struct members for overflow */ #define JK_SHM_SLOT_SIZE 384 /* Really huge numbers, but 64 workers should be enough */ #define JK_SHM_DEF_WORKERS 64 #define JK_SHM_ALIGNMENT JK_SHM_SLOT_SIZE #define JK_SHM_ALIGN(x) JK_ALIGN((x), JK_SHM_ALIGNMENT) #define JK_SHM_MIN_SIZE ((JK_SHM_SLOT_SIZE * JK_SHM_DEF_WORKERS * 3) + JK_SHM_ALIGNMENT) /** jk shm generic worker record structure */ struct jk_shm_worker_header { /* Shared memory slot id */ int id; /* JK_XXX_WORKER_TYPE */ int type; /* worker name */ char name[JK_SHM_STR_SIZ]; /* parent slot id. * Zero in case worker does not belong to balancer. */ int parent_id; /* Sequence counter starting at 0 and increasing * every time we change the config. */ volatile unsigned int sequence; }; typedef struct jk_shm_worker_header jk_shm_worker_header_t; /** jk shm ajp13/ajp14 worker record structure */ struct jk_shm_ajp_worker { jk_shm_worker_header_t h; char host[JK_SHM_STR_SIZ]; int port; volatile int addr_sequence; /* Configuration data mirrored from ajp_worker */ int cache_timeout; int connect_timeout; int ping_timeout; int reply_timeout; int prepost_timeout; unsigned int recovery_opts; int retries; int retry_interval; int busy_limit; unsigned int max_packet_size; /* current error state (runtime) of the worker */ volatile int state; /* Statistical data */ /* Number of currently connected channels */ volatile int connected; /* Maximum number of connected channels */ volatile int max_connected; /* Number of currently busy channels */ volatile int busy; /* Maximum number of busy channels */ volatile int max_busy; volatile time_t error_time; /* Number of bytes read from remote */ volatile jk_uint64_t readed; /* Number of bytes transferred to remote */ volatile jk_uint64_t transferred; /* Number of times the worker was used */ volatile jk_uint64_t used; /* Number of times the worker was used - snapshot during maintenance */ volatile jk_uint64_t used_snapshot; /* Number of non 200 responses */ volatile jk_uint32_t errors; /* Decayed number of reply_timeout errors */ volatile jk_uint32_t reply_timeouts; /* Number of client errors */ volatile jk_uint32_t client_errors; /* Last reset time */ volatile time_t last_reset; volatile time_t last_maintain_time; }; typedef struct jk_shm_ajp_worker jk_shm_ajp_worker_t; /** jk shm lb sub worker record structure */ struct jk_shm_lb_sub_worker { jk_shm_worker_header_t h; /* route */ char route[JK_SHM_STR_SIZ]; /* worker domain */ char domain[JK_SHM_STR_SIZ]; /* worker redirect route */ char redirect[JK_SHM_STR_SIZ]; /* worker distance */ volatile int distance; /* current activation state (config) of the worker */ volatile int activation; /* current error state (runtime) of the worker */ volatile int state; /* Current lb factor */ volatile int lb_factor; /* Current lb reciprocal factor */ volatile jk_uint64_t lb_mult; /* Current lb value */ volatile jk_uint64_t lb_value; /* First consecutive error time */ volatile time_t first_error_time; /* Last consecutive error time */ volatile time_t last_error_time; /* Number of times the worker was elected - snapshot during maintenance */ volatile jk_uint64_t elected_snapshot; /* Number of non-sticky requests handled, that were not marked as stateless */ volatile jk_uint64_t sessions; /* Number of non 200 responses */ volatile jk_uint32_t errors; }; typedef struct jk_shm_lb_sub_worker jk_shm_lb_sub_worker_t; /** jk shm lb worker record structure */ struct jk_shm_lb_worker { jk_shm_worker_header_t h; /* Number of currently busy channels */ volatile int busy; /* Maximum number of busy channels */ volatile int max_busy; int sticky_session; int sticky_session_force; int recover_wait_time; int error_escalation_time; int max_reply_timeouts; int retries; int retry_interval; int lbmethod; int lblock; unsigned int max_packet_size; /* Last reset time */ volatile time_t last_reset; volatile time_t last_maintain_time; }; typedef struct jk_shm_lb_worker jk_shm_lb_worker_t; const char *jk_shm_name(void); /* Calculate needed shm size */ int jk_shm_calculate_size(jk_map_t *init_data, jk_logger_t *l); /* Open the shared memory creating file if needed */ int jk_shm_open(const char *fname, int sz, jk_logger_t *l); /* Close the shared memory */ void jk_shm_close(jk_logger_t *l); /* Attach the shared memory in child process. * File has to be opened in parent. */ int jk_shm_attach(const char *fname, int sz, jk_logger_t *l); /* allocate shm ajp worker record * If there is no shm present the pool will be used instead */ jk_shm_ajp_worker_t *jk_shm_alloc_ajp_worker(jk_pool_t *p, const char *name, jk_logger_t *l); /* allocate shm lb sub worker record * If there is no shm present the pool will be used instead */ jk_shm_lb_sub_worker_t *jk_shm_alloc_lb_sub_worker(jk_pool_t *p, int lb_id, const char *name, jk_logger_t *l); /* allocate shm lb worker record * If there is no shm present the pool will be used instead */ jk_shm_lb_worker_t *jk_shm_alloc_lb_worker(jk_pool_t *p, const char *name, jk_logger_t *l); int jk_shm_check_maintain(time_t trigger); /* Lock shared memory for thread safe access */ int jk_shm_lock(void); /* Unlock shared memory for thread safe access */ int jk_shm_unlock(void); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* _JK_SHM_H */ tomcat-connectors-1.2.41-src/native/common/jk_connect.c0000644000000000000020000013224712465671172021376 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * Description: Socket/Naming manipulation functions * Based on: Various Jserv files */ /** * @package jk_connect * @author Gal Shachor * @author Mladen Turk * @version $Revision: 1658173 $ */ #include "jk_connect.h" #include "jk_util.h" #ifdef HAVE_APR #include "apr_network_io.h" #include "apr_errno.h" #include "apr_general.h" #include "apr_pools.h" static apr_pool_t *jk_apr_pool = NULL; #endif #ifdef HAVE_SYS_FILIO_H /* FIONREAD on Solaris et al. */ #include #endif #ifdef HAVE_POLL_H /* Use poll instead select */ #include #endif #if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) #define JK_IS_SOCKET_ERROR(x) ((x) == SOCKET_ERROR) #define JK_GET_SOCKET_ERRNO() errno = WSAGetLastError() - WSABASEERR #else #define JK_IS_SOCKET_ERROR(x) ((x) == -1) #define JK_GET_SOCKET_ERRNO() ((void)0) #endif /* WIN32 */ #if defined(NETWARE) && defined(__NOVELL_LIBC__) #define USE_SOCK_CLOEXEC #endif #ifndef INET6_ADDRSTRLEN /* Maximum size of an IPv6 address in ASCII */ #define INET6_ADDRSTRLEN 46 #endif /* 2 IPv6 adresses of length (INET6_ADDRSTRLEN-1) * each suffixed with a ":" and a port (5 digits) * plus " -> " plus terminating "\0" */ #define DUMP_SINFO_BUF_SZ (2 * (INET6_ADDRSTRLEN - 1 + 1 + 5) + 4 + 1) #ifndef IN6ADDRSZ #define IN6ADDRSZ 16 #endif #ifndef INT16SZ #define INT16SZ sizeof(short) #endif #if !defined(EAFNOSUPPORT) && defined(WSAEAFNOSUPPORT) #define EAFNOSUPPORT WSAEAFNOSUPPORT #endif /* our compiler cant deal with char* <-> const char* ... */ #if defined(NETWARE) && !defined(__NOVELL_LIBC__) typedef char* SET_TYPE; #else typedef const char* SET_TYPE; #endif /** Set socket to blocking * @param sd socket to manipulate * @return errno: fcntl returns -1 (!WIN32) * pseudo errno: ioctlsocket returns SOCKET_ERROR (WIN32) * 0: success */ static int soblock(jk_sock_t sd) { /* BeOS uses setsockopt at present for non blocking... */ #if defined (WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) u_long on = 0; if (JK_IS_SOCKET_ERROR(ioctlsocket(sd, FIONBIO, &on))) { JK_GET_SOCKET_ERRNO(); return errno; } #else int fd_flags; fd_flags = fcntl(sd, F_GETFL, 0); #if defined(O_NONBLOCK) fd_flags &= ~O_NONBLOCK; #elif defined(O_NDELAY) fd_flags &= ~O_NDELAY; #elif defined(FNDELAY) fd_flags &= ~FNDELAY; #else #error Please teach JK how to make sockets blocking on your platform. #endif if (fcntl(sd, F_SETFL, fd_flags) == -1) { return errno; } #endif /* WIN32 || (NETWARE && __NOVELL_LIBC__) */ return 0; } /** Set socket to non-blocking * @param sd socket to manipulate * @return errno: fcntl returns -1 (!WIN32) * pseudo errno: ioctlsocket returns SOCKET_ERROR (WIN32) * 0: success */ static int sononblock(jk_sock_t sd) { #if defined (WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) u_long on = 1; if (JK_IS_SOCKET_ERROR(ioctlsocket(sd, FIONBIO, &on))) { JK_GET_SOCKET_ERRNO(); return errno; } #else int fd_flags; fd_flags = fcntl(sd, F_GETFL, 0); #if defined(O_NONBLOCK) fd_flags |= O_NONBLOCK; #elif defined(O_NDELAY) fd_flags |= O_NDELAY; #elif defined(FNDELAY) fd_flags |= FNDELAY; #else #error Please teach JK how to make sockets non-blocking on your platform. #endif if (fcntl(sd, F_SETFL, fd_flags) == -1) { return errno; } #endif /* WIN32 || (NETWARE && __NOVELL_LIBC__) */ return 0; } #if defined (WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) /* WIN32 implementation */ /** Non-blocking socket connect * @param sd socket to connect * @param addr address to connect to * @param source optional source address * @param timeout connect timeout in seconds * (<=0: no timeout=blocking) * @param l logger * @return -1: some kind of error occured * SOCKET_ERROR: no timeout given and error * during blocking connect * 0: success */ static int nb_connect(jk_sock_t sd, jk_sockaddr_t *addr, jk_sockaddr_t *source, int timeout, jk_logger_t *l) { int rc; char buf[64]; JK_TRACE_ENTER(l); if (source != NULL) { if (bind(sd, (const struct sockaddr *)&source->sa.sin, source->salen)) { JK_GET_SOCKET_ERRNO(); jk_log(l, JK_LOG_ERROR, "error during source bind on socket %d [%s] (errno=%d)", sd, jk_dump_hinfo(source, buf, sizeof(buf)), errno); } } if (timeout <= 0) { rc = connect(sd, (const struct sockaddr *)&addr->sa.sin, addr->salen); JK_TRACE_EXIT(l); return rc; } if ((rc = sononblock(sd))) { JK_TRACE_EXIT(l); return -1; } if (JK_IS_SOCKET_ERROR(connect(sd, (const struct sockaddr *)&addr->sa.sin, addr->salen))) { struct timeval tv; fd_set wfdset, efdset; if ((rc = WSAGetLastError()) != WSAEWOULDBLOCK) { soblock(sd); WSASetLastError(rc); JK_TRACE_EXIT(l); return -1; } /* wait for the connect to complete or timeout */ FD_ZERO(&wfdset); FD_SET(sd, &wfdset); FD_ZERO(&efdset); FD_SET(sd, &efdset); tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; rc = select((int)sd + 1, NULL, &wfdset, &efdset, &tv); if (JK_IS_SOCKET_ERROR(rc) || rc == 0) { rc = WSAGetLastError(); soblock(sd); WSASetLastError(rc); JK_TRACE_EXIT(l); return -1; } /* Evaluate the efdset */ if (FD_ISSET(sd, &efdset)) { /* The connect failed. */ int rclen = (int)sizeof(rc); if (getsockopt(sd, SOL_SOCKET, SO_ERROR, (char*) &rc, &rclen)) rc = 0; soblock(sd); if (rc) WSASetLastError(rc); JK_TRACE_EXIT(l); return -1; } } soblock(sd); JK_TRACE_EXIT(l); return 0; } #elif !defined(NETWARE) /* POSIX implementation */ /** Non-blocking socket connect * @param sd socket to connect * @param addr address to connect to * @param source optional source address * @param timeout connect timeout in seconds * (<=0: no timeout=blocking) * @param l logger * @return -1: some kind of error occured * 0: success */ static int nb_connect(jk_sock_t sd, jk_sockaddr_t *addr, jk_sockaddr_t *source, int timeout, jk_logger_t *l) { int rc = 0; char buf[64]; JK_TRACE_ENTER(l); if (source != NULL) { if (bind(sd, (const struct sockaddr *)&source->sa.sin, source->salen)) { JK_GET_SOCKET_ERRNO(); jk_log(l, JK_LOG_ERROR, "error during source bind on socket %d [%s] (errno=%d)", sd, jk_dump_hinfo(source, buf, sizeof(buf)), errno); } } if (timeout > 0) { if (sononblock(sd)) { JK_TRACE_EXIT(l); return -1; } } do { rc = connect(sd, (const struct sockaddr *)&addr->sa.sin, addr->salen); } while (rc == -1 && errno == EINTR); if ((rc == -1) && (errno == EINPROGRESS || errno == EALREADY) && (timeout > 0)) { fd_set wfdset; struct timeval tv; socklen_t rclen = (socklen_t)sizeof(rc); FD_ZERO(&wfdset); FD_SET(sd, &wfdset); tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; rc = select(sd + 1, NULL, &wfdset, NULL, &tv); if (rc <= 0) { /* Save errno */ int err = errno; soblock(sd); errno = err; JK_TRACE_EXIT(l); return -1; } rc = 0; #ifdef SO_ERROR if (!FD_ISSET(sd, &wfdset) || (getsockopt(sd, SOL_SOCKET, SO_ERROR, (char *)&rc, &rclen) < 0) || rc) { if (rc) errno = rc; rc = -1; } #endif /* SO_ERROR */ } /* Not sure we can be already connected */ if (rc == -1 && errno == EISCONN) rc = 0; soblock(sd); JK_TRACE_EXIT(l); return rc; } #else /* NETWARE implementation - blocking for now */ /** Non-blocking socket connect * @param sd socket to connect * @param addr address to connect to * @param source optional source address * @param timeout connect timeout in seconds (ignored!) * @param l logger * @return -1: some kind of error occured * 0: success */ static int nb_connect(jk_sock_t sd, jk_sockaddr_t *addr, jk_sockaddr_t *source, int timeout, jk_logger_t *l) { int rc; char buf[64]; JK_TRACE_ENTER(l); if (source != NULL) { if (bind(sd, (const struct sockaddr *)&source->sa.sin, source->salen)) { JK_GET_SOCKET_ERRNO(); jk_log(l, JK_LOG_ERROR, "error during source bind on socket %d [%s] (errno=%d)", sd, jk_dump_hinfo(source, buf, sizeof(buf)), errno); } } rc = connect(sd, (const struct sockaddr *)&addr->sa.sin, addr->salen); JK_TRACE_EXIT(l); return rc; } #endif #ifdef AS400_UTF8 /* * i5/OS V5R4 need EBCDIC for its runtime calls but APR/APACHE works in UTF */ in_addr_t jk_inet_addr(const char * addrstr) { in_addr_t addr; char *ptr; ptr = (char *)malloc(strlen(addrstr) + 1); jk_ascii2ebcdic((char *)addrstr, ptr); addr = inet_addr(ptr); free(ptr); return(addr); } #endif /** Clone a jk_sockaddr_t * @param out The source structure * @param in The target structure */ void jk_clone_sockaddr(jk_sockaddr_t *out, jk_sockaddr_t *in) { memcpy(out, in, sizeof(*in)); /* The ipaddr_ptr member points to memory inside the struct. * Do not copy the pointer but use the same offset relative * to the struct start */ out->ipaddr_ptr = (char *)out + ((char *)in->ipaddr_ptr - (char *)in); } /** Resolve the host IP * @param host host or ip address * @param port port * @param rc return value pointer * @param l logger * @return JK_FALSE: some kind of error occured * JK_TRUE: success */ int jk_resolve(const char *host, int port, jk_sockaddr_t *saddr, void *pool, int prefer_ipv6, jk_logger_t *l) { int family = JK_INET; struct in_addr iaddr; JK_TRACE_ENTER(l); memset(saddr, 0, sizeof(jk_sockaddr_t)); if (*host >= '0' && *host <= '9' && strspn(host, "0123456789.") == strlen(host)) { /* If we found only digits we use inet_addr() */ iaddr.s_addr = jk_inet_addr(host); memcpy(&(saddr->sa.sin.sin_addr), &iaddr, sizeof(struct in_addr)); } else { #ifdef HAVE_APR apr_sockaddr_t *remote_sa, *temp_sa; if (!jk_apr_pool) { if (apr_pool_create(&jk_apr_pool, (apr_pool_t *)pool) != APR_SUCCESS) { JK_TRACE_EXIT(l); return JK_FALSE; } } apr_pool_clear(jk_apr_pool); if (apr_sockaddr_info_get(&remote_sa, host, APR_UNSPEC, (apr_port_t)port, 0, jk_apr_pool) != APR_SUCCESS) { JK_TRACE_EXIT(l); return JK_FALSE; } /* Check if we have multiple address matches */ if (remote_sa->next) { /* Since we are only handling JK_INET (IPV4) address (in_addr_t) */ /* make sure we find one of those. */ temp_sa = remote_sa; #if APR_HAVE_IPV6 if (prefer_ipv6) { while ((NULL != temp_sa) && (APR_INET6 != temp_sa->family)) temp_sa = temp_sa->next; } #endif if (NULL != temp_sa) { remote_sa = temp_sa; } else { while ((NULL != temp_sa) && (APR_INET != temp_sa->family)) temp_sa = temp_sa->next; #if APR_HAVE_IPV6 if (NULL == temp_sa) { temp_sa = remote_sa; while ((NULL != temp_sa) && (APR_INET6 != temp_sa->family)) temp_sa = temp_sa->next; } #endif } /* if temp_sa is set, we have a valid address otherwise, just return */ if (NULL != temp_sa) { remote_sa = temp_sa; } else { JK_TRACE_EXIT(l); return JK_FALSE; } } if (remote_sa->family == APR_INET) { saddr->sa.sin = remote_sa->sa.sin; family = JK_INET; } #if APR_HAVE_IPV6 else { saddr->sa.sin6 = remote_sa->sa.sin6; family = JK_INET6; } #endif #else /* HAVE_APR */ /* Without APR go the classic way. */ #if defined(HAVE_GETADDRINFO) /* TODO: * 1. Check for numeric IPV6 addresses * 2. Do we need to set service name for getaddrinfo? */ struct addrinfo hints, *ai_list, *ai = NULL; int error; char pbuf[12]; char *pbufptr = NULL; memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; #if JK_HAVE_IPV6 if (strchr(host, ':')) { /* If host name contains collon this must be IPV6 address. * Set prefer_ipv6 flag in this case if it wasn't set already */ prefer_ipv6 = 1; } if (prefer_ipv6) hints.ai_family = JK_INET6; else #endif hints.ai_family = JK_INET; if (port > 0) { snprintf(pbuf, sizeof(pbuf), "%d", port); pbufptr = pbuf; } error = getaddrinfo(host, pbufptr, &hints, &ai_list); #if JK_HAVE_IPV6 /* XXX: * Is the check for EAI_FAMILY/WSAEAFNOSUPPORT correct * way to retry the IPv4 address? */ if (error == EAI_FAMILY && prefer_ipv6) { hints.ai_family = JK_INET; error = getaddrinfo(host, pbufptr, &hints, &ai_list); } #endif if (error) { JK_TRACE_EXIT(l); errno = error; return JK_FALSE; } #if JK_HAVE_IPV6 if (prefer_ipv6) { ai = ai_list; while (ai) { if (ai->ai_family == JK_INET6) { /* ignore elements without required address info */ if((ai->ai_addr != NULL) && (ai->ai_addrlen > 0)) { family = JK_INET6; break; } } ai = ai->ai_next; } } #endif if (ai == NULL) { ai = ai_list; while (ai) { if (ai->ai_family == JK_INET) { /* ignore elements without required address info */ if((ai->ai_addr != NULL) && (ai->ai_addrlen > 0)) { family = JK_INET; break; } } ai = ai->ai_next; } } if (ai == NULL) { /* No address found * XXX: Use better error code? */ freeaddrinfo(ai_list); JK_TRACE_EXIT(l); errno = ENOENT; return JK_FALSE; } memcpy(&(saddr->sa), ai->ai_addr, ai->ai_addrlen); freeaddrinfo(ai_list); #else /* HAVE_GETADDRINFO */ struct hostent *hoste; /* XXX : WARNING : We should really use gethostbyname_r in multi-threaded env */ /* Fortunatly when APR is available, ie under Apache 2.0, we use it */ #if defined(NETWARE) && !defined(__NOVELL_LIBC__) hoste = gethostbyname((char*)host); #else hoste = gethostbyname(host); #endif if (!hoste) { JK_TRACE_EXIT(l); return JK_FALSE; } iaddr = *((struct in_addr *)hoste->h_addr_list[0]); memcpy(&(saddr->sa.sin.sin_addr), &iaddr, sizeof(struct in_addr)); #endif /* HAVE_GETADDRINFO */ #endif /* HAVE_APR */ } if (family == JK_INET) { saddr->ipaddr_ptr = &(saddr->sa.sin.sin_addr); saddr->ipaddr_len = (int)sizeof(struct in_addr); saddr->salen = (int)sizeof(struct sockaddr_in); } #if JK_HAVE_IPV6 else { saddr->ipaddr_ptr = &(saddr->sa.sin6.sin6_addr); saddr->ipaddr_len = (int)sizeof(struct in6_addr); saddr->salen = (int)sizeof(struct sockaddr_in6); } #endif saddr->sa.sin.sin_family = family; /* XXX IPv6: assumes sin_port and sin6_port at same offset */ saddr->sa.sin.sin_port = htons(port); saddr->port = port; saddr->family = family; JK_TRACE_EXIT(l); return JK_TRUE; } /** Connect to Tomcat * @param addr address to connect to * @param keepalive should we set SO_KEEPALIVE (if !=0) * @param timeout connect timeout in seconds * (<=0: no timeout=blocking) * @param sock_buf size of send and recv buffer * (<=0: use default) * @param l logger * @return JK_INVALID_SOCKET: some kind of error occured * created socket: success * @remark Cares about errno */ jk_sock_t jk_open_socket(jk_sockaddr_t *addr, jk_sockaddr_t *source, int keepalive, int timeout, int connect_timeout, int sock_buf, jk_logger_t *l) { char buf[DUMP_SINFO_BUF_SZ]; jk_sock_t sd; int set = 1; int ret = 0; int flags = 0; #ifdef SO_LINGER struct linger li; #endif JK_TRACE_ENTER(l); errno = 0; #if defined(SOCK_CLOEXEC) && defined(USE_SOCK_CLOEXEC) flags |= SOCK_CLOEXEC; #endif sd = socket(addr->family, SOCK_STREAM | flags, 0); if (!IS_VALID_SOCKET(sd)) { JK_GET_SOCKET_ERRNO(); jk_log(l, JK_LOG_ERROR, "socket() failed (errno=%d)", errno); JK_TRACE_EXIT(l); return JK_INVALID_SOCKET; } #if defined(FD_CLOEXEC) && !defined(USE_SOCK_CLOEXEC) if ((flags = fcntl(sd, F_GETFD)) == -1) { JK_GET_SOCKET_ERRNO(); jk_log(l, JK_LOG_ERROR, "fcntl() failed (errno=%d)", errno); jk_close_socket(sd, l); JK_TRACE_EXIT(l); return JK_INVALID_SOCKET; } flags |= FD_CLOEXEC; if (fcntl(sd, F_SETFD, flags) == -1) { JK_GET_SOCKET_ERRNO(); jk_log(l, JK_LOG_ERROR, "fcntl() failed (errno=%d)", errno); jk_close_socket(sd, l); JK_TRACE_EXIT(l); return JK_INVALID_SOCKET; } #endif /* Disable Nagle algorithm */ if (setsockopt(sd, IPPROTO_TCP, TCP_NODELAY, (SET_TYPE)&set, sizeof(set))) { JK_GET_SOCKET_ERRNO(); jk_log(l, JK_LOG_ERROR, "failed setting TCP_NODELAY (errno=%d)", errno); jk_close_socket(sd, l); JK_TRACE_EXIT(l); return JK_INVALID_SOCKET; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "socket TCP_NODELAY set to On"); if (keepalive) { #if defined(WIN32) && !defined(NETWARE) DWORD dw; struct tcp_keepalive ka = { 0 }, ks = { 0 }; if (timeout) ka.keepalivetime = timeout * 10000; else ka.keepalivetime = 60 * 10000; /* 10 minutes */ ka.keepaliveinterval = 1000; ka.onoff = 1; if (WSAIoctl(sd, SIO_KEEPALIVE_VALS, &ka, sizeof(ka), &ks, sizeof(ks), &dw, NULL, NULL)) { JK_GET_SOCKET_ERRNO(); jk_log(l, JK_LOG_ERROR, "failed setting SIO_KEEPALIVE_VALS (errno=%d)", errno); jk_close_socket(sd, l); JK_TRACE_EXIT(l); return JK_INVALID_SOCKET; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "socket SO_KEEPALIVE set to %d seconds", ka.keepalivetime / 1000); #else set = 1; if (setsockopt(sd, SOL_SOCKET, SO_KEEPALIVE, (SET_TYPE)&set, sizeof(set))) { JK_GET_SOCKET_ERRNO(); jk_log(l, JK_LOG_ERROR, "failed setting SO_KEEPALIVE (errno=%d)", errno); jk_close_socket(sd, l); JK_TRACE_EXIT(l); return JK_INVALID_SOCKET; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "socket SO_KEEPALIVE set to On"); #endif } if (sock_buf > 0) { set = sock_buf; /* Set socket send buffer size */ if (setsockopt(sd, SOL_SOCKET, SO_SNDBUF, (SET_TYPE)&set, sizeof(set))) { JK_GET_SOCKET_ERRNO(); jk_log(l, JK_LOG_ERROR, "failed setting SO_SNDBUF (errno=%d)", errno); jk_close_socket(sd, l); JK_TRACE_EXIT(l); return JK_INVALID_SOCKET; } set = sock_buf; /* Set socket receive buffer size */ if (setsockopt(sd, SOL_SOCKET, SO_RCVBUF, (SET_TYPE)&set, sizeof(set))) { JK_GET_SOCKET_ERRNO(); jk_log(l, JK_LOG_ERROR, "failed setting SO_RCVBUF (errno=%d)", errno); jk_close_socket(sd, l); JK_TRACE_EXIT(l); return JK_INVALID_SOCKET; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "socket SO_SNDBUF and SO_RCVBUF set to %d", sock_buf); } if (timeout > 0) { #if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) int tmout = timeout * 1000; setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (const char *) &tmout, sizeof(int)); setsockopt(sd, SOL_SOCKET, SO_SNDTIMEO, (const char *) &tmout, sizeof(int)); JK_GET_SOCKET_ERRNO(); #elif defined(SO_RCVTIMEO) && defined(USE_SO_RCVTIMEO) && defined(SO_SNDTIMEO) && defined(USE_SO_SNDTIMEO) struct timeval tv; tv.tv_sec = timeout; tv.tv_usec = 0; setsockopt(sd, SOL_SOCKET, SO_RCVTIMEO, (const void *) &tv, sizeof(tv)); setsockopt(sd, SOL_SOCKET, SO_SNDTIMEO, (const void *) &tv, sizeof(tv)); #endif if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "timeout %d set for socket=%d", timeout, sd); } #ifdef SO_NOSIGPIPE /* The preferred method on Mac OS X (10.2 and later) to prevent SIGPIPEs when * sending data to a dead peer. Possibly also existing and in use on other BSD * systems? */ set = 1; if (setsockopt(sd, SOL_SOCKET, SO_NOSIGPIPE, (const char *)&set, sizeof(int))) { JK_GET_SOCKET_ERRNO(); jk_log(l, JK_LOG_ERROR, "failed setting SO_NOSIGPIPE (errno=%d)", errno); jk_close_socket(sd, l); JK_TRACE_EXIT(l); return JK_INVALID_SOCKET; } #endif #ifdef SO_LINGER /* Make hard closesocket by disabling lingering */ li.l_linger = li.l_onoff = 0; if (setsockopt(sd, SOL_SOCKET, SO_LINGER, (SET_TYPE)&li, sizeof(li))) { JK_GET_SOCKET_ERRNO(); jk_log(l, JK_LOG_ERROR, "failed setting SO_LINGER (errno=%d)", errno); jk_close_socket(sd, l); JK_TRACE_EXIT(l); return JK_INVALID_SOCKET; } #endif /* Tries to connect to Tomcat (continues trying while error is EINTR) */ if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "trying to connect socket %d to %s", sd, jk_dump_hinfo(addr, buf, sizeof(buf))); /* Need more infos for BSD 4.4 and Unix 98 defines, for now only iSeries when Unix98 is required at compile time */ #if (_XOPEN_SOURCE >= 520) && defined(AS400) ((struct sockaddr *)addr)->sa.sin.sa_len = sizeof(struct sockaddr_in); #endif ret = nb_connect(sd, addr, source, connect_timeout, l); #if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) if (JK_IS_SOCKET_ERROR(ret)) { JK_GET_SOCKET_ERRNO(); } #endif /* WIN32 */ /* Check if we are connected */ if (ret) { jk_log(l, JK_LOG_INFO, "connect to %s failed (errno=%d)", jk_dump_hinfo(addr, buf, sizeof(buf)), errno); jk_close_socket(sd, l); sd = JK_INVALID_SOCKET; } else { if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "socket %d [%s] connected", sd, jk_dump_sinfo(sd, buf, sizeof(buf))); } JK_TRACE_EXIT(l); return sd; } /** Close the socket * @param sd socket to close * @param l logger * @return -1: some kind of error occured (!WIN32) * SOCKET_ERROR: some kind of error occured (WIN32) * 0: success * @remark Does not change errno */ int jk_close_socket(jk_sock_t sd, jk_logger_t *l) { int rc; int save_errno; JK_TRACE_ENTER(l); if (!IS_VALID_SOCKET(sd)) { JK_TRACE_EXIT(l); return -1; } save_errno = errno; #if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) rc = closesocket(sd) ? -1 : 0; #else do { rc = close(sd); } while (JK_IS_SOCKET_ERROR(rc) && (errno == EINTR || errno == EAGAIN)); #endif JK_TRACE_EXIT(l); errno = save_errno; return rc; } #ifndef MAX_SECS_TO_LINGER #define MAX_SECS_TO_LINGER 2 #endif #ifndef MS_TO_LINGER #define MS_TO_LINGER 100 #endif #ifndef MS_TO_LINGER_LAST #define MS_TO_LINGER_LAST 20 #endif #ifndef MAX_READ_RETRY #define MAX_READ_RETRY 10 #endif #ifndef MAX_LINGER_BYTES #define MAX_LINGER_BYTES 32768 #endif #ifndef SHUT_WR #ifdef SD_SEND #define SHUT_WR SD_SEND #else #define SHUT_WR 0x01 #endif #endif #ifndef SHUT_RD #ifdef SD_RECEIVE #define SHUT_RD SD_RECEIVE #else #define SHUT_RD 0x00 #endif #endif /** Drain and close the socket * @param sd socket to close * @param l logger * @return -1: socket to close is invalid * -1: some kind of error occured (!WIN32) * SOCKET_ERROR: some kind of error occured (WIN32) * 0: success * @remark Does not change errno */ int jk_shutdown_socket(jk_sock_t sd, jk_logger_t *l) { char dummy[512]; char buf[DUMP_SINFO_BUF_SZ]; char *sb = NULL; int rc = 0; size_t rd = 0; size_t rp = 0; int save_errno; int timeout = MS_TO_LINGER; time_t start = time(NULL); JK_TRACE_ENTER(l); if (!IS_VALID_SOCKET(sd)) { JK_TRACE_EXIT(l); return -1; } save_errno = errno; if (JK_IS_DEBUG_LEVEL(l)) { sb = jk_dump_sinfo(sd, buf, sizeof(buf)); jk_log(l, JK_LOG_DEBUG, "About to shutdown socket %d [%s]", sd, sb); } /* Shut down the socket for write, which will send a FIN * to the peer. */ if (shutdown(sd, SHUT_WR)) { rc = jk_close_socket(sd, l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Failed sending SHUT_WR for socket %d [%s]", sd, sb); errno = save_errno; JK_TRACE_EXIT(l); return rc; } do { rp = 0; if (jk_is_input_event(sd, timeout, l)) { /* Do a restartable read on the socket * draining out all the data currently in the socket buffer. */ int num = 0; do { num++; #if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) rc = recv(sd, &dummy[0], sizeof(dummy), 0); if (JK_IS_SOCKET_ERROR(rc)) JK_GET_SOCKET_ERRNO(); #else rc = read(sd, &dummy[0], sizeof(dummy)); #endif if (rc > 0) rp += rc; } while (JK_IS_SOCKET_ERROR(rc) && (errno == EINTR || errno == EAGAIN) && num < MAX_READ_RETRY); if (rc < 0) { /* Read failed. * Bail out from the loop. */ break; } } else { /* Error or timeout (reason is logged within jk_is_input_event) * Exit the drain loop */ break; } rd += rp; if (rp < sizeof(dummy)) { if (timeout > MS_TO_LINGER_LAST) { /* Try one last time with a short timeout */ timeout = MS_TO_LINGER_LAST; continue; } /* We have read less then size of buffer * It's a good chance there will be no more data * to read. */ if ((rc = sononblock(sd))) { rc = jk_close_socket(sd, l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "error setting socket %d [%s] to nonblocking", sd, sb); errno = save_errno; JK_TRACE_EXIT(l); return rc; } if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "shutting down the read side of socket %d [%s]", sd, sb); shutdown(sd, SHUT_RD); break; } timeout = MS_TO_LINGER; } while ((rd < MAX_LINGER_BYTES) && (difftime(time(NULL), start) < MAX_SECS_TO_LINGER)); rc = jk_close_socket(sd, l); if (JK_IS_DEBUG_LEVEL(l)) jk_log(l, JK_LOG_DEBUG, "Shutdown socket %d [%s] and read %d lingering bytes in %d sec.", sd, sb, rd, (int)difftime(time(NULL), start)); errno = save_errno; JK_TRACE_EXIT(l); return rc; } /** send a message * @param sd socket to use * @param b buffer containing the data * @param len length to send * @param l logger * @return negative errno: write returns a fatal -1 (!WIN32) * negative pseudo errno: send returns SOCKET_ERROR (WIN32) * JK_SOCKET_EOF: no bytes could be sent * >0: success, provided number of bytes send * @remark Always closes socket in case of error * @remark Cares about errno * @bug this fails on Unixes if len is too big for the underlying * protocol */ int jk_tcp_socket_sendfull(jk_sock_t sd, const unsigned char *b, int len, jk_logger_t *l) { int sent = 0; int wr; JK_TRACE_ENTER(l); errno = 0; while (sent < len) { do { #if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) wr = send(sd, (const char*)(b + sent), len - sent, 0); if (JK_IS_SOCKET_ERROR(wr)) JK_GET_SOCKET_ERRNO(); #else wr = write(sd, b + sent, len - sent); #endif } while (JK_IS_SOCKET_ERROR(wr) && (errno == EINTR || errno == EAGAIN)); if (JK_IS_SOCKET_ERROR(wr)) { int err; jk_shutdown_socket(sd, l); err = (errno > 0) ? -errno : errno; JK_TRACE_EXIT(l); return err; } else if (wr == 0) { jk_shutdown_socket(sd, l); JK_TRACE_EXIT(l); return JK_SOCKET_EOF; } sent += wr; } JK_TRACE_EXIT(l); return sent; } /** receive a message * @param sd socket to use * @param b buffer to store the data * @param len length to receive * @param l logger * @return negative errno: read returns a fatal -1 (!WIN32) * negative pseudo errno: recv returns SOCKET_ERROR (WIN32) * JK_SOCKET_EOF: no bytes could be read * >0: success, requested number of bytes received * @remark Always closes socket in case of error * @remark Cares about errno */ int jk_tcp_socket_recvfull(jk_sock_t sd, unsigned char *b, int len, jk_logger_t *l) { int rdlen = 0; int rd; JK_TRACE_ENTER(l); errno = 0; while (rdlen < len) { do { #if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) rd = recv(sd, (char *)b + rdlen, len - rdlen, 0); if (JK_IS_SOCKET_ERROR(rd)) JK_GET_SOCKET_ERRNO(); #else rd = read(sd, (char *)b + rdlen, len - rdlen); #endif } while (JK_IS_SOCKET_ERROR(rd) && errno == EINTR); if (JK_IS_SOCKET_ERROR(rd)) { int err = (errno > 0) ? -errno : errno; jk_shutdown_socket(sd, l); JK_TRACE_EXIT(l); return (err == 0) ? JK_SOCKET_EOF : err; } else if (rd == 0) { jk_shutdown_socket(sd, l); JK_TRACE_EXIT(l); return JK_SOCKET_EOF; } rdlen += rd; } JK_TRACE_EXIT(l); return rdlen; } /* const char * * inet_ntop4(src, dst, size) * format an IPv4 address, more or less like inet_ntoa() * return: * `dst' (as a const) * notes: * (1) uses no statics * (2) takes a u_char* not an in_addr as input * author: * Paul Vixie, 1996. */ static const char *inet_ntop4(const unsigned char *src, char *dst, size_t size) { const size_t MIN_SIZE = 16; /* space for 255.255.255.255\0 */ int n = 0; char *next = dst; if (size < MIN_SIZE) { errno = ENOSPC; return NULL; } do { unsigned char u = *src++; if (u > 99) { *next++ = '0' + u/100; u %= 100; *next++ = '0' + u/10; u %= 10; } else if (u > 9) { *next++ = '0' + u/10; u %= 10; } *next++ = '0' + u; *next++ = '.'; n++; } while (n < 4); *--next = '\0'; return dst; } #if JK_HAVE_IPV6 /* const char * * inet_ntop6(src, dst, size) * convert IPv6 binary address into presentation (printable) format * author: * Paul Vixie, 1996. */ static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size) { /* * Note that int32_t and int16_t need only be "at least" large enough * to contain a value of the specified size. On some systems, like * Crays, there is no such thing as an integer variable with 16 bits. * Keep this in mind if you think this function should have been coded * to use pointer overlays. All the world's not a VAX. */ char tmp[INET6_ADDRSTRLEN], *tp; struct { int base, len; } best = {-1, 0}, cur = {-1, 0}; unsigned int words[IN6ADDRSZ / INT16SZ]; int i; const unsigned char *next_src, *src_end; unsigned int *next_dest; /* * Preprocess: * Copy the input (bytewise) array into a wordwise array. * Find the longest run of 0x00's in src[] for :: shorthanding. */ next_src = src; src_end = src + IN6ADDRSZ; next_dest = words; i = 0; do { unsigned int next_word = (unsigned int)*next_src++; next_word <<= 8; next_word |= (unsigned int)*next_src++; *next_dest++ = next_word; if (next_word == 0) { if (cur.base == -1) { cur.base = i; cur.len = 1; } else { cur.len++; } } else { if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) { best = cur; } cur.base = -1; } } i++; } while (next_src < src_end); if (cur.base != -1) { if (best.base == -1 || cur.len > best.len) { best = cur; } } if (best.base != -1 && best.len < 2) { best.base = -1; } /* * Format the result. */ tp = tmp; for (i = 0; i < (IN6ADDRSZ / INT16SZ);) { /* Are we inside the best run of 0x00's? */ if (i == best.base) { *tp++ = ':'; i += best.len; continue; } /* Are we following an initial run of 0x00s or any real hex? */ if (i != 0) { *tp++ = ':'; } /* Is this address an encapsulated IPv4? */ if (i == 6 && best.base == 0 && (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) { return (NULL); } tp += strlen(tp); break; } tp += sprintf(tp, "%x", words[i]); i++; } /* Was it a trailing run of 0x00's? */ if (best.base != -1 && (best.base + best.len) == (IN6ADDRSZ / INT16SZ)) { *tp++ = ':'; } *tp++ = '\0'; /* * Check for overflow, copy, and we're done. */ if ((size_t)(tp - tmp) > size) { errno = ENOSPC; return NULL; } strcpy(dst, tmp); return dst; } #endif /** * dump a jk_sockaddr_t in A.B.C.D:P in ASCII buffer * */ char *jk_dump_hinfo(jk_sockaddr_t *saddr, char *buf, size_t size) { char pb[8]; if (saddr->family == JK_INET) { inet_ntop4(saddr->ipaddr_ptr, buf, size); } #if JK_HAVE_IPV6 else { inet_ntop6(saddr->ipaddr_ptr, buf, size); } #endif sprintf(pb, ":%d", saddr->port); strncat(buf, pb, size - strlen(buf) - 1); return buf; } char *jk_dump_sinfo(jk_sock_t sd, char *buf, size_t size) { struct sockaddr rsaddr; struct sockaddr lsaddr; socklen_t salen; salen = sizeof(struct sockaddr); if (getsockname(sd, &lsaddr, &salen) == 0) { salen = sizeof(struct sockaddr); if (getpeername(sd, &rsaddr, &salen) == 0) { char pb[8]; size_t ps; if (lsaddr.sa_family == JK_INET) { struct sockaddr_in *sa = (struct sockaddr_in *)&lsaddr; inet_ntop4((unsigned char *)&sa->sin_addr, buf, size); sprintf(pb, ":%d", (unsigned int)htons(sa->sin_port)); } #if JK_HAVE_IPV6 else { struct sockaddr_in6 *sa = (struct sockaddr_in6 *)&lsaddr; inet_ntop6((unsigned char *)&sa->sin6_addr, buf, size); sprintf(pb, ":%d", (unsigned int)htons(sa->sin6_port)); } #endif ps = strlen(buf); strncat(buf, pb, size - ps - 1); ps = strlen(buf); strncat(buf, " -> ", size - ps - 1); ps = strlen(buf); if (rsaddr.sa_family == JK_INET) { struct sockaddr_in *sa = (struct sockaddr_in *)&rsaddr; inet_ntop4((unsigned char *)&sa->sin_addr, buf + ps, size - ps); sprintf(pb, ":%d", (unsigned int)htons(sa->sin_port)); } #if JK_HAVE_IPV6 else { struct sockaddr_in6 *sa = (struct sockaddr_in6 *)&rsaddr; inet_ntop6((unsigned char *)&sa->sin6_addr, buf + ps, size - ps); sprintf(pb, ":%d", (unsigned int)htons(sa->sin6_port)); } #endif strncat(buf, pb, size - strlen(buf) - 1); return buf; } } snprintf(buf, size, "errno=%d", errno); return buf; } /** Wait for input event on socket until timeout * @param sd socket to use * @param timeout wait timeout in milliseconds * @param l logger * @return JK_FALSE: Timeout expired without something to read * JK_FALSE: Error during waiting * JK_TRUE: success * @remark Does not close socket in case of error * to allow for iterative waiting * @remark Cares about errno */ #ifdef HAVE_POLL int jk_is_input_event(jk_sock_t sd, int timeout, jk_logger_t *l) { struct pollfd fds; int rc; int save_errno; char buf[DUMP_SINFO_BUF_SZ]; JK_TRACE_ENTER(l); errno = 0; fds.fd = sd; fds.events = POLLIN; fds.revents = 0; do { rc = poll(&fds, 1, timeout); } while (rc < 0 && errno == EINTR); if (rc == 0) { if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "timeout during poll on socket %d [%s] (timeout=%d)", sd, jk_dump_sinfo(sd, buf, sizeof(buf)), timeout); } /* Timeout. Set the errno to timeout */ errno = ETIMEDOUT; JK_TRACE_EXIT(l); return JK_FALSE; } else if (rc < 0) { save_errno = errno; if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "error during poll on socket %d [%s] (errno=%d)", sd, jk_dump_sinfo(sd, buf, sizeof(buf)), errno); } errno = save_errno; JK_TRACE_EXIT(l); return JK_FALSE; } if ((fds.revents & (POLLERR | POLLHUP))) { save_errno = fds.revents & (POLLERR | POLLHUP); if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "error event during poll on socket %d [%s] (event=%d)", sd, jk_dump_sinfo(sd, buf, sizeof(buf)), save_errno); } errno = save_errno; JK_TRACE_EXIT(l); return JK_FALSE; } errno = 0; JK_TRACE_EXIT(l); return JK_TRUE; } #else int jk_is_input_event(jk_sock_t sd, int timeout, jk_logger_t *l) { fd_set rset; struct timeval tv; int rc; int save_errno; char buf[DUMP_SINFO_BUF_SZ]; JK_TRACE_ENTER(l); errno = 0; FD_ZERO(&rset); FD_SET(sd, &rset); tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; do { rc = select((int)sd + 1, &rset, NULL, NULL, &tv); } while (rc < 0 && errno == EINTR); if (rc == 0) { if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "timeout during select on socket %d [%s] (timeout=%d)", sd, jk_dump_sinfo(sd, buf, sizeof(buf)), timeout); } /* Timeout. Set the errno to timeout */ #if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) errno = WSAETIMEDOUT - WSABASEERR; #else errno = ETIMEDOUT; #endif JK_TRACE_EXIT(l); return JK_FALSE; } else if (rc < 0) { save_errno = errno; if (JK_IS_DEBUG_LEVEL(l)) { jk_log(l, JK_LOG_DEBUG, "error during select on socket %d [%s] (errno=%d)", sd, jk_dump_sinfo(sd, buf, sizeof(buf)), errno); } errno = save_errno; JK_TRACE_EXIT(l); return JK_FALSE; } errno = 0; JK_TRACE_EXIT(l); return JK_TRUE; } #endif /** Test if a socket is still connected * @param sd socket to use * @param l logger * @return JK_FALSE: failure * JK_TRUE: success * @remark Always closes socket in case of error * @remark Cares about errno */ #ifdef HAVE_POLL int jk_is_socket_connected(jk_sock_t sd, jk_logger_t *l) { struct pollfd fds; int rc; JK_TRACE_ENTER(l); errno = 0; fds.fd = sd; fds.events = POLLIN; do { rc = poll(&fds, 1, 0); } while (rc < 0 && errno == EINTR); if (rc == 0) { /* If we get a timeout, then we are still connected */ JK_TRACE_EXIT(l); return JK_TRUE; } else if (rc == 1 && fds.revents == POLLIN) { char buf; do { rc = (int)recvfrom(sd, &buf, 1, MSG_PEEK, NULL, NULL); } while (rc < 0 && errno == EINTR); if (rc == 1) { /* There is at least one byte to read. */ JK_TRACE_EXIT(l); return JK_TRUE; } } jk_shutdown_socket(sd, l); JK_TRACE_EXIT(l); return JK_FALSE; } #else int jk_is_socket_connected(jk_sock_t sd, jk_logger_t *l) { fd_set fd; struct timeval tv; int rc; JK_TRACE_ENTER(l); errno = 0; FD_ZERO(&fd); FD_SET(sd, &fd); /* Initially test the socket without any blocking. */ tv.tv_sec = 0; tv.tv_usec = 0; do { rc = select((int)sd + 1, &fd, NULL, NULL, &tv); JK_GET_SOCKET_ERRNO(); /* Wait one microsecond on next select, if EINTR */ tv.tv_sec = 0; tv.tv_usec = 1; } while (JK_IS_SOCKET_ERROR(rc) && errno == EINTR); errno = 0; if (rc == 0) { /* If we get a timeout, then we are still connected */ JK_TRACE_EXIT(l); return JK_TRUE; } else if (rc == 1) { #if defined(WIN32) || (defined(NETWARE) && defined(__NOVELL_LIBC__)) u_long nr; rc = ioctlsocket(sd, FIONREAD, &nr); if (rc == 0) { if (WSAGetLastError() == 0) errno = 0; else JK_GET_SOCKET_ERRNO(); } #else int nr; rc = ioctl(sd, FIONREAD, (void*)&nr); #endif if (rc == 0 && nr != 0) { JK_TRACE_EXIT(l); return JK_TRUE; } JK_GET_SOCKET_ERRNO(); } jk_shutdown_socket(sd, l); JK_TRACE_EXIT(l); return JK_FALSE; } #endif tomcat-connectors-1.2.41-src/native/common/jk_md5.c0000644000000000000020000004006710516516102020412 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * This is work is derived from material Copyright RSA Data Security, Inc. * * The RSA copyright statement and Licence for that original material is * included below. This is followed by the Apache copyright statement and * licence for the modifications made to that material. */ /* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm */ /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. */ /* * The ap_MD5Encode() routine uses much code obtained from the FreeBSD 3.0 * MD5 crypt() function, which is licenced as follows: * ---------------------------------------------------------------------------- * "THE BEER-WARE LICENSE" (Revision 42): * wrote this file. As long as you retain this notice you * can do whatever you want with this stuff. If we meet some day, and you think * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp * ---------------------------------------------------------------------------- */ /*************************************************************************** * Description: MD5 encoding wrapper * * Author: Henri Gomez * * Version: $Revision: 466585 $ * ***************************************************************************/ /* * JK MD5 Encoding function (jk_MD5Encode) * * Jk delegate MD5 encoding to ap_MD5Encode when used in Apache Web-Server. * When another web-server is used like NES/IIS, we should use corresponding calls. * NES/IIS specialists will add the necessary code but until that, I reused the code * from Apache HTTP server. * * Nota: If you use an EBCDIC system without Apache, you'll have to use MD5 encoding * corresponding call or have a ebcdic2ascii() functions somewhere. * For example current AS/400 have MD5 encoding support APIs but olders not.... */ #include "jk_global.h" #include "jk_md5.h" char *JK_METHOD jk_hextocstr(unsigned char *org, char *dst, int n) { char *os = dst; unsigned char v; static unsigned char zitohex[] = "0123456789ABCDEF"; while (--n >= 0) { v = *org++; *dst++ = zitohex[v >> 4]; *dst++ = zitohex[v & 0x0f]; } *dst = 0; return (os); } #ifndef USE_APACHE_MD5 /* Constants for MD5Transform routine. */ #define S11 7 #define S12 12 #define S13 17 #define S14 22 #define S21 5 #define S22 9 #define S23 14 #define S24 20 #define S31 4 #define S32 11 #define S33 16 #define S34 23 #define S41 6 #define S42 10 #define S43 15 #define S44 21 static void MD5Transform(jk_uint32_t state[4], const unsigned char block[64]); static void Encode(unsigned char *output, const jk_uint32_t * input, size_t len); static void Decode(jk_uint32_t * output, const unsigned char *input, size_t len); static void jk_MD5Init(JK_MD5_CTX * context); static void jk_MD5Update(JK_MD5_CTX * context, const unsigned char *input, size_t inputLen); /*static void jk_MD5Final(unsigned char digest[JK_MD5_DIGESTSIZE], JK_MD5_CTX *context);*/ static unsigned char PADDING[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* F, G, H and I are basic MD5 functions. */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) /* ROTATE_LEFT rotates x left n bits. */ #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) /* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. Rotation is separate from addition to prevent recomputation. */ #define FF(a, b, c, d, x, s, ac) { \ (a) += F ((b), (c), (d)) + (x) + (jk_uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define GG(a, b, c, d, x, s, ac) { \ (a) += G ((b), (c), (d)) + (x) + (jk_uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define HH(a, b, c, d, x, s, ac) { \ (a) += H ((b), (c), (d)) + (x) + (jk_uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } #define II(a, b, c, d, x, s, ac) { \ (a) += I ((b), (c), (d)) + (x) + (jk_uint32_t)(ac); \ (a) = ROTATE_LEFT ((a), (s)); \ (a) += (b); \ } /* MD5 initialization. Begins an MD5 operation, writing a new context. */ static void jk_MD5Init(JK_MD5_CTX * context) { context->count[0] = context->count[1] = 0; /* Load magic initialization constants. */ context->state[0] = 0x67452301; context->state[1] = 0xefcdab89; context->state[2] = 0x98badcfe; context->state[3] = 0x10325476; } /* MD5 block update operation. Continues an MD5 message-digest operation, processing another message block, and updating the context. */ static void jk_MD5Update(JK_MD5_CTX * context, const unsigned char *input, size_t inputLen) { size_t i, idx, partLen; /* Compute number of bytes mod 64 */ idx = (size_t) ((context->count[0] >> 3) & 0x3F); /* Update number of bits */ if ((context->count[0] += ((jk_uint32_t) inputLen << 3)) < ((jk_uint32_t) inputLen << 3)) { context->count[1]++; } context->count[1] += (jk_uint32_t) inputLen >> 29; partLen = 64 - idx; /* Transform as many times as possible. */ #ifndef CHARSET_EBCDIC if (inputLen >= partLen) { memcpy(&context->buffer[idx], input, partLen); MD5Transform(context->state, context->buffer); for (i = partLen; i + 63 < inputLen; i += 64) { MD5Transform(context->state, &input[i]); } idx = 0; } else { i = 0; } /* Buffer remaining input */ memcpy(&context->buffer[idx], &input[i], inputLen - i); #else /*CHARSET_EBCDIC */ if (inputLen >= partLen) { ebcdic2ascii(&context->buffer[idx], input, partLen); MD5Transform(context->state, context->buffer); for (i = partLen; i + 63 < inputLen; i += 64) { unsigned char inp_tmp[64]; ebcdic2ascii(inp_tmp, &input[i], 64); MD5Transform(context->state, inp_tmp); } idx = 0; } else { i = 0; } /* Buffer remaining input */ ebcdic2ascii(&context->buffer[idx], &input[i], inputLen - i); #endif /*CHARSET_EBCDIC */ } /* MD5 finalization. Ends an MD5 message-digest operation, writing the the message digest and zeroizing the context. */ static void JK_METHOD jk_MD5Final(unsigned char digest[16], JK_MD5_CTX * context) { unsigned char bits[8]; size_t idx, padLen; /* Save number of bits */ Encode(bits, context->count, 8); #ifdef CHARSET_EBCDIC /* XXX: @@@: In order to make this no more complex than necessary, * this kludge converts the bits[] array using the ascii-to-ebcdic * table, because the following jk_MD5Update() re-translates * its input (ebcdic-to-ascii). * Otherwise, we would have to pass a "conversion" flag to jk_MD5Update() */ ascii2ebcdic(bits, bits, 8); /* Since everything is converted to ascii within jk_MD5Update(), * the initial 0x80 (PADDING[0]) must be stored as 0x20 */ ascii2ebcdic(PADDING, PADDING, 1); #endif /*CHARSET_EBCDIC */ /* Pad out to 56 mod 64. */ idx = (size_t) ((context->count[0] >> 3) & 0x3f); padLen = (idx < 56) ? (56 - idx) : (120 - idx); jk_MD5Update(context, (const unsigned char *)PADDING, padLen); /* Append length (before padding) */ jk_MD5Update(context, (const unsigned char *)bits, 8); /* Store state in digest */ Encode(digest, context->state, 16); /* Zeroize sensitive information. */ memset(context, 0, sizeof(*context)); } /* MD5 basic transformation. Transforms state based on block. */ static void MD5Transform(jk_uint32_t state[4], const unsigned char block[64]) { jk_uint32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16]; Decode(x, block, 64); /* Round 1 */ FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */ FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */ FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */ FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */ FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */ FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */ FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */ FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */ FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */ FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */ FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ /* Round 2 */ GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */ GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */ GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */ GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */ GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */ GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */ GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */ GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */ GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */ GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */ GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */ GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ /* Round 3 */ HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */ HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */ HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */ HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */ HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */ HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */ HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */ HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */ HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */ HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */ /* Round 4 */ II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */ II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */ II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */ II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */ II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */ II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */ II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */ II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */ II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */ II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; /* Zeroize sensitive information. */ memset(x, 0, sizeof(x)); } /* Encodes input (jk_uint32_t) into output (unsigned char). Assumes len is a multiple of 4. */ static void Encode(unsigned char *output, const jk_uint32_t * input, size_t len) { size_t i, j; jk_uint32_t k; for (i = 0, j = 0; j < len; i++, j += 4) { k = input[i]; output[j] = (unsigned char)(k & 0xff); output[j + 1] = (unsigned char)((k >> 8) & 0xff); output[j + 2] = (unsigned char)((k >> 16) & 0xff); output[j + 3] = (unsigned char)((k >> 24) & 0xff); } } /* Decodes input (unsigned char) into output (jk_uint32_t). Assumes len is * a multiple of 4. */ static void Decode(jk_uint32_t * output, const unsigned char *input, size_t len) { size_t i, j; for (i = 0, j = 0; j < len; i++, j += 4) output[i] = ((jk_uint32_t) input[j]) | (((jk_uint32_t) input[j + 1]) << 8) | (((jk_uint32_t) input[j + 2]) << 16) | (((jk_uint32_t) input[j + 3]) << 24); } char *JK_METHOD jk_md5(const unsigned char *org, const unsigned char *org2, char *dst) { JK_MD5_CTX ctx; char buf[JK_MD5_DIGESTSIZE + 1]; jk_MD5Init(&ctx); jk_MD5Update(&ctx, org, strlen((const char *)org)); if (org2 != NULL) jk_MD5Update(&ctx, org2, strlen((const char *)org2)); jk_MD5Final((unsigned char *)buf, &ctx); return (jk_hextocstr((unsigned char *)buf, dst, JK_MD5_DIGESTSIZE)); } #else /* USE_APACHE_MD5 */ #include "httpd.h" #include "http_config.h" #ifdef STANDARD20_MODULE_STUFF #include "apr_md5.h" #define AP_MD5_CTX apr_md5_ctx_t #define ap_MD5Init apr_md5_init #define ap_MD5Update apr_md5_update #define ap_MD5Final apr_md5_final #else /* STANDARD20_MODULE_STUFF */ #include "ap_md5.h" #endif /* STANDARD20_MODULE_STUFF */ char *JK_METHOD jk_md5(const unsigned char *org, const unsigned char *org2, char *dst) { AP_MD5_CTX ctx; char buf[JK_MD5_DIGESTSIZE + 1]; ap_MD5Init(&ctx); ap_MD5Update(&ctx, org, strlen((const char *)org)); if (org2 != NULL) ap_MD5Update(&ctx, org2, strlen((const char *)org2)); ap_MD5Final((unsigned char *)buf, &ctx); return (jk_hextocstr((unsigned char *)buf, dst, JK_MD5_DIGESTSIZE)); } #endif /* USE_APACHE_MD5 */ /* Test values: * "" D4 1D 8C D9 8F 00 B2 04 E9 80 09 98 EC F8 42 7E * "a" 0C C1 75 B9 C0 F1 B6 A8 31 C3 99 E2 69 77 26 61 * "abc 90 01 50 98 3C D2 4F B0 D6 96 3F 7D 28 E1 7F 72 * "message digest" F9 6B 69 7D 7C B7 93 8D 52 5A 2F 31 AA F1 61 D0 * */ #ifdef TEST_JKMD5 main(int argc, char **argv) { char xxx[(2 * JK_MD5_DIGESTSIZE) + 1]; if (argc > 1) printf("%s => %s\n", argv[1], jk_md5(argv[1], NULL, xxx)); } #endif tomcat-connectors-1.2.41-src/native/common/jk_ajp13.c0000644000000000000020000000352610516516102020642 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: Experimental bi-directionl protocol handler. * * Author: Gal Shachor * * Author: Henri Gomez * * Version: $Revision: 466585 $ * ***************************************************************************/ #include "jk_global.h" #include "jk_util.h" #include "jk_ajp_common.h" #include "jk_ajp13.h" int ajp13_marshal_shutdown_into_msgb(jk_msg_buf_t *msg, jk_pool_t *p, jk_logger_t *l) { JK_TRACE_ENTER(l); /* To be on the safe side */ jk_b_reset(msg); /* * Just a single byte with s/d command. */ if (jk_b_append_byte(msg, JK_AJP13_SHUTDOWN)) { jk_log(l, JK_LOG_ERROR, "failed appending shutdown message"); JK_TRACE_EXIT(l); return JK_FALSE; } JK_TRACE_EXIT(l); return JK_TRUE; } tomcat-connectors-1.2.41-src/native/common/jk_uri_worker_map.h0000644000000000000020000001676212445324026022771 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: URI to worker mapper header file * * Author: Gal Shachor * * Version: $Revision: 1647017 $ * ***************************************************************************/ #ifndef JK_URI_WORKER_MAP_H #define JK_URI_WORKER_MAP_H #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ #include "jk_global.h" #include "jk_map.h" #include "jk_logger.h" #include "jk_mt.h" #define MATCH_TYPE_EXACT 0x0001 /* deprecated #define MATCH_TYPE_CONTEXT 0x0002 */ /* match all context path URIs with a path component suffix */ /* deprecated #define MATCH_TYPE_CONTEXT_PATH 0x0004 */ /* deprecated #define MATCH_TYPE_SUFFIX 0x0010 */ /* match all URIs of the form *ext */ /* deprecated #define MATCH_TYPE_GENERAL_SUFFIX 0x0020 */ /* match multiple wild characters (*) and (?) */ #define MATCH_TYPE_WILDCHAR_PATH 0x0040 #define MATCH_TYPE_NO_MATCH 0x1000 #define MATCH_TYPE_DISABLED 0x2000 /* deprecated #define MATCH_TYPE_STOPPED 0x4000 */ #define JK_COLLAPSE_ALL 0x0001 #define JK_COLLAPSE_NONE 0x0002 #define JK_COLLAPSE_UNMOUNT 0x0003 #define JK_COLLAPSE_DEFAULT JK_COLLAPSE_UNMOUNT #define SOURCE_TYPE_WORKERDEF 0x0001 #define SOURCE_TYPE_JKMOUNT 0x0002 #define SOURCE_TYPE_URIMAP 0x0003 #define SOURCE_TYPE_DISCOVER 0x0004 #define SOURCE_TYPE_TEXT_WORKERDEF ("worker definition") #define SOURCE_TYPE_TEXT_JKMOUNT ("JkMount") #define SOURCE_TYPE_TEXT_URIMAP ("uriworkermap") #define SOURCE_TYPE_TEXT_DISCOVER ("ajp14") #define JK_MAX_URI_LEN 4095 struct rule_extension { /* reply_timeout overwrite */ int reply_timeout; /* Whether to ignore session routing info */ int sticky_ignore; /* Whether the request is stateless and should not * influence session load balancing */ int stateless; /* activation state overwrites for load balancers */ /* Number of elements in the array activations. */ int activation_size; /* Dynamically allocated array with one entry per lb member. */ int *activation; /* Temporary storage for the original extension strings. */ char *active; char *disabled; char *stopped; /* fail_on_status overwrites */ /* Number of elements in the array fail_on_status. */ int fail_on_status_size; /* Dynamically allocated array with one entry per status. */ int *fail_on_status; /* Temporary storage for the original extension strings. */ char *fail_on_status_str; /* Use server error pages for responses >= 400. */ int use_server_error_pages; /* session_cookie overwrite */ char *session_cookie; /* session_path overwrite */ char *session_path; int set_session_cookie; char *session_cookie_path; }; typedef struct rule_extension rule_extension_t; struct uri_worker_record { /* Original uri for logging */ char *uri; /* Name of worker mapped */ const char *worker_name; /* Base context */ const char *context; /* Match type */ unsigned int match_type; /* Definition source type */ unsigned int source_type; /* char length of the context */ size_t context_len; /* extended mapping properties */ rule_extension_t extensions; }; typedef struct uri_worker_record uri_worker_record_t; struct jk_uri_worker_map { /* Memory Pool */ jk_pool_t p; jk_pool_atom_t buf[BIG_POOL_SIZE]; /* Index 0 or 1, which map instance do we use */ /* Needed to make map reload more atomically */ int index; /* map Id. * Unique value which gets incremented each time we * call uri_worker_map_alloc */ int id; /* Memory Pool - cleared when doing reload */ /* Use this pool to allocate objects, that are deleted */ /* when the map gets dynamically reloaded from uriworkermap.properties. */ jk_pool_t p_dyn[2]; jk_pool_atom_t buf_dyn[2][BIG_POOL_SIZE]; /* map URI->WORKER */ uri_worker_record_t **maps[2]; /* Map Number */ unsigned int size[2]; /* Map Capacity */ unsigned int capacity[2]; /* NoMap Number */ unsigned int nosize[2]; /* Dynamic config support */ JK_CRIT_SEC cs; /* should we forward potentially unsafe URLs */ int reject_unsafe; /* how to handle multiple adjacent slashes in URLs */ int collapse_slashes; /* uriworkermap filename */ const char *fname; /* uriworkermap reload check interval */ int reload; /* Last modified time */ time_t modified; /* Last checked time */ time_t checked; }; typedef struct jk_uri_worker_map jk_uri_worker_map_t; void extension_fix(jk_pool_t *p, const char *name, rule_extension_t *extensions, jk_logger_t *l); void parse_rule_extensions(char *rule, rule_extension_t *extensions, jk_logger_t *l); const char *uri_worker_map_get_source(uri_worker_record_t *uwr, jk_logger_t *l); char *uri_worker_map_get_match(uri_worker_record_t *uwr, char *buf, jk_logger_t *l); int uri_worker_map_alloc(jk_uri_worker_map_t **uw_map, jk_map_t *init_data, jk_logger_t *l); int uri_worker_map_free(jk_uri_worker_map_t **uw_map, jk_logger_t *l); int uri_worker_map_open(jk_uri_worker_map_t *uw_map, jk_map_t *init_data, jk_logger_t *l); void uri_worker_map_switch(jk_uri_worker_map_t *uw_map, jk_logger_t *l); void uri_worker_map_ext(jk_uri_worker_map_t *uw_map, jk_logger_t *l); int uri_worker_map_add(jk_uri_worker_map_t *uw_map, const char *puri, const char *worker, unsigned int source_type, jk_logger_t *l); const char *map_uri_to_worker(jk_uri_worker_map_t *uw_map, const char *uri, const char *vhost, jk_logger_t *l); const char *map_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, const char *uri, const char *vhost, rule_extension_t **extensions, int *index, jk_logger_t *l); rule_extension_t *get_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, int index); int uri_worker_map_load(jk_uri_worker_map_t *uw_map, jk_logger_t *l); int uri_worker_map_update(jk_uri_worker_map_t *uw_map, int force, jk_logger_t *l); #ifdef __cplusplus } #endif /* __cplusplus */ #endif /* JK_URI_WORKER_MAP_H */ tomcat-connectors-1.2.41-src/native/common/jk_md5.h0000644000000000000020000000516712446644276020443 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * This is work is derived from material Copyright RSA Data Security, Inc. * * The RSA copyright statement and Licence for that original material is * included below. This is followed by the Apache copyright statement and * licence for the modifications made to that material. */ /* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All rights reserved. License to copy and use this software is granted provided that it is identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing this software or this function. License is also granted to make and use derivative works provided that such works are identified as "derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm" in all material mentioning or referencing the derived work. RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided "as is" without express or implied warranty of any kind. These notices must be retained in any copies of any part of this documentation and/or software. */ #ifndef JK_APACHE_MD5_H #define JK_APACHE_MD5_H #ifdef __cplusplus extern "C" { #endif /* MD5.H - header file for MD5.C */ #define JK_MD5_DIGESTSIZE 16 /* MD5 context. */ typedef struct { jk_uint32_t state[4]; /* state (ABCD) */ jk_uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */ unsigned char buffer[64]; /* input buffer */ } JK_MD5_CTX; char *JK_METHOD jk_hextocstr(unsigned char *org, char *dst, int n); char *JK_METHOD jk_md5(const unsigned char *org, const unsigned char *org2, char *dst); #ifdef __cplusplus } #endif #endif /* !JK_APACHE_MD5_H */ tomcat-connectors-1.2.41-src/native/netscape/0000755000000000000020000000000012555256552017417 5ustar rootbintomcat-connectors-1.2.41-src/native/netscape/Makefile.netware0000644000000000000020000001621611660657144022527 0ustar rootbin# # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # # Makefile for jk_nsapi_plugin (NetWare version - gnu make) # created by Guenter Knauf # # Edit the path below to point to the base of your Netscape includes. ifndef NS_HOME NS_HOME = c:/projects/sdks/netscape endif # Edit the path below to point to the base of your Novell NDK. ifndef NDKBASE NDKBASE = c:/novell endif ifndef INSTDIR INSTDIR = s:/sys/novonyx/modules endif # Edit the vars below to change NLM target settings. TARGET = nsapi_rd VERSION = $(JK_VERSION) COPYR = Licensed under the Apache License, Version 2.0 DESCR = Netscape plugin for Tomcat $(JK_VERSION_STR) MTSAFE = NO STACK = 65536 #SCREEN = System Console MODULES = nshttpd EXPORTS = jk_init jk_service IMPORTS = __nsapi30_table # Edit the var below to point to your lib architecture. ifndef LIBARCH LIBARCH = CLIB # LIBARCH = LIBC endif # must be equal to DEBUG or NDEBUG DB = NDEBUG # DB = DEBUG # Optimization: -O or debugging: -g ifeq ($(DB),NDEBUG) OPT = -O2 OBJDIR = release else OPT = -g OBJDIR = debug endif # Include the version info retrieved from jk_version.h -include $(OBJDIR)/version.inc # The following line defines your compiler. ifdef METROWERKS CC = mwccnlm else CC = gcc endif # RM = rm -f # CP = cp -fv # if you want to mark the target as MTSAFE you will need a tool for # generating the xdc data for the linker; here's a minimal tool: # http://www.gknw.net/development/prgtools/mkxdc.zip MPKXDC = mkxdc AWK = awk # Global flags for all compilers CFLAGS = $(OPT) -D$(DB) -DNETWARE -DXP_NETWARE -nostdinc -DJK_NSAPI ifeq ($(CC),mwccnlm) LD = mwldnlm LDFLAGS = -nostdlib $(OBJS) $(PRELUDE) $(LDLIBS) -o $@ -commandfile CFLAGS += -gccinc -inline off -opt nointrinsics #CFLAGS += -w on ifeq ($(LIBARCH),LIBC) PRELUDE = $(SDK_LIBC)/imports/libcpre.o CFLAGS += -align 4 -inst mmx -proc 686 # CFLAGS += -D__ANSIC__ else PRELUDE = "$(METROWERKS)/Novell Support/libraries/runtime/prelude.obj" LDLIBS = "$(METROWERKS)/Novell Support/libraries/runtime/mwcrtl.lib" # CFLAGS += -include "$(METROWERKS)/Novell Support/headers/nlm_prefix.h" CFLAGS += -align 1 -proc 586 endif else LD = nlmconv LDFLAGS = -T CFLAGS += -fno-builtin -fpack-struct -fpcc-struct-return CFLAGS += -Wall -Wno-main # -pedantic ifeq ($(LIBARCH),LIBC) PRELUDE = $(SDK_LIBC)/imports/libcpre.gcc.o # CFLAGS += -D__ANSIC__ else PRELUDE = $(SDK_CLIB)/imports/clibpre.gcc.o CFLAGS += -include $(NDKBASE)/nlmconv/genlm.h endif endif NDK_ROOT = $(NDKBASE)/ndk SDK_CLIB = $(NDK_ROOT)/nwsdk SDK_LIBC = $(NDK_ROOT)/libc JKCOMMON = ../common INCLUDES = -I$(NS_HOME)/include -I$(NS_HOME)/include/base INCLUDES += -I$(JKCOMMON) ifeq ($(LIBARCH),LIBC) INCLUDES += -I$(SDK_LIBC)/include INCLUDES += -I$(SDK_LIBC)/include/winsock else INCLUDES += -I$(SDK_CLIB)/include/nlm # INCLUDES += -I$(NDKBASE)/ws295sdk/include CFLAGS += -DNETDB_USE_INTERNET CFLAGS += -DNO_GETTIMEOFDAY CFLAGS += -DJK_PREFORK endif CFLAGS += $(INCLUDES) ifeq ($(MTSAFE),YES) XDCDATA = $(OBJDIR)/$(TARGET).xdc endif ifeq ($(findstring linux,$(OSTYPE)),linux) DL = ' #-include $(NDKBASE)/nlmconv/ncpfs.inc endif OBJS = \ $(OBJDIR)/jk_nsapi_plugin.o \ $(OBJDIR)/jk_nwmain.o \ $(OBJDIR)/jk_ajp12_worker.o \ $(OBJDIR)/jk_ajp13.o \ $(OBJDIR)/jk_ajp13_worker.o \ $(OBJDIR)/jk_ajp14.o \ $(OBJDIR)/jk_ajp14_worker.o \ $(OBJDIR)/jk_ajp_common.o \ $(OBJDIR)/jk_connect.o \ $(OBJDIR)/jk_context.o \ $(OBJDIR)/jk_lb_worker.o \ $(OBJDIR)/jk_map.o \ $(OBJDIR)/jk_md5.o \ $(OBJDIR)/jk_msg_buff.o \ $(OBJDIR)/jk_pool.o \ $(OBJDIR)/jk_shm.o \ $(OBJDIR)/jk_sockbuf.o \ $(OBJDIR)/jk_status.o \ $(OBJDIR)/jk_uri_worker_map.o \ $(OBJDIR)/jk_url.o \ $(OBJDIR)/jk_util.o \ $(OBJDIR)/jk_worker.o \ $(OBJDIR)/ap_snprintf.o vpath %.c . $(JKCOMMON) all: $(OBJDIR) $(OBJDIR)/version.inc $(OBJDIR)/$(TARGET).nlm $(OBJDIR)/%.o: %.c @echo Compiling $< @$(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/version.inc: $(JKCOMMON)/jk_version.h $(OBJDIR) @echo Creating $@ @$(AWK) -f ../../support/get_ver.awk $< > $@ dist: all -$(RM) $(OBJDIR)/*.o $(OBJDIR)/$(TARGET).map $(OBJDIR)/$(TARGET).ncv -$(RM) $(OBJDIR)/$(TARGET).def $(OBJDIR)/version.inc $(XDCDATA) # -$(CP) ../changes.txt $(OBJDIR)/ install: all @[ -d $(INSTDIR) ] || mkdir $(INSTDIR) @$(CP) $(TARGET).nlm $(INSTDIR) clean: -$(RM) -r $(OBJDIR) $(OBJDIR): @mkdir $(OBJDIR) $(OBJDIR)/$(TARGET).nlm: $(OBJS) $(OBJDIR)/$(TARGET).def $(XDCDATA) @echo Linking $@ @-$(RM) $@ @$(LD) $(LDFLAGS) $(OBJDIR)/$(TARGET).def $(OBJDIR)/%.xdc: Makefile.netware @echo Creating $@ @$(MPKXDC) $(XDCOPT) $@ $(OBJDIR)/%.def: Makefile.netware @echo $(DL)# DEF file for linking with $(LD)$(DL) > $@ @echo $(DL)# Do not edit this file - it is created by make!$(DL) >> $@ @echo $(DL)# All your changes will be lost!!$(DL) >> $@ @echo $(DL)#$(DL) >> $@ @echo $(DL)copyright "$(COPYR)"$(DL) >> $@ @echo $(DL)description "$(DESCR)"$(DL) >> $@ @echo $(DL)version $(VERSION)$(DL) >> $@ ifdef NLMTYPE @echo $(DL)type $(NLMTYPE)$(DL) >> $@ endif ifdef STACK @echo $(DL)stack $(STACK)$(DL) >> $@ endif ifdef SCREEN @echo $(DL)screenname "$(SCREEN)"$(DL) >> $@ else @echo $(DL)screenname "DEFAULT"$(DL) >> $@ endif ifeq ($(DB),DEBUG) @echo $(DL)debug$(DL) >> $@ endif @echo $(DL)threadname "$(TARGET)"$(DL) >> $@ ifdef XDCDATA @echo $(DL)xdcdata $(XDCDATA)$(DL) >> $@ endif ifeq ($(LIBARCH),CLIB) @echo $(DL)start _Prelude$(DL) >> $@ @echo $(DL)exit _Stop$(DL) >> $@ @echo $(DL)import @$(NDK_ROOT)/nwsdk/imports/clib.imp$(DL) >> $@ @echo $(DL)import @$(NDK_ROOT)/nwsdk/imports/threads.imp$(DL) >> $@ @echo $(DL)import @$(NDK_ROOT)/nwsdk/imports/nlmlib.imp$(DL) >> $@ @echo $(DL)import @$(NDK_ROOT)/nwsdk/imports/socklib.imp$(DL) >> $@ @echo $(DL)module clib$(DL) >> $@ else ifeq ($(LD),nlmconv) @echo $(DL)flag_on 64$(DL) >> $@ else @echo $(DL)autounload$(DL) >> $@ endif @echo $(DL)pseudopreemption$(DL) >> $@ @echo $(DL)start _LibCPrelude$(DL) >> $@ @echo $(DL)exit _LibCPostlude$(DL) >> $@ @echo $(DL)check _LibCCheckUnload$(DL) >> $@ @echo $(DL)import @$(NDK_ROOT)/libc/imports/libc.imp$(DL) >> $@ @echo $(DL)import @$(NDK_ROOT)/libc/imports/netware.imp$(DL) >> $@ @echo $(DL)module libc$(DL) >> $@ endif ifdef MODULES @echo $(DL)module $(MODULES)$(DL) >> $@ endif ifdef EXPORTS @echo $(DL)export $(EXPORTS)$(DL) >> $@ endif ifdef IMPORTS @echo $(DL)import $(IMPORTS)$(DL) >> $@ endif ifeq ($(LD),nlmconv) @echo $(DL)input $(OBJS)$(DL) >> $@ @echo $(DL)input $(PRELUDE)$(DL) >> $@ ifdef LDLIBS @echo $(DL)input $(LDLIBS)$(DL) >> $@ endif @echo $(DL)output $*.nlm$(DL) >> $@ endif tomcat-connectors-1.2.41-src/native/netscape/Makefile.solaris0000644000000000000020000000470611731401736022530 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Defines for example NSAPI programs running under SOLARIS # Choose between the settings for gcc or Sun Studio compiler # gcc # If you get relocation errors, try: # 1. compiling with Sun's cc # 2. statically linking with libgcc # 3. Adjusting LD_LIBRARY_PATH to grab libgcc_s CC=gcc ifeq (gcc,$(CC)) # For 64 Bit builds, add "-m64" to EXTRA_CFLAGS CFLAGS+=-fPIC -pthread LDFLAGS=-shared else # For 64 Bit builds, add "-m64" to EXTRA_CFLAGS CFLAGS+=-O -Xa -KPIC -mt LDFLAGS=-G -dy endif # Change this according to location where on installed the server. # Don't forget to do the ./configure --enable-netscape=/opt/SUNWwbsvr/plugins # before doing gmake -f Makefile.solaris CC_CMD=$(CC) $(CFLAGS) $(EXTRA_CFLAGS) \ -DNET_SSL -DSOLARIS -D_REENTRANT -DXP_UNIX -DMCC_HTTPD -DSPAPI20 -DJK_NSAPI -DHAVE_CONFIG_H LD_SHAREDCMD=$(CC) $(LDFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) all: prepare: OS_TYPE=solaris INCLUDEDIR=$(IPLANET_HOME)/include JK_DIR=../common VPATH=.:$(JK_DIR) JK_OBJS = ap_snprintf.o \ jk_md5.o \ jk_ajp12_worker.o \ jk_msg_buff.o \ jk_ajp13.o \ jk_ajp13_worker.o \ jk_pool.o \ jk_ajp14.o \ jk_shm.o \ jk_ajp14_worker.o \ jk_sockbuf.o \ jk_ajp_common.o \ jk_status.o \ jk_connect.o \ jk_uri_worker_map.o \ jk_context.o \ jk_url.o \ jk_util.o \ jk_lb_worker.o \ jk_worker.o \ jk_map.o PLUGIN_OBJ = jk_nsapi_plugin.o INCLUDE_FLAGS= -I$(JK_DIR) -I$(INCLUDEDIR) -I$(INCLUDEDIR)/base \ -I$(INCLUDEDIR)/frame all: nsapi_redirector.so nsapi_redirector.so: $(JK_OBJS) $(PLUGIN_OBJ) $(LD_SHAREDCMD) $(JK_OBJS) $(PLUGIN_OBJ) -o nsapi_redirector.so $(EXTRA_LDDEFINES) clean: rm -f *.o nsapi_redirector.so $(JK_OBJS) rm -f $(JK_DIR)/*.o %.o : %.c $(CC_CMD) $(INCLUDE_FLAGS) -c $< tomcat-connectors-1.2.41-src/native/netscape/nsapi.dsp0000644000000000000020000001614611660226567021250 0ustar rootbin# Microsoft Developer Studio Project File - Name="nsapi" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=nsapi - Win32 Debug !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "nsapi.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "nsapi.mak" CFG="nsapi - Win32 Debug" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "nsapi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "nsapi - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "nsapi - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "nsapi_release" # PROP Intermediate_Dir "nsapi_release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JK_NSAPI" /D "NSAPI_EXPORTS" /YX /FD /c # ADD CPP /nologo /MD /W3 /Zi /O2 /I "..\common" /I "$(IPLANET_HOME)\plugins\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JK_NSAPI" /D "NSAPI_EXPORTS" /D "XP_WIN32" /D "MCC_HTTPD" /D "SPAPI20" /Fd"Release/nsapi_redirect_src" /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 ns-httpd40.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /base:"0x6A6B0000" /dll /debug /machine:I386 /out:"nsapi_release/nsapi_redirect.dll" /libpath:"$(IPLANET_HOME)\plugins\lib" !ELSEIF "$(CFG)" == "nsapi - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "nsapi___Win32_Debug" # PROP BASE Intermediate_Dir "nsapi___Win32_Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "nsapi_debug" # PROP Intermediate_Dir "nsapi_debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JK_NSAPI" /D "NSAPI_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "..\common" /I "$(IPLANET_HOME)\plugins\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JK_NSAPI" /D "NSAPI_EXPORTS" /D "XP_WIN32" /D "MCC_HTTPD" /D "SPAPI20" /Fd"Debug/nsapi_redirect_src" /FD /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 ns-httpd40.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib /nologo /base:"0x6A6B0000" /dll /debug /machine:I386 /out:"nsapi_debug/nsapi_redirect.dll" /pdbtype:sept /libpath:"$(IPLANET_HOME)\plugins\lib" !ENDIF # Begin Target # Name "nsapi - Win32 Release" # Name "nsapi - Win32 Debug" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=..\common\jk_ajp12_worker.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp13.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp13_worker.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp14.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp14_worker.c # End Source File # Begin Source File SOURCE=..\common\jk_ajp_common.c # End Source File # Begin Source File SOURCE=..\common\jk_connect.c # End Source File # Begin Source File SOURCE=..\common\jk_context.c # End Source File # Begin Source File SOURCE=..\common\jk_lb_worker.c # End Source File # Begin Source File SOURCE=..\common\jk_map.c # End Source File # Begin Source File SOURCE=..\common\jk_md5.c # End Source File # Begin Source File SOURCE=..\common\jk_msg_buff.c # End Source File # Begin Source File SOURCE=.\jk_nsapi_plugin.c # End Source File # Begin Source File SOURCE=..\common\jk_pool.c # End Source File # Begin Source File SOURCE=..\common\jk_shm.c # End Source File # Begin Source File SOURCE=..\common\jk_sockbuf.c # End Source File # Begin Source File SOURCE=..\common\jk_status.c # End Source File # Begin Source File SOURCE=..\common\jk_uri_worker_map.c # End Source File # Begin Source File SOURCE=..\common\jk_url.c # End Source File # Begin Source File SOURCE=..\common\jk_util.c # End Source File # Begin Source File SOURCE=..\common\jk_worker.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=..\common\jk_ajp13.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp13_worker.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp14.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp14_worker.h # End Source File # Begin Source File SOURCE=..\common\jk_ajp_common.h # End Source File # Begin Source File SOURCE=..\common\jk_connect.h # End Source File # Begin Source File SOURCE=..\common\jk_context.h # End Source File # Begin Source File SOURCE=..\common\jk_global.h # End Source File # Begin Source File SOURCE=..\common\jk_lb_worker.h # End Source File # Begin Source File SOURCE=..\common\jk_logger.h # End Source File # Begin Source File SOURCE=..\common\jk_map.h # End Source File # Begin Source File SOURCE=..\common\jk_md5.h # End Source File # Begin Source File SOURCE=..\common\jk_msg_buff.h # End Source File # Begin Source File SOURCE=..\common\jk_mt.h # End Source File # Begin Source File SOURCE=..\common\jk_pool.h # End Source File # Begin Source File SOURCE=..\common\jk_service.h # End Source File # Begin Source File SOURCE=..\common\jk_shm.h # End Source File # Begin Source File SOURCE=..\common\jk_status.h # End Source File # Begin Source File SOURCE=..\common\jk_uri_worker_map.h # End Source File # Begin Source File SOURCE=..\common\jk_url.h # End Source File # Begin Source File SOURCE=..\common\jk_util.h # End Source File # Begin Source File SOURCE=..\common\jk_worker.h # End Source File # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # End Target # End Project tomcat-connectors-1.2.41-src/native/netscape/jk_nsapi_plugin.c0000644000000000000020000005011512357620570022734 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /*************************************************************************** * Description: NSAPI plugin for Netscape servers * * Author: Gal Shachor * * Version: $Revision: 1609589 $ * ***************************************************************************/ #if defined(WIN32) #ifndef _WIN32_WINNT #define _WIN32_WINNT 0x0500 #endif #include #endif #include "nsapi.h" #include "jk_global.h" #include "jk_url.h" #include "jk_util.h" #include "jk_map.h" #include "jk_pool.h" #include "jk_service.h" #include "jk_worker.h" #include "jk_shm.h" #include "jk_ajp13.h" #define URI_PATTERN "path" #define DEFAULT_WORKER_NAME ("ajp13") #define REJECT_UNSAFE_TAG "reject_unsafe" #define STRNULL_FOR_NULL(x) ((x) ? (x) : "(null)") struct nsapi_private_data { jk_pool_t p; pblock *pb; Session *sn; Request *rq; }; typedef struct nsapi_private_data nsapi_private_data_t; static int init_on_other_thread_is_done = JK_FALSE; static int init_on_other_thread_is_ok = JK_FALSE; static const char ssl_cert_start[] = "-----BEGIN CERTIFICATE-----\r\n"; static const char ssl_cert_end[] = "\r\n-----END CERTIFICATE-----\r\n"; static jk_logger_t *logger = NULL; static jk_worker_env_t worker_env; static jk_map_t *init_map = NULL; static jk_uri_worker_map_t *uw_map = NULL; static int jk_shm_size = 0; #ifdef NETWARE int (*PR_IsSocketSecure) (SYS_NETFD * csd); /* pointer to PR_IsSocketSecure function */ #endif static int JK_METHOD start_response(jk_ws_service_t *s, int status, const char *reason, const char *const *header_names, const char *const *header_values, unsigned num_of_headers); static int JK_METHOD ws_read(jk_ws_service_t *s, void *b, unsigned l, unsigned *a); static int JK_METHOD ws_write(jk_ws_service_t *s, const void *b, unsigned l); NSAPI_PUBLIC int jk_init(pblock * pb, Session * sn, Request * rq); NSAPI_PUBLIC void jk_term(void *p); NSAPI_PUBLIC int jk_service(pblock * pb, Session * sn, Request * rq); static int init_ws_service(nsapi_private_data_t * private_data, jk_ws_service_t *s); static int setup_http_headers(nsapi_private_data_t * private_data, jk_ws_service_t *s); static void init_workers_on_other_threads(void *init_d) { init_map = (jk_map_t *)init_d; /* we add the URI->WORKER MAP since workers using AJP14 will feed it */ /* but where are they here in Netscape ? */ if (uri_worker_map_alloc(&uw_map, NULL, logger)) { uw_map->fname = ""; uw_map->reload = JK_URIMAP_DEF_RELOAD; uw_map->reject_unsafe = jk_map_get_bool(init_map, "worker." REJECT_UNSAFE_TAG, JK_FALSE); worker_env.uri_to_worker = uw_map; worker_env.pool = NULL; if (wc_open(init_map, &worker_env, logger)) { init_on_other_thread_is_ok = JK_TRUE; uri_worker_map_ext(uw_map, logger); uri_worker_map_switch(uw_map, logger); } else { jk_log(logger, JK_LOG_EMERG, "In init_workers_on_other_threads, failed"); } } else { jk_log(logger, JK_LOG_EMERG, "In init_workers_on_other_threads, failed"); } init_on_other_thread_is_done = JK_TRUE; } /* * Convert string to lower case. * If string is longer than the provided buffer, * just return the original string. */ static const char *to_lower(const char *str, char *buf, int bufsz) { const char *from = str; char *to = buf; char *end = buf + (bufsz - 1); while (to != end && *from) { *to = (char)tolower(*from); to++; from++; } if (to != end) { *to = '\0'; return buf; } return str; } static int JK_METHOD start_response(jk_ws_service_t *s, int status, const char *reason, const char *const *header_names, const char *const *header_values, unsigned num_of_headers) { if (s && s->ws_private) { nsapi_private_data_t *p = s->ws_private; if (!s->response_started) { unsigned i; s->response_started = JK_TRUE; /* Remove "old" content type */ param_free(pblock_remove("content-type", p->rq->srvhdrs)); if (num_of_headers) { /* * NSAPI expects http header names to be lower case. * This is only relevant for the server itself or other * plugins searching for headers in the pblock. * We use a buffer of limited length, because conforming * with this rule should only matter for well-known headers. */ char name_buf[64]; for (i = 0; i < (int)num_of_headers; i++) { pblock_nvinsert(to_lower(header_names[i], name_buf, 64), header_values[i], p->rq->srvhdrs); } } else { pblock_nvinsert("content-type", "text/plain", p->rq->srvhdrs); } protocol_status(p->sn, p->rq, status, (char *)reason); protocol_start_response(p->sn, p->rq); } return JK_TRUE; } return JK_FALSE; } static int JK_METHOD ws_read(jk_ws_service_t *s, void *b, unsigned l, unsigned *a) { if (s && s->ws_private && b && a) { nsapi_private_data_t *p = s->ws_private; *a = 0; if (l) { unsigned i; netbuf *inbuf = p->sn->inbuf; /* Until we get a service pack for NW5.1 and earlier that has the latest */ /* Enterprise Server, we have to go through the else version of this code*/ #if defined(netbuf_getbytes) && !defined(NETWARE) i = netbuf_getbytes(inbuf, b, l); if (NETBUF_EOF == i || NETBUF_ERROR == i) { return JK_FALSE; } #else char *buf = b; int ch; for (i = 0; i < l; i++) { ch = netbuf_getc(inbuf); /* * IO_EOF is 0 (zero) which is a very reasonable byte * when it comes to binary data. So we are not breaking * out of the read loop when reading it. * * We are protected from an infinit loop by the Java part of * Tomcat. */ if (IO_ERROR == ch) { break; } buf[i] = ch; } if (0 == i) { return JK_FALSE; } #endif *a = i; } return JK_TRUE; } return JK_FALSE; } static int JK_METHOD ws_write(jk_ws_service_t *s, const void *b, unsigned l) { if (s && s->ws_private && b) { nsapi_private_data_t *p = s->ws_private; if (l) { if (!s->response_started) { start_response(s, 200, NULL, NULL, NULL, 0); } if (net_write(p->sn->csd, (char *)b, (int)l) == IO_ERROR) { return JK_FALSE; } } return JK_TRUE; } return JK_FALSE; } NSAPI_PUBLIC int jk_init(pblock * pb, Session * sn, Request * rq) { char *worker_prp_file = pblock_findval(JK_WORKER_FILE_TAG, pb); char *log_level_str = pblock_findval(JK_LOG_LEVEL_TAG, pb); char *log_file = pblock_findval(JK_LOG_FILE_TAG, pb); char *shm_file = pblock_findval(JK_SHM_FILE_TAG, pb); char *shm_file_safe = ""; char *reject_unsafe = pblock_findval(REJECT_UNSAFE_TAG, pb); int rc = REQ_ABORTED; if (!worker_prp_file) { worker_prp_file = JK_WORKER_FILE_DEF; } if (!log_level_str) { log_level_str = JK_LOG_DEF_VERB; } if (!log_file) { fprintf(stderr, "Missing attribute %s in magnus.conf (jk_init) - aborting!\n", JK_LOG_FILE_TAG); return rc; } if (shm_file) { shm_file_safe = shm_file; } #if !defined(WIN32) && !defined(NETWARE) else { fprintf(stderr, "Missing attribute %s in magnus.conf (jk_init) - aborting!\n", JK_SHM_FILE_TAG); return rc; } #endif fprintf(stderr, "In jk_init.\n Worker file = %s.\n Log level = %s.\n Log File = %s\n SHM File = %s\n", worker_prp_file, log_level_str, log_file, shm_file); if (!jk_open_file_logger(&logger, log_file, jk_parse_log_level(log_level_str))) { logger = NULL; } if (jk_map_alloc(&init_map)) { if (jk_map_read_properties(init_map, NULL, worker_prp_file, NULL, JK_MAP_HANDLE_DUPLICATES, logger)) { int rv; int sleep_cnt; SYS_THREAD s; if (jk_map_resolve_references(init_map, "worker.", 1, 1, logger) == JK_FALSE) { jk_log(logger, JK_LOG_ERROR, "Error in resolving configuration references"); } if (reject_unsafe) { jk_map_add(init_map, "worker." REJECT_UNSAFE_TAG, reject_unsafe); } jk_shm_size = jk_shm_calculate_size(init_map, logger); if ((rv = jk_shm_open(shm_file, jk_shm_size, logger)) != 0) jk_log(logger, JK_LOG_ERROR, "Initializing shm:%s errno=%d. Load balancing workers will not function properly.", jk_shm_name(), rv); s = systhread_start(SYSTHREAD_DEFAULT_PRIORITY, 0, init_workers_on_other_threads, init_map); for (sleep_cnt = 0; sleep_cnt < 60; sleep_cnt++) { systhread_sleep(1000); jk_log(logger, JK_LOG_DEBUG, "jk_init, a second passed"); if (init_on_other_thread_is_done) { break; } } if (init_on_other_thread_is_done && init_on_other_thread_is_ok) { magnus_atrestart(jk_term, NULL); rc = REQ_PROCEED; jk_log(logger, JK_LOG_INFO, "%s initialized", JK_FULL_EXPOSED_VERSION); } /* if(wc_open(init_map, NULL, logger)) { magnus_atrestart(jk_term, NULL); rc = REQ_PROCEED; } */ } } #ifdef NETWARE PR_IsSocketSecure = (int (*)(void **))ImportSymbol(GetNLMHandle(), "PR_IsSocketSecure"); #endif return rc; } NSAPI_PUBLIC void jk_term(void *p) { #ifdef NETWARE if (NULL != PR_IsSocketSecure) { UnimportSymbol(GetNLMHandle(), "PR_IsSocketSecure"); PR_IsSocketSecure = NULL; } #endif if (uw_map) { uri_worker_map_free(&uw_map, logger); } if (init_map) { jk_map_free(&init_map); } wc_close(logger); jk_shm_close(logger); if (logger) { jk_close_file_logger(&logger); } } NSAPI_PUBLIC int jk_service(pblock * pb, Session * sn, Request * rq) { char *worker_name = pblock_findval(JK_WORKER_NAME_TAG, pb); char *uri_pattern = pblock_findval(URI_PATTERN, pb); jk_worker_t *worker; int rc = REQ_ABORTED; if (uri_pattern) { char *uri = pblock_findval("uri", rq->reqpb); if (0 != shexp_match(uri, uri_pattern)) { return REQ_NOACTION; } } if (!worker_name) { worker_name = DEFAULT_WORKER_NAME; } worker = wc_get_worker_for_name(worker_name, logger); if (worker) { nsapi_private_data_t private_data; jk_ws_service_t s; jk_pool_atom_t buf[SMALL_POOL_SIZE]; jk_open_pool(&private_data.p, buf, sizeof(buf)); private_data.pb = pb; private_data.sn = sn; private_data.rq = rq; jk_init_ws_service(&s); s.ws_private = &private_data; s.pool = &private_data.p; wc_maintain(logger); if (init_ws_service(&private_data, &s)) { jk_endpoint_t *e = NULL; if (worker->get_endpoint(worker, &e, logger)) { int is_error = JK_HTTP_SERVER_ERROR; int result; if ((result = e->service(e, &s, logger, &is_error)) > 0) { rc = REQ_PROCEED; if (JK_IS_DEBUG_LEVEL(logger)) jk_log(logger, JK_LOG_DEBUG, "service() returned OK"); } else { protocol_status(sn, rq, is_error, NULL); if ((result == JK_CLIENT_ERROR) && (is_error == JK_HTTP_OK)) { rc = REQ_EXIT; jk_log(logger, JK_LOG_INFO, "service() failed because client aborted connection"); } else { rc = REQ_ABORTED; jk_log(logger, JK_LOG_ERROR, "service() failed with http error %d", is_error); } } e->done(&e, logger); } } jk_close_pool(&private_data.p); } return rc; } static int init_ws_service(nsapi_private_data_t * private_data, jk_ws_service_t *s) { char *tmp; int size; int rc; s->start_response = start_response; s->read = ws_read; s->write = ws_write; s->auth_type = pblock_findval("auth-type", private_data->rq->vars); s->remote_user = pblock_findval("auth-user", private_data->rq->vars); tmp = NULL; rc = request_header("content-length", &tmp, private_data->sn, private_data->rq); if ((rc != REQ_ABORTED) && tmp) { sscanf(tmp, "%" JK_UINT64_T_FMT, &(s->content_length)); } s->method = pblock_findval("method", private_data->rq->reqpb); s->protocol = pblock_findval("protocol", private_data->rq->reqpb); s->remote_host = session_dns(private_data->sn); s->remote_addr = pblock_findval("ip", private_data->sn->client); /* Remote port is not available from NSAPI. */ s->remote_port = "0"; tmp = pblock_findval("uri", private_data->rq->reqpb); size = 3 * strlen(tmp) + 1; s->req_uri = jk_pool_alloc(s->pool, size); jk_canonenc(tmp, s->req_uri, size); s->query_string = pblock_findval("query", private_data->rq->reqpb); /* Local address is not available from NSAPI. */ s->local_addr = server_hostname; s->server_name = server_hostname; #ifdef NETWARE /* On NetWare, since we have virtual servers, we have a different way of * getting the port that we need to try first. */ tmp = pblock_findval("server_port", private_data->sn->client); if (NULL != tmp) s->server_port = atoi(tmp); else #endif s->server_port = server_portnum; s->server_software = system_version(); s->uw_map = uw_map; #ifdef NETWARE /* on NetWare, we can have virtual servers that are secure. * PR_IsSocketSecure is an api made available with virtual servers to check * if the socket is secure or not */ if (NULL != PR_IsSocketSecure) s->is_ssl = PR_IsSocketSecure(private_data->sn->csd); else #endif s->is_ssl = security_active; if (s->is_ssl) { char *ssl_cert = pblock_findval("auth-cert", private_data->rq->vars); if (ssl_cert != NULL) { s->ssl_cert = jk_pool_alloc(s->pool, sizeof(ssl_cert_start)+ strlen(ssl_cert)+ sizeof(ssl_cert_end)); strcpy(s->ssl_cert, ssl_cert_start); strcat(s->ssl_cert, ssl_cert); strcat(s->ssl_cert, ssl_cert_end); s->ssl_cert_len = strlen(s->ssl_cert); } s->ssl_cipher = pblock_findval("cipher", private_data->sn->client); s->ssl_session = pblock_findval("ssl-id", private_data->sn->client); /* XXX: We need to investigate how to set s->ssl_key_size */ } rc = setup_http_headers(private_data, s); /* Dump all connection param so we can trace what's going to * the remote tomcat */ if (JK_IS_DEBUG_LEVEL(logger)) { jk_log(logger, JK_LOG_DEBUG, "Service protocol=%s method=%s host=%s addr=%s name=%s port=%d auth=%s user=%s uri=%s", STRNULL_FOR_NULL(s->protocol), STRNULL_FOR_NULL(s->method), STRNULL_FOR_NULL(s->remote_host), STRNULL_FOR_NULL(s->remote_addr), STRNULL_FOR_NULL(s->server_name), s->server_port, STRNULL_FOR_NULL(s->auth_type), STRNULL_FOR_NULL(s->remote_user), STRNULL_FOR_NULL(s->req_uri)); } return rc; } static int setup_http_headers(nsapi_private_data_t * private_data, jk_ws_service_t *s) { int need_content_length_header = (s->content_length == 0) ? JK_TRUE : JK_FALSE; pblock *headers_jar = private_data->rq->headers; int cnt; int i; for (i = 0, cnt = 0; i < headers_jar->hsize; i++) { struct pb_entry *h = headers_jar->ht[i]; while (h && h->param) { cnt++; h = h->next; } } s->headers_names = NULL; s->headers_values = NULL; s->num_headers = cnt; if (cnt) { /* allocate an extra header slot in case we need to add a content-length header */ s->headers_names = jk_pool_alloc(&private_data->p, (cnt + 1) * sizeof(char *)); s->headers_values = jk_pool_alloc(&private_data->p, (cnt + 1) * sizeof(char *)); if (s->headers_names && s->headers_values) { for (i = 0, cnt = 0; i < headers_jar->hsize; i++) { struct pb_entry *h = headers_jar->ht[i]; while (h && h->param) { s->headers_names[cnt] = h->param->name; s->headers_values[cnt] = h->param->value; if (need_content_length_header && !strncmp(h->param->name, "content-length", 14)) { need_content_length_header = JK_FALSE; } cnt++; h = h->next; } } /* Add a content-length = 0 header if needed. * Ajp13 assumes an absent content-length header means an unknown, * but non-zero length body. */ if (need_content_length_header) { s->headers_names[cnt] = "content-length"; s->headers_values[cnt] = "0"; cnt++; } s->num_headers = cnt; return JK_TRUE; } } else { if (need_content_length_header) { s->headers_names = jk_pool_alloc(&private_data->p, sizeof(char *)); s->headers_values = jk_pool_alloc(&private_data->p, sizeof(char *)); if (s->headers_names && s->headers_values) { s->headers_names[0] = "content-length"; s->headers_values[0] = "0"; s->num_headers++; return JK_TRUE; } } else return JK_TRUE; } return JK_FALSE; } tomcat-connectors-1.2.41-src/native/netscape/Makefile.linux0000644000000000000020000000345611660720020022203 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Defines for example NSAPI programs running under Linux # gcc # If you get relocation errors, try: # 1. compiling with Sun's cc # 2. statically linking with libgcc # 3. Adjusting LD_LIBRARY_PATH to grab libgcc_s CC=gcc # For 64 Bit builds, add "-m64" to EXTRA_CFLAGS EXTRA_CFLAGS=-fPIC -pthread LDFLAGS=-shared CC_CMD=$(CC) $(CFLAGS) $(EXTRA_CFLAGS) \ -DNET_SSL -DSOLARIS -D_REENTRANT -DXP_UNIX -DMCC_HTTPD -DSPAPI20 -DJK_NSAPI LD_SHAREDCMD=$(CC) $(LDFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) OS_TYPE=linux INCLUDEDIR=$(IPLANET_HOME)/include JK_DIR=../common VPATH=.:$(JK_DIR) JK_SRCS = $(shell \ls $(JK_DIR)/*.c) JK_OBJECTS = $(patsubst $(JK_DIR)/%.c,%.o,$(JK_SRCS)) PLUGIN_OBJ = jk_nsapi_plugin.o INCLUDE_FLAGS= -I$(JK_DIR) -I$(INCLUDEDIR) -I$(INCLUDEDIR)/base \ -I$(INCLUDEDIR)/frame all: nsapi_redirector.so nsapi_redirector.so: $(JK_OBJECTS) $(PLUGIN_OBJ) $(LD_SHAREDCMD) $(JK_OBJECTS) $(PLUGIN_OBJ) -o nsapi_redirector.so $(EXTRA_LDDEFINES) clean: rm -f *.o nsapi_redirector.so $(JK_OBJECTS) %.o : %.c $(CC_CMD) $(INCLUDE_FLAGS) -c $< tomcat-connectors-1.2.41-src/native/netscape/Makefile.vc0000644000000000000020000001477011660226567021476 0ustar rootbin# Microsoft Developer Studio Generated NMAKE File, Based on nsapi.dsp !IF "$(CFG)" == "" CFG=nsapi - Win32 Release !MESSAGE No configuration specified. Defaulting to nsapi - Win32 Release. !ENDIF !IF "$(CFG)" != "nsapi - Win32 Release" !MESSAGE Invalid configuration "$(CFG)" specified. !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "nsapi.mak" CFG="nsapi - Win32 Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "nsapi - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE !ERROR An invalid configuration is specified. !ENDIF !IF "$(OS)" == "Windows_NT" NULL= !ELSE NULL=nul !ENDIF TARGET=nsapi_redirect$(SO_VERSION) OUTDIR=.\nsapi_release INTDIR=.\nsapi_release # Begin Custom Macros OutDir=.\nsapi_release # End Custom Macros ALL : "$(OUTDIR)\$(TARGET).dll" CLEAN : -@erase "$(INTDIR)\jk_ajp12_worker.obj" -@erase "$(INTDIR)\jk_ajp13.obj" -@erase "$(INTDIR)\jk_ajp13_worker.obj" -@erase "$(INTDIR)\jk_ajp14.obj" -@erase "$(INTDIR)\jk_ajp14_worker.obj" -@erase "$(INTDIR)\jk_ajp_common.obj" -@erase "$(INTDIR)\jk_connect.obj" -@erase "$(INTDIR)\jk_context.obj" -@erase "$(INTDIR)\jk_lb_worker.obj" -@erase "$(INTDIR)\jk_map.obj" -@erase "$(INTDIR)\jk_md5.obj" -@erase "$(INTDIR)\jk_msg_buff.obj" -@erase "$(INTDIR)\jk_nsapi_plugin.obj" -@erase "$(INTDIR)\jk_pool.obj" -@erase "$(INTDIR)\jk_shm.obj" -@erase "$(INTDIR)\jk_sockbuf.obj" -@erase "$(INTDIR)\jk_status.obj" -@erase "$(INTDIR)\jk_uri_worker_map.obj" -@erase "$(INTDIR)\jk_url.obj" -@erase "$(INTDIR)\jk_util.obj" -@erase "$(INTDIR)\jk_worker.obj" -@erase "$(OUTDIR)\$(TARGET).dll" -@erase "$(OUTDIR)\nsapi_redirect.exp" -@erase "$(OUTDIR)\nsapi_redirect.lib" -@erase "$(OUTDIR)\$(TARGET).pdb" -@erase "$(OUTDIR)\nsapi_redirect_src.idb" -@erase "$(OUTDIR)\\nsapi_redirect_src.pdb" "$(OUTDIR)" : if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)" CPP=cl.exe CPP_PROJ=-nologo -MD -W3 -O2 -Ob2 -Oy- -Zi -EHsc /I "..\common" /I "$(IPLANET_HOME)\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "JK_NSAPI" /D "NSAPI_EXPORTS" /D "XP_WIN32" /D "MCC_HTTPD" /D "SPAPI20" /Fo"$(INTDIR)\\" /Fd"$(OUTDIR)\nsapi_redirect_src" /FD /c .c{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.obj:: $(CPP) @<< $(CPP_PROJ) $< << .c{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cpp{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << .cxx{$(INTDIR)}.sbr:: $(CPP) @<< $(CPP_PROJ) $< << MTL=midl.exe MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32 RSC=rc.exe RSC_PROJ=/l 0x409 /fo"$(INTDIR)\jk.res" /i "..\common" /d "JK_NSAPI" /d "NDEBUG" BSC32=bscmake.exe BSC32_FLAGS=/nologo /o"$(OUTDIR)\nsapi.bsc" BSC32_SBRS= \ LINK32=link.exe LINK32_FLAGS=ns-httpd40.lib kernel32.lib user32.lib advapi32.lib ws2_32.lib mswsock.lib $(EXTRA_LIBS) /nologo /base:"0x6A6B0000" /dll /incremental:no /pdb:"$(OUTDIR)\$(TARGET).pdb" /debug /machine:I386 /out:"$(OUTDIR)\$(TARGET).dll" /implib:"$(OUTDIR)\nsapi_redirect.lib" /libpath:"$(IPLANET_HOME)\lib" LINK32_OBJS= \ "$(INTDIR)\jk_ajp12_worker.obj" \ "$(INTDIR)\jk_ajp13.obj" \ "$(INTDIR)\jk_ajp13_worker.obj" \ "$(INTDIR)\jk_ajp14.obj" \ "$(INTDIR)\jk_ajp14_worker.obj" \ "$(INTDIR)\jk_ajp_common.obj" \ "$(INTDIR)\jk_connect.obj" \ "$(INTDIR)\jk_context.obj" \ "$(INTDIR)\jk_lb_worker.obj" \ "$(INTDIR)\jk_map.obj" \ "$(INTDIR)\jk_md5.obj" \ "$(INTDIR)\jk_msg_buff.obj" \ "$(INTDIR)\jk_nsapi_plugin.obj" \ "$(INTDIR)\jk_pool.obj" \ "$(INTDIR)\jk_shm.obj" \ "$(INTDIR)\jk_sockbuf.obj" \ "$(INTDIR)\jk_status.obj" \ "$(INTDIR)\jk_uri_worker_map.obj" \ "$(INTDIR)\jk_url.obj" \ "$(INTDIR)\jk_util.obj" \ "$(INTDIR)\jk.res" \ "$(INTDIR)\jk_worker.obj" "$(OUTDIR)\$(TARGET).dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) $(LINK32) @<< $(LINK32_FLAGS) $(LINK32_OBJS) << IF EXIST $(OUTDIR)\$(TARGET).manifest \ mt -nologo -manifest $(OUTDIR)\$(TARGET).manifest -outputresource:$(OUTDIR)\$(TARGET).dll;2 !IF "$(CFG)" == "nsapi - Win32 Release" SOURCE=..\common\jk.rc "$(INTDIR)\jk.res" : $(SOURCE) "$(INTDIR)" $(RSC) $(RSC_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp12_worker.c "$(INTDIR)\jk_ajp12_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp13.c "$(INTDIR)\jk_ajp13.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp13_worker.c "$(INTDIR)\jk_ajp13_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp14.c "$(INTDIR)\jk_ajp14.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp14_worker.c "$(INTDIR)\jk_ajp14_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_ajp_common.c "$(INTDIR)\jk_ajp_common.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_connect.c "$(INTDIR)\jk_connect.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_context.c "$(INTDIR)\jk_context.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_lb_worker.c "$(INTDIR)\jk_lb_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_map.c "$(INTDIR)\jk_map.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_md5.c "$(INTDIR)\jk_md5.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_msg_buff.c "$(INTDIR)\jk_msg_buff.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=.\jk_nsapi_plugin.c "$(INTDIR)\jk_nsapi_plugin.obj" : $(SOURCE) "$(INTDIR)" SOURCE=..\common\jk_pool.c "$(INTDIR)\jk_pool.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_shm.c "$(INTDIR)\jk_shm.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_sockbuf.c "$(INTDIR)\jk_sockbuf.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_status.c "$(INTDIR)\jk_status.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_uri_worker_map.c "$(INTDIR)\jk_uri_worker_map.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_url.c "$(INTDIR)\jk_url.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_util.c "$(INTDIR)\jk_util.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) SOURCE=..\common\jk_worker.c "$(INTDIR)\jk_worker.obj" : $(SOURCE) "$(INTDIR)" $(CPP) $(CPP_PROJ) $(SOURCE) !ENDIF tomcat-connectors-1.2.41-src/native/netscape/README0000644000000000000020000000176112555244075020301 0ustar rootbinABOUT ----- The redirector was originally developed using Visual C++ Ver.6.0, so having this environment is a prerequisite if you want to perform a custom build on Windows systems On Unix system, a Makefile.solaris and Makefile.linux are provided and should be adapted to tailor to your own configuration. Be sure to read the BUILDING.txt file, one directory up. REQUIREMENT for Windows build ----------------------------- MS VC 6.0 (+ update, latest service pack is 6) BUILDING on Windows ------------------- The steps that you need to take are: 1. Change directory to the nsapi redirector plugins source directory. 2. Set the IPLANET_HOME system environment value to iPlanet installation directory or edit the nsapi.dsp and replace all $(IPLANET_HOME) occurrences with the real path 3. Execute the following command: nmake -f Makefile.vc [SO_VERSION=-1.2.41] An alternative will be to open the isapi workspace file (nsapi.dsw) in msdev and build it using the build menu. tomcat-connectors-1.2.41-src/native/Makefile.am0000644000000000000020000000252211460211630017630 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Tell automake what it should do AUTOMAKE_OPTIONS = foreign MAINTAINERCLEANFILES=config.cache config.status config.log \ config.nice Makefile.in configure common/config.h.in \ common/config.h aclocal.m4 SUBDIRS = @WEBSERVER@ all: target="all"; \ list='$(SUBDIRS)'; \ for i in $$list; do \ echo "Making $$target in $$i"; \ if test "$$i" != "."; then \ (cd $$i && $(MAKE) $$target) || exit 1; \ fi; \ done; apidocs: common/*.h ../../scandoc/scandoc.pl -i ../../scandoc/template.pl -p \ ./docs/api/ -dproject="mod_jk Library" common/*.h common/*.c tomcat-connectors-1.2.41-src/native/configure.ac0000644000000000000020000005233012445347314020101 0ustar rootbindnl Licensed to the Apache Software Foundation (ASF) under one or more dnl contributor license agreements. See the NOTICE file distributed with dnl this work for additional information regarding copyright ownership. dnl The ASF licenses this file to You under the Apache License, Version 2.0 dnl (the "License"); you may not use this file except in compliance with dnl the License. You may obtain a copy of the License at dnl dnl http://www.apache.org/licenses/LICENSE-2.0 dnl dnl Unless required by applicable law or agreed to in writing, software dnl distributed under the License is distributed on an "AS IS" BASIS, dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. dnl See the License for the specific language governing permissions and dnl limitations under the License. dnl dnl Process this file with autoconf to produce a configure script dnl AC_REVISION($Id: configure.ac 1647040 2014-12-20 19:32:28Z rjung $)dnl dnl Minimum autoconf version AC_PREREQ(2.59) dnl package and version. dnl synchronization with common/jk_version.h ? AC_INIT([mod_jk], [1.2.41]) AC_CONFIG_SRCDIR([common/jk_worker.h]) AC_CONFIG_HEADER(common/config.h) AC_CONFIG_AUX_DIR(scripts/build/unix) AC_CANONICAL_SYSTEM AM_INIT_AUTOMAKE dnl dnl Include our own M4 macros dnl sinclude(scripts/build/jk_common.m4) dnl Generate ./config.nice for reproducing runs of configure dnl JK_CONFIG_NICE(config.nice) AC_PATH_PROG(TEST,test,$PATH)dnl AC_SUBST(TEST) AC_PATH_PROG(GREP,grep,$PATH)dnl AC_SUBST(GREP) AC_PATH_PROG(ECHO,echo,echo,$PATH)dnl AC_SUBST(ECHO) AC_PATH_PROG(SED,sed,$PATH)dnl AC_SUBST(SED) AC_PATH_PROG(CP,cp,$PATH)dnl AC_SUBST(CP) AC_PATH_PROG(MKDIR,mkdir,$PATH)dnl AC_SUBST(MKDIR) dnl Mark that we have generated config.h CFLAGS="${CFLAGS} -DHAVE_CONFIG_H" AC_SUBST(CFLAGS) configure_dir=`dirname $0` configure_dir=`cd $configure_dir; pwd` APACHE_CONFIG_VARS=$configure_dir/scripts/build/config_vars.mk WEBSERVER="" apache_dir="" apache_include="" APXS="apxs" AC_ARG_WITH(apxs, [[ --with-apxs[=FILE] Build shared Apache module. FILE is the optional pathname to the apxs tool; defaults to finding apxs in your PATH.]], [ case "${withval}" in y | yes | true) find_apxs=true ;; n | no | false) find_apxs= ;; *) find_apxs=${withval} ;; esac if ${TEST} ${find_apxs} ; then AC_MSG_RESULT([need to check for Perl first, apxs depends on it...]) AC_PATH_PROG(PERL,perl,$PATH)dnl if ${TEST} ${find_apxs} = true ; then AC_PATH_PROG(APXS,apxs,$PATH)dnl else APXS=${find_apxs} fi if ${TEST} -n "${APXS}" ; then dnl Seems that we have it, but have to check if it is OK first if ${TEST} ! -x "${APXS}" ; then AC_MSG_ERROR(Invalid location for apxs: '${APXS}') fi ${APXS} -q PREFIX >/dev/null 2>/dev/null || apxs_support=false if ${TEST} "${apxs_support}" = "false" ; then AC_MSG_RESULT(could not find ${APXS}) AC_MSG_ERROR(You must specify a valid --with-apxs path) fi dnl apache_dir and apache_include are also needed. apache_dir=`$APXS -q PREFIX` apache_include="-I`$APXS -q INCLUDEDIR`" dnl test apache version APA=`${GREP} STANDARD20 ${APXS}` if ${TEST} -z "$APA" ; then WEBSERVER="apache-1.3" APXSCC="`$APXS -q CC`" APXSCFLAGS="`$APXS -q CFLAGS` -DJK_PREFORK" APXSCPPFLAGS="" APXSLDFLAGS="`$APXS -q LDFLAGS_SHLIB`" else WEBSERVER="apache-2.0" APRINCLUDEDIR="" INCTEMP="`$APXS -q APR_INCLUDEDIR` `$APXS -q APU_INCLUDEDIR`" for INC in ${INCTEMP}; do APRINCLUDEDIR="${APRINCLUDEDIR} -I${INC}" done AC_MSG_RESULT([APRINCLUDEDIR is $APRINCLUDEDIR]) APXSCC="`$APXS -q CC`" APXSCFLAGS="`${APXS} -q CFLAGS` `${APXS} -q EXTRA_CFLAGS` -DHAVE_APR ${APRINCLUDEDIR}" APXSCPPFLAGS="`${APXS} -q EXTRA_CPPFLAGS`" APXSLDFLAGS="`$APXS -q LDFLAGS`" APACHE_CONFIG_VARS="`${APXS} -q exp_installbuilddir`/config_vars.mk" LIBTOOL=`$APXS -q LIBTOOL` fi AC_MSG_RESULT([building connector for \"$WEBSERVER\"]) if ${TEST} -z "${CC}" ; then CC="${APXSCC}" else if ${TEST} "${CC}" != "$APXSCC" ; then WARN_CC=1 fi fi AC_SUBST(APXS) fi fi ], [ AC_MSG_RESULT(no apxs given) ]) AC_SUBST(APACHE_CONFIG_VARS) AC_PROG_CC AC_PROG_LD SAVE_LIBTOOL="$LIBTOOL" dnl Not sure what it does, but the libtool manual seems to require this dnl It should use the native platform dlopen ( if available ) AC_LIBTOOL_DLOPEN dnl AM_PROG_LIBTOOL often causes problems. dnl I have solved them once using aclocal --acdir=/usr/local/share/aclocal/ AM_PROG_LIBTOOL if ${TEST} -n "${SAVE_LIBTOOL}" ; then LIBTOOL="$SAVE_LIBTOOL" fi AC_MSG_RESULT([LIBTOOL="$LIBTOOL"]) AC_SUBST(LIBTOOL) dnl ----------------------------- Checks for standard typedefs dnl Checks for integer size AC_CHECK_SIZEOF(char, 1) AC_CHECK_SIZEOF(int, 4) AC_CHECK_SIZEOF(long, 4) AC_CHECK_SIZEOF(short, 2) AC_CHECK_SIZEOF(long double, 12) AC_CHECK_SIZEOF(long long, 8) AC_CHECK_SIZEOF(longlong, 8) # Now we need to find what jk_uint32_t (sizeof == 4) will be. # The first match is our preference. if test "$ac_cv_sizeof_int" = "4"; then int32_t_fmt='#define JK_INT32_T_FMT "d"' uint32_t_fmt='#define JK_UINT32_T_FMT "u"' uint32_t_hex_fmt='#define JK_UINT32_T_HEX_FMT "x"' int32_value="int" elif test "$ac_cv_sizeof_long" = "4"; then int32_t_fmt='#define JK_INT32_T_FMT "ld"' uint32_t_fmt='#define JK_UINT32_T_FMT "lu"' uint32_t_hex_fmt='#define JK_UINT32_T_HEX_FMT "lx"' int32_value="long" else int32_t_fmt='#error could not detect a 32-bit integer type' uint32_t_fmt='#error could not detect a 32-bit integer type' uint32_t_hex_fmt='#error could not detect a 32-bit integer type' AC_ERROR([could not detect a 32-bit integer type]) fi # Now we need to find what jk_uint64_t (sizeof == 8) will be. # The first match is our preference. if test "$ac_cv_sizeof_int" = "8"; then int64_t_fmt='#define JK_INT64_T_FMT "d"' uint64_t_fmt='#define JK_UINT64_T_FMT "u"' uint64_t_hex_fmt='#define JK_UINT64_T_HEX_FMT "x"' int64_value="int" elif test "$ac_cv_sizeof_long" = "8"; then int64_t_fmt='#define JK_INT64_T_FMT "ld"' uint64_t_fmt='#define JK_UINT64_T_FMT "lu"' uint64_t_hex_fmt='#define JK_UINT64_T_HEX_FMT "lx"' int64_value="long" elif test "$ac_cv_sizeof_long_long" = "8"; then # Linux, Solaris, FreeBSD all support ll with printf. # BSD 4.4 originated 'q'. Solaris is more popular and # doesn't support 'q'. Solaris wins. Exceptions can # go to the OS-dependent section. int64_t_fmt='#define JK_INT64_T_FMT "lld"' uint64_t_fmt='#define JK_UINT64_T_FMT "llu"' uint64_t_hex_fmt='#define JK_UINT64_T_HEX_FMT "llx"' int64_value="long long" elif test "$ac_cv_sizeof_long_double" = "8"; then int64_t_fmt='#define JK_INT64_T_FMT "Ld"' uint64_t_fmt='#define JK_UINT64_T_FMT "Lu"' uint64_t_hex_fmt='#define JK_UINT64_T_HEX_FMT "Lx"' int64_value="long double" elif test "$ac_cv_sizeof_longlong" = "8"; then int64_t_fmt='#define JK_INT64_T_FMT "qd"' uint64_t_fmt='#define JK_UINT64_T_FMT "qu"' uint64_t_hex_fmt='#define JK_UINT64_T_HEX_FMT "qx"' int64_value="__int64" else int64_t_fmt='#error could not detect a 64-bit integer type' uint64_t_fmt='#error could not detect a 64-bit integer type' uint64_t_hex_fmt='#error could not detect a 64-bit integer type' AC_ERROR([could not detect a 64-bit integer type]) fi JK_CHECK_SIZEOF_EXTENDED([#include ], pid_t, 8) if test "$ac_cv_sizeof_pid_t" = "$ac_cv_sizeof_short"; then pid_t_fmt='#define JK_PID_T_FMT "hd"' elif test "$ac_cv_sizeof_pid_t" = "$ac_cv_sizeof_int"; then pid_t_fmt='#define JK_PID_T_FMT "d"' elif test "$ac_cv_sizeof_pid_t" = "$ac_cv_sizeof_long"; then pid_t_fmt='#define JK_PID_T_FMT "ld"' elif test "$ac_cv_sizeof_pid_t" = "$ac_cv_sizeof_long_long"; then pid_t_fmt='#define JK_PID_T_FMT JK_INT64_T_FMT' else pid_t_fmt='#error Can not determine the proper size for pid_t' fi JK_CHECK_SIZEOF_EXTENDED([#include ], pthread_t, 8) if test "$ac_cv_sizeof_pthread_t" = "$ac_cv_sizeof_short"; then pthread_t_fmt='#define JK_PTHREAD_T_FMT "hu"' pthread_t_value="short" elif test "$ac_cv_sizeof_pthread_t" = "$ac_cv_sizeof_int"; then pthread_t_fmt='#define JK_PTHREAD_T_FMT "u"' pthread_t_value="int" elif test "$ac_cv_sizeof_pthread_t" = "$ac_cv_sizeof_long"; then pthread_t_fmt='#define JK_PTHREAD_T_FMT "lu"' pthread_t_value="long" elif test "$ac_cv_sizeof_pthread_t" = "$ac_cv_sizeof_long_long"; then pthread_t_fmt='#define JK_PTHREAD_T_FMT "llu"' pthread_t_value="long long" else pthread_t_fmt='#error Can not determine the proper size for pthread_t' fi # Basically, we have tried to figure out the correct format strings # for pid_t which varies between platforms, but we don't always get # it right. If you find that we don't get it right for your platform, # you can override our decision below. case $host in *-solaris*) if test "$ac_cv_sizeof_pid_t" = "$ac_cv_sizeof_long"; then pid_t_fmt='#define JK_PID_T_FMT "ld"' fi ;; esac AC_SUBST(int32_value) AC_SUBST(int32_t_fmt) AC_SUBST(uint32_t_fmt) AC_SUBST(uint32_t_hex_fmt) AC_SUBST(int64_value) AC_SUBST(int64_t_fmt) AC_SUBST(uint64_t_fmt) AC_SUBST(uint64_t_hex_fmt) AC_SUBST(pid_t_fmt) AC_SUBST(pthread_t_fmt) AC_SUBST(pthread_t_value) dnl check for snprintf and vsnprintf. AC_CHECK_FUNC(snprintf, AC_DEFINE(HAVE_SNPRINTF,1,[Have snprintf()])) AC_CHECK_FUNC(vsnprintf, AC_DEFINE(HAVE_VSNPRINTF,1,[Have vsnprintf()])) dnl check for flock function. AC_CHECK_FUNC(flock, AC_DEFINE(HAVE_FLOCK,1,[Have flock()])) dnl check for -lsocket library AC_CHECK_LIB(socket, setsockopt, [LIBS="$LIBS -lsocket"]) dnl check for filio.h used on Solaris to define FIONREAD ioctl. AC_CHECK_HEADERS(sys/filio.h) AC_DEFUN([JK_CHECK_SETSOCKOPT], [ AC_MSG_CHECKING(whether to use $1 with setsockopt()) AC_TRY_RUN([ #include #include #include int main(void) { int s; struct timeval tv; tv.tv_sec = 3; tv.tv_usec = 0; #ifndef $1 exit(3); #else if ((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) exit(2); /* fails on Solaris 2.6,8,9,10 and some Linuxes because SO_RCVTIMEO|SO_SNDTIMEO are defined but not implemented */ if (setsockopt(s, SOL_SOCKET, $1, (const void *)&tv, sizeof(tv)) == -1) exit(1); exit(0); #endif } ] , [ AC_MSG_RESULT([yes]) AC_DEFINE(USE_$1, 1, [Define to use $1 with setsockopt()]) ] , [ AC_MSG_RESULT([no]) ] ) ])dnl dnl check for SO_RCVTIMEO and SO_SNDTIMEO JK_CHECK_SETSOCKOPT(SO_RCVTIMEO) JK_CHECK_SETSOCKOPT(SO_SNDTIMEO) AC_DEFUN([JK_CHECK_SOCKOPT], [ AC_MSG_CHECKING(whether to use $1 with socket()) AC_TRY_RUN([ #include #include #include int main(void) { int s; #ifndef $1 exit(3); #else if ((s = socket(AF_INET, SOCK_STREAM | $1, 0)) == -1) exit(2); exit(0); #endif } ] , [ AC_MSG_RESULT([yes]) AC_DEFINE(USE_$1, 1, [Define to use $1 with socket()]) ] , [ AC_MSG_RESULT([no]) ] ) ])dnl AC_ARG_ENABLE(sock-cloexec, [AS_HELP_STRING([--disable-sock-cloexec],[Disable use of SOCK_CLOEXEC. This ensures the built module can be used on systems that do not support SOCK_CLOEXEC])], [ case "${enableval}" in y | Y | YES | yes | TRUE | true ) dnl check for SOCK_CLOEXEC JK_CHECK_SOCKOPT(SOCK_CLOEXEC) ;; esac ], [ dnl check for SOCK_CLOEXEC JK_CHECK_SOCKOPT(SOCK_CLOEXEC) ]) dnl check for poll.h header AC_CHECK_HEADERS(poll.h) dnl check for poll function AC_CHECK_FUNC(poll, AC_DEFINE(HAVE_POLL,1,[Have poll()])) dnl check for netinet/in.h header AC_CHECK_HEADERS(netinet/in.h) dnl check for netdb.h header AC_CHECK_HEADERS(netdb.h) AC_DEFUN([JK_HAVE_IPV6], [ AC_MSG_CHECKING(for IPv6 with socket()) AC_TRY_RUN([ #include #include #include int main(void) { int s; if ((s = socket(AF_INET6, SOCK_STREAM, 0)) == -1) exit(2); exit(0); } ] , [ AC_MSG_RESULT([yes]) AC_DEFINE(HAVE_AF_INET6, 1, [Define to 1 if you have IPv6 support]) ] , [ AC_MSG_RESULT([no]) ] ) ])dnl AC_DEFUN([JK_CHECK_SASTORAGE], [ AC_MSG_CHECKING(for struct sockaddr_storage) AC_TRY_RUN([ #include #include #include int main(void) { struct sockaddr_storage sa; exit(sizeof(sa) == 0); } ] , [ AC_MSG_RESULT([yes]) AC_DEFINE(HAVE_SOCKADDR_STORAGE, 1, [Define to 1 if you have struct sockaddr_storage]) ] , [ AC_MSG_RESULT([no]) ] ) ])dnl JK_HAVE_IPV6 JK_CHECK_SASTORAGE AC_CHECK_FUNC(getaddrinfo, AC_DEFINE(HAVE_GETADDRINFO,1,[Have getaddrinfo()])) AC_CHECK_FUNC(gethostbyname_r, AC_DEFINE(HAVE_GETHOSTBYNAME_R,1,[Have gethostbyname_r()])) dnl Apache-2.0 needs the os subdirectory to include os.h dnl this include is copy from os/config.m4 sinclude(../support/os_apache.m4) dnl it is copied from the configure of JServ ;=) dnl and adapted. apache_dir_is_src="false" AC_ARG_WITH(apache, [AS_HELP_STRING([--with-apache=DIR], [Build static Apache module. DIR is the pathname to the Apache source directory.])], [ if ${TEST} ! -z "$WEBSERVER" ; then AC_MSG_ERROR([Sorry cannot use --with-apxs=${APXS} and --with-apache=${withval} together, please choose one of both]) fi AC_MSG_CHECKING([for Apache source directory (assume static build)]) if ${TEST} -n "${withval}" && ${TEST} -d "${withval}" ; then if ${TEST} -d "${withval}/src" ; then # handle the case where people use relative paths to # the apache source directory by pre-pending the current # build directory to the path. there are probably # errors with this if configure is run while in a # different directory than what you are in at the time if ${TEST} -n "`${ECHO} ${withval}|${GREP} \"^\.\.\"`" ; then withval=`pwd`/${withval} fi apache_dir=${withval} apache_dir_is_src="true" AC_MSG_RESULT(${apache_dir}) AC_MSG_CHECKING(for Apache include directory) if ${TEST} -d "${withval}/src/include" ; then # read osdir from the existing apache. osdir=`${GREP} '^OSDIR=' ${withval}/src/Makefile.config | ${SED} -e 's:^OSDIR=.*/os:os:'` if ${TEST} -z "${osdir}" ; then osdir=os/unix fi apache_include="-I${withval}/src/include \ -I${withval}/src/${osdir}" WEBSERVER="apache-1.3" LIB_JK_TYPE=mod_jk.a CFLAGS="${CFLAGS} -DJK_PREFORK" AC_MSG_RESULT([${apache_include}, version 1.3]) else AC_MSG_ERROR([Sorry Apache 1.2.x is no longer supported.]) fi else if ${TEST} -d "${withval}/include" ; then # osdir for Apache20. WEBSERVER="apache-2.0" apache_dir=${withval} apache_dir_is_src="true" LIB_JK_TYPE=lib_jk.la apache_include="-I${withval}/include -I${withval}/srclib/apr/include -I${withval}/os/${OS_APACHE_DIR} -I${withval}/srclib/apr-util/include" AC_MSG_RESULT(${apache_dir}) fi fi fi dnl Make sure we have a result. if ${TEST} -z "$WEBSERVER" ; then AC_MSG_ERROR([Directory $apache_dir is not a valid Apache source distribution]) fi # VT: Now, which one I'm supposed to use? Let's figure it out later configure_apache=true configure_src=true AC_MSG_RESULT([building connector for \"$WEBSERVER\"]) ], [ AC_MSG_RESULT(no apache given) ]) AC_SUBST(apache_include) APACHE_DIR=${apache_dir} AC_SUBST(APACHE_DIR) AC_ARG_ENABLE(netscape, [AS_HELP_STRING([--enable-netscape=DIR],[Build Netscape/iPlanet/SunONE nsapi redirector plugin])], [ if ${TEST} ! -z "$WEBSERVER" ; then AC_MSG_ERROR([Sorry cannot use --with-apxs=${APXS} or --with-apache=${withval} with --with-netscape, please choose one or the other.]) fi WEBSERVER="netscape" AC_MSG_RESULT([building connector for \"$WEBSERVER\"]) ], [ AC_MSG_RESULT(no netscape given) ]) dnl CFLAGS for EAPI mod_ssl (Apache 1.3) dnl it also allows the CFLAGS environment variable. CFLAGS="${CFLAGS}" AC_ARG_ENABLE(EAPI, [AS_HELP_STRING([--enable-EAPI],[Enable EAPI support (mod_ssl, Apache 1.3)])], [ case "${enableval}" in y | Y | YES | yes | TRUE | true ) CFLAGS="${CFLAGS} -DEAPI" AC_MSG_RESULT([...Enabling EAPI Support...]) ;; esac ]) AC_SUBST(CFLAGS) dnl CFLAGS for maintainer mode dnl it also allows the CFLAGS environment variable. CFLAGS="${CFLAGS}" AC_ARG_ENABLE(maintainer-mode, [AS_HELP_STRING([--enable-maintainer-mode],[Turn on debugging and compile time warnings])], [ case "${enableval}" in y | Y | YES | yes | TRUE | true ) CFLAGS="${CFLAGS} -DDEBUG -Wall" AC_MSG_RESULT([...Enabling Maintainer mode...]) ;; esac ]) AC_SUBST(CFLAGS) dnl CFLAGS for prefork mode dnl it also allows the CFLAGS environment variable. CFLAGS="${CFLAGS}" AC_ARG_ENABLE(prefork, [AS_HELP_STRING([--enable-prefork],[Turn on prefork web server mode (single-threaded)])], [ case "${enableval}" in y | Y | YES | yes | TRUE | true ) CFLAGS="${CFLAGS} -DJK_PREFORK" AC_MSG_RESULT([...Enabling Prefork mode...]) ;; esac ]) AC_SUBST(CFLAGS) dnl CFLAGS for stripping TRACE logs dnl it also allows the CFLAGS environment variable. CFLAGS="${CFLAGS}" AC_ARG_ENABLE(trace, [AS_HELP_STRING([--disable-trace],[Exclude trace log code from compilation])], [ case "${enableval}" in no ) CFLAGS="${CFLAGS} -DJK_PRODUCTION" AC_MSG_RESULT([...Exclude trace log code...]) ;; esac ]) AC_SUBST(CFLAGS) dnl CFLAGS for building against recent httpd but without dnl using httpd API functions, which didn't exist in the first dnl production releases. This ensures, that the resulting dnl module binary is compatible with older httpd releases. dnl Until now only relevant for httpd 2.2.x with x >= 4. CFLAGS="${CFLAGS}" AC_ARG_ENABLE(api-compatibility, [AS_HELP_STRING([--enable-api-compatibility], [Only use httpd API functions available in all production releases. This improves binary compatibility of module builds with httpd releases older than the release against we build (only between minor versions).])], [ case "${enableval}" in y | Y | YES | yes | TRUE | true ) CFLAGS="${CFLAGS} -DAPI_COMPATIBILITY" AC_MSG_RESULT([...Only using compatible httpd API...]) ;; esac ]) AC_SUBST(CFLAGS) dnl CFLAGS for shared memory lock mode dnl it also allows the CFLAGS environment variable. CFLAGS="${CFLAGS}" AC_ARG_ENABLE(flock, [AS_HELP_STRING([--enable-flock],[Turn on flock for shared locking if present])], [ case "${enableval}" in y | Y | YES | yes | TRUE | true ) CFLAGS="${CFLAGS} -DJK_USE_FLOCK" AC_MSG_RESULT([...Enabling flock() shared memory locking...]) ;; esac ]) AC_SUBST(CFLAGS) dnl the APXSCFLAGS is given by apxs to the C compiler if ${TEST} -n "${CFLAGS}" ; then APXSCFLAGS="${APXSCFLAGS} ${CFLAGS}" fi AC_SUBST(APXSCFLAGS) AC_SUBST(APXSCPPFLAGS) dnl the APXSLDFLAGS is given to the linker (for APRVARS). if ${TEST} -n "${LDFLAGS}" ; then APXSLDFLAGS="${APXSLDFLAGS} ${LDFLAGS}" fi dnl Prefix all LDFLAGS with "-Wl,", dnl because we pass them to libtool JK_PREFIX_IF_MISSING(APXSLDFLAGS, [-Wl,]) AC_SUBST(APXSLDFLAGS) dnl Check that a WEBSERVER has been given if ${TEST} -z "$WEBSERVER" ; then AC_MSG_ERROR(Cannot find the WebServer) fi dnl Add common to subdir list WEBSERVER="common ${WEBSERVER}" AC_SUBST(WEBSERVER) AM_CONDITIONAL(MAKE_DYNAMIC_APACHE, ${TEST} "${apache_dir_is_src}" = "false") if ${TEST} "${apache_dir_is_src}" = "false" ; then dnl normal apxs handling APACHE20_OEXT=.c LIB_JK_TYPE=mod_jk.so INSTALL_TYPE=install_dynamic else dnl install static library in apache sources. APACHE20_OEXT=.lo INSTALL_TYPE=install_static fi AC_SUBST(APACHE20_OEXT) AC_SUBST(LIB_JK_TYPE) AC_SUBST(INSTALL_TYPE) dnl automake needs the path it does not work with $WEBSERVER dnl that why useless Makefiles are build. AC_OUTPUT([ Makefile apache-1.3/Makefile apache-1.3/Makefile.apxs apache-2.0/Makefile apache-2.0/Makefile.apxs common/Makefile common/list.mk common/jk_types.h ]) if ${TEST} -n "${WARN_CC}" ; then AC_MSG_WARN([===========================================]) AC_MSG_WARN([Using CC from environment:]) AC_MSG_WARN([ CC="$CC"]) AC_MSG_WARN([instead of CC from apxs:]) AC_MSG_WARN([ CC="$APXSCC"]) AC_MSG_WARN([If "make" throws an error of the form]) AC_MSG_WARN([ "libtool: compile: unable to infer tagged configuration"]) AC_MSG_WARN([ "libtool: compile: specify a tag with `--tag'"]) AC_MSG_WARN([try running configure without setting CC,]) AC_MSG_WARN([or at least CC should start with "$APXSCC"]) AC_MSG_WARN([===========================================]) fi tomcat-connectors-1.2.41-src/README.txt0000644000000000000020000000232611731403060016007 0ustar rootbin Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Building the Web Server Connectors ================================== 1) Install the web server 2) Go to the "native" subdirectory cd native 3) Proceed with the instructions in BUILDING.txt. Building the Docs ================= 1) Make sure you have Java and "ant" installed and "ant" is found in your PATH 2) Go to the "xdocs" subdirectory cd xdocs 3) Call "ant" ant 4) The resulting documentation can be in the directory build/docs. tomcat-connectors-1.2.41-src/docs/0000755000000000000020000000000012555256556015263 5ustar rootbintomcat-connectors-1.2.41-src/docs/ajp/0000755000000000000020000000000012555256556016035 5ustar rootbintomcat-connectors-1.2.41-src/docs/ajp/ajpv13ext.html0000644000000000000020000007246212555256556020563 0ustar rootbinThe Apache Tomcat Connectors - AJP Protocol Reference - AJPv13 extensions Proposal
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - AJP Protocol Reference

AJPv13 extensions Proposal

Printer Friendly Version
print-friendly
version
Introduction

This document is a proposal of evolution of the current Apache JServ Protocol version 1.3, also known as ajp13. I'll not cover here the full protocol but only the add-on from ajp13. This nth pass include comments from the tomcat-dev list and misses discovered during developpment.

Missing features in AJP13

ajp13 is a good protocol to link a servlet engine like tomcat to a web server like Apache:

  • use persistants connections to avoid reconnect time at each request
  • encode many http commands to reduce stream size
  • send to servlet engine many info from web server (like SSL certs)

But ajp13 lacks support for :

  • security between web server and servlet engine. Anybody can connect to an ajp13 port (no login mecanism used) You could connect, for example with telnet, and keep the remote thread up by not sending any data (no timeout in connection)
  • context information passed from servlet engine to web server. Part of the configuration of JK, the web server connector, is to indicate to the web server which URI to handle. The mod_jk JkMount directive, told to web server which URI must be forwarded to servlet engine. A servlet engine allready knows which URI it handle and TC 3.3 is allready capable to generate a config file for JK from the list of available contexts.
  • state update of contexts from servlet engine to web server. Big site with farm of Tomcat, like ISP and virtuals hosters, may need to stop a context for admin purposes. In that case the front web server must know that the context is currently down, to eventually relay the request to another Tomcat
  • verify state of connection before sending request. Actually JK send the request to the servlet engine and next wait for the answer. But one of the beauty of the socket API, is you that you could write() to a closed connection without any error reporting, but a read() to a closed connection return you the error code.

Proposed add-ons to AJP13

Let's descrive here the features and add-on that could be added to AJP13. Since this document is a proposal, a reasonable level of chaos must be expected at first. Be sure that discussion on tomcat list will help clarify points, add features but the current list seems to be a 'minimun vital'

  • Advanced login features at connect time
  • Basic authorisation system, where a shared secret key is present in web server and servlet engine.
  • Basic protocol negociation, just to be sure that if functionnalities are added to AJP13 in the future, current implementations will still works.
  • Clean handling of 'Unknown packets'
  • Extended env vars passed from web-server to servlet engine.
  • Add extra SSL informations needed by Servlet 2.3 API (like SSL_KEY_SIZE)

Advanced login

  1. WEB-SERVER send LOGIN INIT CMD + NEGOCIATION DATA + WEB SERVER INFO
  2. TOMCAT respond with LOGIN SEED CMD + RANDOM DATA
  3. WEB-SERVER calculted the MD5 of RANDOM DATA+SECRET DATA
  4. WEB-SERVER send LOGIN COMP CMD + MD5 (SECRET DATA + RANDOM DATA)
  5. TOMCAT respond with LOGIN STATUS CMD + NEGOCIED DATA + SERVLET ENGINE INFO
To prevent DOS attack, the servlet engine will wait the LOGIN CMD only 15/30 seconds and reports the timeout exception for admins investigation. The login command will contains basic protocol negociation information like compressing ability, crypto, context info (at start up), context update at run-time (up/down), level of SSL env vars, AJP protocol level supported (level1/level2/level3...) The Web server info will contain web server info and connector name (ie Apache 1.3.26 + mod_ssl 2.8.8 + mod_jk 1.2.41 + mod_perl 1.25). The servlet engine will mask the negociation mask with it's own mask (what it can do) and return it when loggin is accepted. This will help having a basic AJP13 implementation (level 1) on a web-server working with a more advanced protocol handler on the servlet engine side or vice-versa. AJP13 was designed to be small and fast and so many SSL informations present in the web-server are not forwarded to the servlet engine. We add here four negociations flags to provide more informations on client SSL data (certs), server SSL datas, crypto used, and misc datas (timeout...).

Messages Stream

+----------------+------------------+-----------------+
| LOGIN INIT CMD | NEGOCIATION DATA | WEB SERVER INFO |
+----------------+------------------+-----------------+

+----------------+----------------+
| LOGIN SEED CMD | MD5 of entropy |
+----------------+----------------+

+----------------+----------------------------+
| LOGIN COMP CMD | MD5 of RANDOM + SECRET KEY |
+----------------+----------------------------+

+-----------+---------------+---------------------+
| LOGOK CMD | NEGOCIED DATA | SERVLET ENGINE INFO |
+-----------+---------------+---------------------+

+------------+--------------+
| LOGNOK CMD | FAILURE CODE |
+------------+--------------+
  • LOGIN INIT CMD, LOGIN SEED CMD, LOGIN COMP CMD, LOGOK CMD, LOGNOK CMD are 1 byte long.
  • MD5, MD5 of RANDOM + SECRET KEY are 32 chars long.
  • NEGOCIATION DATA, NEGOCIED DATA, FAILURE CODE are 32 bits long.
  • WEB SERVER INFO, SERVLET ENGINE INFO are CString.
The secret key will be set by a new propertie in workers.properties : secretkey
worker.ajp13.port=8009
worker.ajp13.host=localhost
worker.ajp13.type=ajp13
worker.ajp13.secretkey=myverysecretkey

Shutdown feature

AJP13 miss a functionnality of AJP12, which is shutdown command. A logout will tell servlet engine to shutdown itself.

+--------------+----------------------------+
| SHUTDOWN CMD | MD5 of RANDOM + SECRET KEY |
+--------------+----------------------------+

+------------+
| SHUTOK CMD |
+------------+

+-------------+--------------+
| SHUTNOK CMD | FAILURE CODE |
+-------------+--------------+
  • SHUTDOWN CMD, SHUTOK CMD, SHUTNOK CMD are 1 byte long.
  • MD5 of RANDOM + SECRET KEY are 32 chars long.
  • FAILURE CODE is 32 bits long.

Extended Env Vars feature

NOTA: While working on AJP13 in JK, I really discovered "JkEnvVar". The following "Extended Env Vars feature" description may not be implemented in extended AJP13 since allready available in original implementation. DESC: Many users will want to see some of their web-server env vars passed to their servlet engine. To reduce the network traffic, the web-servlet will send a table to describing the external vars in a shorter fashion. We'll use there a functionnality allready present in AJP13, attributes list : In the AJP13, we've got :

AJP13_FORWARD_REQUEST :=
    prefix_code      2
    method           (byte)
    protocol         (string)
    req_uri          (string)
    remote_addr      (string)
    remote_host      (string)
    server_name      (string)
    server_port      (integer)
    is_ssl           (boolean)
    num_headers      (integer)
    request_headers *(req_header_name req_header_value)

    ?context       (byte string)
    ?servlet_path  (byte string)
    ?remote_user   (byte string)
    ?auth_type     (byte string)
    ?query_string  (byte string)
    ?route         (byte string)
    ?ssl_cert      (byte string)
    ?ssl_cipher    (byte string)
    ?ssl_session   (byte string)

    ?attributes   *(attribute_name attribute_value)
    request_terminator (byte)
Using short 'web server attribute name' will reduce the network traffic.
+-------------------+---------------------------+-------------------------------+----+
| EXTENDED VARS CMD | WEB SERVER ATTRIBUTE NAME | SERVLET ENGINE ATTRIBUTE NAME | ES |
+-------------------+---------------------------+-------------------------------+----+
ie :
JkExtVars S1 SSL_CLIENT_V_START javax.servlet.request.ssl_start_cert_date
JkExtVars S2 SSL_CLIENT_V_END   javax.servlet.request.ssl_end_cert_date
JkExtVars S3 SSL_SESSION_ID     javax.servlet.request.ssl_session_id


+-------------------+----+-------------------------------------------+
| EXTENDED VARS CMD | S1 | javax.servlet.request.ssl_start_cert_date |
+-------------------+----+-------------------------------------------+
+----+-----------------------------------------+
| S2 | javax.servlet.request.ssl_end_cert_date |
+----+-----------------------------------------+
+----+-----------------------------------------+
| S3 | javax.servlet.request.ssl_end_cert_date |
+----+-----------------------------------------+
During transmission in extended AJP13 we'll see attributes name containing S1, S2, S3 and attributes values of 2001/01/03, 2002/01/03, 0123AFE56. This example showed the use of extended SSL vars but any 'personnal' web-server vars like custom authentification vars could be reused in the servlet engine. The cost will be only some more bytes in the AJP traffic.
  • EXTENDED VARS CMD is 1 byte long.
  • WEB SERVER ATTRIBUTE NAME, SERVLET ENGINE ATTRIBUTE NAME are CString.
  • ES is an empty CString.

Context informations forwarding for Servlet engine to Web Server

Just after the LOGON PHASE, the web server will ask for the list of contexts and URLs/URIs handled by the servlet engine. It will ease installation in many sites, reduce questions about configuration on tomcat-user list, and be ready for servlet API 2.3. This mode will be activated by a new directive JkAutoMount ie: JkAutoMount examples myworker1 /examples/ If we want to get ALL the contexts handled by the servlet engine, willcard could be used : ie: JkAutoMount * myworker1 * A servlet engine could have many contexts, /examples, /admin, /test. We may want to use only some contexts for a given worker. It was done previously, in apache HTTP server for example, by setting by hand the JkMount accordingly in each [virtual] area of Apache. If you web-server support virtual hosting, we'll forward also that information to servlet engine which will only return contexts for that virtual host. In that case the servlet engine will only return the URL/URI matching these particular virtual server (defined in server.xml). This feature will help ISP and big sites which mutualize large farm of Tomcat in load-balancing configuration.

+-----------------+-------------------+----------+----------+----+
| CONTEXT QRY CMD | VIRTUAL HOST NAME | CONTEXTA | CONTEXTB | ES |
+-----------------+-------------------+----------+----------+----+

+------------------+-------------------+----------+-------------------+----------+---------------+----+
| CONTEXT INFO CMD | VIRTUAL HOST NAME | CONTEXTA | URL1 URL2 URL3 ES | CONTEXTB | URL1 URL2 ... | ES |
+------------------+-------------------+----------+-------------------+----------+---------------+----+
We'll discover via context-query, the list of URL/MIMES handled by the remove servlet engine for a list of contextes. In wildcard mode, CONTEXTA will contains just '*'.
  • CONTEXT QRY CMD and CONTEXT INFO CMD are 1 byte long.
  • VIRTUAL HOST NAME is a CString, ie an array of chars terminated by a null byte (/0).
  • An empty string is just a null byte (/0).
  • ES is an empty CString. Indicate end of URI/URLs or end of CONTEXTs.
NB:
When VirtualMode is not to be used, the VIRTUAL HOST NAME is '*'. In that case the servlet engine will send all contexts handled.

Context informations updates from Servlet engine to Web Server

Context update are messages caming from the servlet engine each time a context is desactivated/reactivated. The update will be in use when the directive JkUpdateMount. This directive will set the AJP13_CONTEXT_UPDATE_NEG flag. ie: JkUpdateMount myworker1

+--------------------+-------------------+----------+--------+----------+--------+----+
| CONTEXT UPDATE CMD | VIRTUAL HOST NAME | CONTEXTA | STATUS | CONTEXTB | STATUS | ES |
+--------------------+-------------------+----------+--------+----------+--------+----+
  • CONTEXT UPDATE CMD, STATUS are 1 byte long.
  • VIRTUAL HOST NAME, CONTEXTS are CString.
  • ES is an empty CString. Indicate end of CONTEXTs.
NB:
When VirtualMode is not in use, the VIRTUAL HOST NAME is '*'. STATUS is one byte indicating if context is UP/DOWN/INVALID

Context status query to Servlet engine

This query will be used by the web-server to determine if a given contexts are UP, DOWN or INVALID (and should be removed).

+-------------------+--------------------+----------+----------+----+
| CONTEXT STATE CMD |  VIRTUAL HOST NAME | CONTEXTA | CONTEXTB | ES |
+-------------------+--------------------+----------+----------+----+

+-------------------------+-------------------+----------+--------+----------+--------+----+
| CONTEXT STATE REPLY CMD | VIRTUAL HOST NAME | CONTEXTA | STATUS | CONTEXTB | STATUS | ES |
+-------------------------+-------------------+----------+-------------------+--------+----+
  • CONTEXT STATE CMD, CONTEXT STATE REPLY CMD, STATUS are 1 byte long.
  • VIRTUAL HOST NAME, CONTEXTs are CString
  • ES is an empty CString
NB:
When VirtualMode is not in use, the VIRTUAL HOST NAME is an empty string.

Handling of unknown packets

Sometimes even with a well negocied protocol, we may be in a situation where one end (web server or servlet engine), will receive a message it couldn't understand. In that case the receiver will send an 'UNKNOW PACKET CMD' with attached the unhandled message.

+--------------------+------------------------+-------------------+
| UNKNOWN PACKET CMD | UNHANDLED MESSAGE SIZE | UNHANDLED MESSAGE |
+--------------------+------------------------+-------------------+
Depending on the message, the sender will report an error and if possible will try to forward the message to another endpoint.
  • UNKNOWN PACKET CMD is 1 byte long.
  • UNHANDLED MESSAGE SIZE is 16bits long.
  • UNHANDLED MESSAGE is an array of byte (length is contained in UNHANDLED MESSAGE SIZE)
NB:
added UNHANDLED MESSAGE SIZE (development)

Verification of connection before sending request

NOTA: This fonctionality may never be used, since it may slow up the normal process since requiring on the web-server side an extra IO (read) before forwarding the request..... One of the beauty of socket APIs, is that you could write on a half closed socket. When servlet engine close the socket, the web server will discover it only at the next read() to the socket. Basically, in the AJP13 protocol, the web server send the HTTP HEADER and HTTP BODY (POST by chunk of 8K) to the servlet engine and then try to receive the reply. If the connection was broken the web server will learn it only at receive time. We could use a buffering scheme but what happen when you use the servlet engine for upload operations with more than 8ko of datas ? The hack in the AJP13 protocol is to add some bytes to read after the end of the service :

EXAMPLE OF DISCUSSION BETWEEN WEB SERVER AND SERVLET ENGINE

AJP HTTP-HEADER (+ HTTP-POST)   (WEB->SERVLET)

AJP HTTP-REPLY					(SERVLET->WEB)

AJP END OF DISCUSSION			(SERVLET->WEB)
						
---> AJP STATUS 				(SERVLET->WEB AJP13)
The AJP STATUS will not be read by the servlet engine at the end of the request/response #N but at the begining of the next session. More at that time the web server could also use OS dependants functions (or better APR functions) to determine if there is also more data to read. And that datas could be CONTEXT Updates. This will avoid the web server sending a request to a desactivated context. In that case, if the load-balancing is used, it will search for another servlet engine to handle the request. And that feature will help ISP and big sites with farm of tomcat, to updates their servlet engine without any service interruption.
+------------+-------------+
| STATUS CMD | STATUS DATA |
+------------+-------------+
  • STATUS CMD and STATUS DATA are one byte long.

Conclusion

The goal of the extended AJP13 protocol is to overcome some of the original AJP13 limitation. An easier configuration, a better support for large site and farm of Tomcat, a simple authentification system and provision for protocol updates. Using the stable ajp13 implementation in JK (native) and in servlet engine (java), it's a reasonable evolution of the well known ajp13.

Commands and IDs in extended AJP13 Index

Index of Commands and ID to be added in AJP13 Protocol

Commands IDs

Command NameCommand Number
AJP13_LOGINIT_CMD0x10
AJP13_LOGSEED_CMD0x11
AJP13_LOGCOMP_CMD0x12
AJP13_LOGOK_CMD0x13
AJP13_LOGNOK_CMD0x14
AJP13_CONTEXT_QRY_CMD0x15
AJP13_CONTEXT_INFO_CMD0x16
AJP13_CONTEXT_UPDATE_CMD0x17
AJP13_STATUS_CMD0x18
AJP13_SHUTDOWN_CMD0x19
AJP13_SHUTOK_CMD0x1A
AJP13_SHUTNOK_CMD0x1B
AJP13_CONTEXT_STATE_CMD0x1C
AJP13_CONTEXT_STATE_REP_CMD0x1D
AJP13_UNKNOW_PACKET_CMD0x1E

Negociations Flags

Command NameNumberDescription
AJP13_CONTEXT_INFO_NEG0x80000000web-server want context info after login
AJP13_CONTEXT_UPDATE_NEG0x40000000web-server want context updates
AJP13_GZIP_STREAM_NEG0x20000000web-server want compressed stream
AJP13_DES56_STREAM_NEG0x10000000web-server want crypted DES56 stream with secret key
AJP13_SSL_VSERVER_NEG0x08000000Extended info on server SSL vars
AJP13_SSL_VCLIENT_NEG0x04000000Extended info on client SSL vars
AJP13_SSL_VCRYPTO_NEG0x02000000Extended info on crypto SSL vars
AJP13_SSL_VMISC_NEG0x01000000Extended info on misc SSL vars

Negociation IDNumberDescription
AJP13_PROTO_SUPPORT_AJPXX_NEG0x00FF0000mask of protocol supported
AJP13_PROTO_SUPPORT_AJP13L1_NEG0x00010000communication could use AJP13 Level 1
AJP13_PROTO_SUPPORT_AJP13L2_NEG0x00020000communication could use AJP13 Level 2
AJP13_PROTO_SUPPORT_AJP13L3_NEG0x00040000communication could use AJP13 Level 3

All others flags must be set to 0 since they are reserved for future use.

Failure IDs

Failure IdNumber
AJP13_BAD_KEY_ERR0xFFFFFFFF
AJP13_ENGINE_DOWN_ERR0xFFFFFFFE
AJP13_RETRY_LATER_ERR0xFFFFFFFD
AJP13_SHUT_AUTHOR_FAILED_ERR0xFFFFFFFC

Status

Failure IdNumber
AJP13_CONTEXT_DOWN0x01
AJP13_CONTEXT_UP0x02
AJP13_CONTEXT_OK0x03


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/ajp/printer/0000755000000000000020000000000012555256556017520 5ustar rootbintomcat-connectors-1.2.41-src/docs/ajp/printer/ajpv13ext.html0000644000000000000020000006421312555256556022241 0ustar rootbinThe Apache Tomcat Connectors - AJP Protocol Reference - AJPv13 extensions Proposal
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - AJP Protocol Reference

AJPv13 extensions Proposal

Introduction

This document is a proposal of evolution of the current Apache JServ Protocol version 1.3, also known as ajp13. I'll not cover here the full protocol but only the add-on from ajp13. This nth pass include comments from the tomcat-dev list and misses discovered during developpment.

Missing features in AJP13

ajp13 is a good protocol to link a servlet engine like tomcat to a web server like Apache:

  • use persistants connections to avoid reconnect time at each request
  • encode many http commands to reduce stream size
  • send to servlet engine many info from web server (like SSL certs)

But ajp13 lacks support for :

  • security between web server and servlet engine. Anybody can connect to an ajp13 port (no login mecanism used) You could connect, for example with telnet, and keep the remote thread up by not sending any data (no timeout in connection)
  • context information passed from servlet engine to web server. Part of the configuration of JK, the web server connector, is to indicate to the web server which URI to handle. The mod_jk JkMount directive, told to web server which URI must be forwarded to servlet engine. A servlet engine allready knows which URI it handle and TC 3.3 is allready capable to generate a config file for JK from the list of available contexts.
  • state update of contexts from servlet engine to web server. Big site with farm of Tomcat, like ISP and virtuals hosters, may need to stop a context for admin purposes. In that case the front web server must know that the context is currently down, to eventually relay the request to another Tomcat
  • verify state of connection before sending request. Actually JK send the request to the servlet engine and next wait for the answer. But one of the beauty of the socket API, is you that you could write() to a closed connection without any error reporting, but a read() to a closed connection return you the error code.

Proposed add-ons to AJP13

Let's descrive here the features and add-on that could be added to AJP13. Since this document is a proposal, a reasonable level of chaos must be expected at first. Be sure that discussion on tomcat list will help clarify points, add features but the current list seems to be a 'minimun vital'

  • Advanced login features at connect time
  • Basic authorisation system, where a shared secret key is present in web server and servlet engine.
  • Basic protocol negociation, just to be sure that if functionnalities are added to AJP13 in the future, current implementations will still works.
  • Clean handling of 'Unknown packets'
  • Extended env vars passed from web-server to servlet engine.
  • Add extra SSL informations needed by Servlet 2.3 API (like SSL_KEY_SIZE)

Advanced login

  1. WEB-SERVER send LOGIN INIT CMD + NEGOCIATION DATA + WEB SERVER INFO
  2. TOMCAT respond with LOGIN SEED CMD + RANDOM DATA
  3. WEB-SERVER calculted the MD5 of RANDOM DATA+SECRET DATA
  4. WEB-SERVER send LOGIN COMP CMD + MD5 (SECRET DATA + RANDOM DATA)
  5. TOMCAT respond with LOGIN STATUS CMD + NEGOCIED DATA + SERVLET ENGINE INFO
To prevent DOS attack, the servlet engine will wait the LOGIN CMD only 15/30 seconds and reports the timeout exception for admins investigation. The login command will contains basic protocol negociation information like compressing ability, crypto, context info (at start up), context update at run-time (up/down), level of SSL env vars, AJP protocol level supported (level1/level2/level3...) The Web server info will contain web server info and connector name (ie Apache 1.3.26 + mod_ssl 2.8.8 + mod_jk 1.2.41 + mod_perl 1.25). The servlet engine will mask the negociation mask with it's own mask (what it can do) and return it when loggin is accepted. This will help having a basic AJP13 implementation (level 1) on a web-server working with a more advanced protocol handler on the servlet engine side or vice-versa. AJP13 was designed to be small and fast and so many SSL informations present in the web-server are not forwarded to the servlet engine. We add here four negociations flags to provide more informations on client SSL data (certs), server SSL datas, crypto used, and misc datas (timeout...).

Messages Stream

+----------------+------------------+-----------------+
| LOGIN INIT CMD | NEGOCIATION DATA | WEB SERVER INFO |
+----------------+------------------+-----------------+

+----------------+----------------+
| LOGIN SEED CMD | MD5 of entropy |
+----------------+----------------+

+----------------+----------------------------+
| LOGIN COMP CMD | MD5 of RANDOM + SECRET KEY |
+----------------+----------------------------+

+-----------+---------------+---------------------+
| LOGOK CMD | NEGOCIED DATA | SERVLET ENGINE INFO |
+-----------+---------------+---------------------+

+------------+--------------+
| LOGNOK CMD | FAILURE CODE |
+------------+--------------+
  • LOGIN INIT CMD, LOGIN SEED CMD, LOGIN COMP CMD, LOGOK CMD, LOGNOK CMD are 1 byte long.
  • MD5, MD5 of RANDOM + SECRET KEY are 32 chars long.
  • NEGOCIATION DATA, NEGOCIED DATA, FAILURE CODE are 32 bits long.
  • WEB SERVER INFO, SERVLET ENGINE INFO are CString.
The secret key will be set by a new propertie in workers.properties : secretkey
worker.ajp13.port=8009
worker.ajp13.host=localhost
worker.ajp13.type=ajp13
worker.ajp13.secretkey=myverysecretkey

Shutdown feature

AJP13 miss a functionnality of AJP12, which is shutdown command. A logout will tell servlet engine to shutdown itself.

+--------------+----------------------------+
| SHUTDOWN CMD | MD5 of RANDOM + SECRET KEY |
+--------------+----------------------------+

+------------+
| SHUTOK CMD |
+------------+

+-------------+--------------+
| SHUTNOK CMD | FAILURE CODE |
+-------------+--------------+
  • SHUTDOWN CMD, SHUTOK CMD, SHUTNOK CMD are 1 byte long.
  • MD5 of RANDOM + SECRET KEY are 32 chars long.
  • FAILURE CODE is 32 bits long.

Extended Env Vars feature

NOTA: While working on AJP13 in JK, I really discovered "JkEnvVar". The following "Extended Env Vars feature" description may not be implemented in extended AJP13 since allready available in original implementation. DESC: Many users will want to see some of their web-server env vars passed to their servlet engine. To reduce the network traffic, the web-servlet will send a table to describing the external vars in a shorter fashion. We'll use there a functionnality allready present in AJP13, attributes list : In the AJP13, we've got :

AJP13_FORWARD_REQUEST :=
    prefix_code      2
    method           (byte)
    protocol         (string)
    req_uri          (string)
    remote_addr      (string)
    remote_host      (string)
    server_name      (string)
    server_port      (integer)
    is_ssl           (boolean)
    num_headers      (integer)
    request_headers *(req_header_name req_header_value)

    ?context       (byte string)
    ?servlet_path  (byte string)
    ?remote_user   (byte string)
    ?auth_type     (byte string)
    ?query_string  (byte string)
    ?route         (byte string)
    ?ssl_cert      (byte string)
    ?ssl_cipher    (byte string)
    ?ssl_session   (byte string)

    ?attributes   *(attribute_name attribute_value)
    request_terminator (byte)
Using short 'web server attribute name' will reduce the network traffic.
+-------------------+---------------------------+-------------------------------+----+
| EXTENDED VARS CMD | WEB SERVER ATTRIBUTE NAME | SERVLET ENGINE ATTRIBUTE NAME | ES |
+-------------------+---------------------------+-------------------------------+----+
ie :
JkExtVars S1 SSL_CLIENT_V_START javax.servlet.request.ssl_start_cert_date
JkExtVars S2 SSL_CLIENT_V_END   javax.servlet.request.ssl_end_cert_date
JkExtVars S3 SSL_SESSION_ID     javax.servlet.request.ssl_session_id


+-------------------+----+-------------------------------------------+
| EXTENDED VARS CMD | S1 | javax.servlet.request.ssl_start_cert_date |
+-------------------+----+-------------------------------------------+
+----+-----------------------------------------+
| S2 | javax.servlet.request.ssl_end_cert_date |
+----+-----------------------------------------+
+----+-----------------------------------------+
| S3 | javax.servlet.request.ssl_end_cert_date |
+----+-----------------------------------------+
During transmission in extended AJP13 we'll see attributes name containing S1, S2, S3 and attributes values of 2001/01/03, 2002/01/03, 0123AFE56. This example showed the use of extended SSL vars but any 'personnal' web-server vars like custom authentification vars could be reused in the servlet engine. The cost will be only some more bytes in the AJP traffic.
  • EXTENDED VARS CMD is 1 byte long.
  • WEB SERVER ATTRIBUTE NAME, SERVLET ENGINE ATTRIBUTE NAME are CString.
  • ES is an empty CString.

Context informations forwarding for Servlet engine to Web Server

Just after the LOGON PHASE, the web server will ask for the list of contexts and URLs/URIs handled by the servlet engine. It will ease installation in many sites, reduce questions about configuration on tomcat-user list, and be ready for servlet API 2.3. This mode will be activated by a new directive JkAutoMount ie: JkAutoMount examples myworker1 /examples/ If we want to get ALL the contexts handled by the servlet engine, willcard could be used : ie: JkAutoMount * myworker1 * A servlet engine could have many contexts, /examples, /admin, /test. We may want to use only some contexts for a given worker. It was done previously, in apache HTTP server for example, by setting by hand the JkMount accordingly in each [virtual] area of Apache. If you web-server support virtual hosting, we'll forward also that information to servlet engine which will only return contexts for that virtual host. In that case the servlet engine will only return the URL/URI matching these particular virtual server (defined in server.xml). This feature will help ISP and big sites which mutualize large farm of Tomcat in load-balancing configuration.

+-----------------+-------------------+----------+----------+----+
| CONTEXT QRY CMD | VIRTUAL HOST NAME | CONTEXTA | CONTEXTB | ES |
+-----------------+-------------------+----------+----------+----+

+------------------+-------------------+----------+-------------------+----------+---------------+----+
| CONTEXT INFO CMD | VIRTUAL HOST NAME | CONTEXTA | URL1 URL2 URL3 ES | CONTEXTB | URL1 URL2 ... | ES |
+------------------+-------------------+----------+-------------------+----------+---------------+----+
We'll discover via context-query, the list of URL/MIMES handled by the remove servlet engine for a list of contextes. In wildcard mode, CONTEXTA will contains just '*'.
  • CONTEXT QRY CMD and CONTEXT INFO CMD are 1 byte long.
  • VIRTUAL HOST NAME is a CString, ie an array of chars terminated by a null byte (/0).
  • An empty string is just a null byte (/0).
  • ES is an empty CString. Indicate end of URI/URLs or end of CONTEXTs.
NB:
When VirtualMode is not to be used, the VIRTUAL HOST NAME is '*'. In that case the servlet engine will send all contexts handled.

Context informations updates from Servlet engine to Web Server

Context update are messages caming from the servlet engine each time a context is desactivated/reactivated. The update will be in use when the directive JkUpdateMount. This directive will set the AJP13_CONTEXT_UPDATE_NEG flag. ie: JkUpdateMount myworker1

+--------------------+-------------------+----------+--------+----------+--------+----+
| CONTEXT UPDATE CMD | VIRTUAL HOST NAME | CONTEXTA | STATUS | CONTEXTB | STATUS | ES |
+--------------------+-------------------+----------+--------+----------+--------+----+
  • CONTEXT UPDATE CMD, STATUS are 1 byte long.
  • VIRTUAL HOST NAME, CONTEXTS are CString.
  • ES is an empty CString. Indicate end of CONTEXTs.
NB:
When VirtualMode is not in use, the VIRTUAL HOST NAME is '*'. STATUS is one byte indicating if context is UP/DOWN/INVALID

Context status query to Servlet engine

This query will be used by the web-server to determine if a given contexts are UP, DOWN or INVALID (and should be removed).

+-------------------+--------------------+----------+----------+----+
| CONTEXT STATE CMD |  VIRTUAL HOST NAME | CONTEXTA | CONTEXTB | ES |
+-------------------+--------------------+----------+----------+----+

+-------------------------+-------------------+----------+--------+----------+--------+----+
| CONTEXT STATE REPLY CMD | VIRTUAL HOST NAME | CONTEXTA | STATUS | CONTEXTB | STATUS | ES |
+-------------------------+-------------------+----------+-------------------+--------+----+
  • CONTEXT STATE CMD, CONTEXT STATE REPLY CMD, STATUS are 1 byte long.
  • VIRTUAL HOST NAME, CONTEXTs are CString
  • ES is an empty CString
NB:
When VirtualMode is not in use, the VIRTUAL HOST NAME is an empty string.

Handling of unknown packets

Sometimes even with a well negocied protocol, we may be in a situation where one end (web server or servlet engine), will receive a message it couldn't understand. In that case the receiver will send an 'UNKNOW PACKET CMD' with attached the unhandled message.

+--------------------+------------------------+-------------------+
| UNKNOWN PACKET CMD | UNHANDLED MESSAGE SIZE | UNHANDLED MESSAGE |
+--------------------+------------------------+-------------------+
Depending on the message, the sender will report an error and if possible will try to forward the message to another endpoint.
  • UNKNOWN PACKET CMD is 1 byte long.
  • UNHANDLED MESSAGE SIZE is 16bits long.
  • UNHANDLED MESSAGE is an array of byte (length is contained in UNHANDLED MESSAGE SIZE)
NB:
added UNHANDLED MESSAGE SIZE (development)

Verification of connection before sending request

NOTA: This fonctionality may never be used, since it may slow up the normal process since requiring on the web-server side an extra IO (read) before forwarding the request..... One of the beauty of socket APIs, is that you could write on a half closed socket. When servlet engine close the socket, the web server will discover it only at the next read() to the socket. Basically, in the AJP13 protocol, the web server send the HTTP HEADER and HTTP BODY (POST by chunk of 8K) to the servlet engine and then try to receive the reply. If the connection was broken the web server will learn it only at receive time. We could use a buffering scheme but what happen when you use the servlet engine for upload operations with more than 8ko of datas ? The hack in the AJP13 protocol is to add some bytes to read after the end of the service :

EXAMPLE OF DISCUSSION BETWEEN WEB SERVER AND SERVLET ENGINE

AJP HTTP-HEADER (+ HTTP-POST)   (WEB->SERVLET)

AJP HTTP-REPLY					(SERVLET->WEB)

AJP END OF DISCUSSION			(SERVLET->WEB)
						
---> AJP STATUS 				(SERVLET->WEB AJP13)
The AJP STATUS will not be read by the servlet engine at the end of the request/response #N but at the begining of the next session. More at that time the web server could also use OS dependants functions (or better APR functions) to determine if there is also more data to read. And that datas could be CONTEXT Updates. This will avoid the web server sending a request to a desactivated context. In that case, if the load-balancing is used, it will search for another servlet engine to handle the request. And that feature will help ISP and big sites with farm of tomcat, to updates their servlet engine without any service interruption.
+------------+-------------+
| STATUS CMD | STATUS DATA |
+------------+-------------+
  • STATUS CMD and STATUS DATA are one byte long.

Conclusion

The goal of the extended AJP13 protocol is to overcome some of the original AJP13 limitation. An easier configuration, a better support for large site and farm of Tomcat, a simple authentification system and provision for protocol updates. Using the stable ajp13 implementation in JK (native) and in servlet engine (java), it's a reasonable evolution of the well known ajp13.

Commands and IDs in extended AJP13 Index

Index of Commands and ID to be added in AJP13 Protocol

Commands IDs

Command NameCommand Number
AJP13_LOGINIT_CMD0x10
AJP13_LOGSEED_CMD0x11
AJP13_LOGCOMP_CMD0x12
AJP13_LOGOK_CMD0x13
AJP13_LOGNOK_CMD0x14
AJP13_CONTEXT_QRY_CMD0x15
AJP13_CONTEXT_INFO_CMD0x16
AJP13_CONTEXT_UPDATE_CMD0x17
AJP13_STATUS_CMD0x18
AJP13_SHUTDOWN_CMD0x19
AJP13_SHUTOK_CMD0x1A
AJP13_SHUTNOK_CMD0x1B
AJP13_CONTEXT_STATE_CMD0x1C
AJP13_CONTEXT_STATE_REP_CMD0x1D
AJP13_UNKNOW_PACKET_CMD0x1E

Negociations Flags

Command NameNumberDescription
AJP13_CONTEXT_INFO_NEG0x80000000web-server want context info after login
AJP13_CONTEXT_UPDATE_NEG0x40000000web-server want context updates
AJP13_GZIP_STREAM_NEG0x20000000web-server want compressed stream
AJP13_DES56_STREAM_NEG0x10000000web-server want crypted DES56 stream with secret key
AJP13_SSL_VSERVER_NEG0x08000000Extended info on server SSL vars
AJP13_SSL_VCLIENT_NEG0x04000000Extended info on client SSL vars
AJP13_SSL_VCRYPTO_NEG0x02000000Extended info on crypto SSL vars
AJP13_SSL_VMISC_NEG0x01000000Extended info on misc SSL vars

Negociation IDNumberDescription
AJP13_PROTO_SUPPORT_AJPXX_NEG0x00FF0000mask of protocol supported
AJP13_PROTO_SUPPORT_AJP13L1_NEG0x00010000communication could use AJP13 Level 1
AJP13_PROTO_SUPPORT_AJP13L2_NEG0x00020000communication could use AJP13 Level 2
AJP13_PROTO_SUPPORT_AJP13L3_NEG0x00040000communication could use AJP13 Level 3

All others flags must be set to 0 since they are reserved for future use.

Failure IDs

Failure IdNumber
AJP13_BAD_KEY_ERR0xFFFFFFFF
AJP13_ENGINE_DOWN_ERR0xFFFFFFFE
AJP13_RETRY_LATER_ERR0xFFFFFFFD
AJP13_SHUT_AUTHOR_FAILED_ERR0xFFFFFFFC

Status

Failure IdNumber
AJP13_CONTEXT_DOWN0x01
AJP13_CONTEXT_UP0x02
AJP13_CONTEXT_OK0x03


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/ajp/printer/ajpv13a.html0000644000000000000020000007060312555256556021661 0ustar rootbinThe Apache Tomcat Connectors - AJP Protocol Reference - AJPv13
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - AJP Protocol Reference

AJPv13

Intro

The original document was written by Dan Milstein, danmil@shore.net on December 2000. The present document is generated out of an xml file to allow a more easy integration in the Tomcat documentation.

This describes the Apache JServ Protocol version 1.3 (hereafter ajp13). There is, apparently, no current documentation of how the protocol works. This document is an attempt to remedy that, in order to make life easier for maintainers of JK, and for anyone who wants to port the protocol somewhere (into jakarta 4.x, for example).

author

I am not one of the designers of this protocol -- I believe that Gal Shachor was the original designer. Everything in this document is derived from the actual implementation I found in the tomcat 3.x code. I hope it is useful, but I can't make any grand claims to perfect accuracy. I also don't know why certain design decisions were made. Where I was able, I've offered some possible justifications for certain choices, but those are only my guesses. In general, the C code which Shachor wrote is very clean and comprehensible (if almost totally undocumented). I've cleaned up the Java code, and I think it's reasonably readable.

Design Goals

According to email from Gal Shachor to the jakarta-dev mailing list, the original goals of JK (and thus ajp13) were to extend mod_jserv and ajp12 by (I am only including the goals which relate to communication between the web server and the servlet container):

  • Increasing performance (speed, specifically).
  • Adding support for SSL, so that isSecure() and getScheme() will function correctly within the servlet container. The client certificates and cipher suite will be available to servlets as request attributes.

Overview of the protocol

The ajp13 protocol is packet-oriented. A binary format was presumably chosen over the more readable plain text for reasons of performance. The web server communicates with the servlet container over TCP connections. To cut down on the expensive process of socket creation, the web server will attempt to maintain persistent TCP connections to the servlet container, and to reuse a connection for multiple request/response cycles.

Once a connection is assigned to a particular request, it will not be used for any others until the request-handling cycle has terminated. In other words, requests are not multiplexed over connections. This makes for much simpler code at either end of the connection, although it does cause more connections to be open at once.

Once the web server has opened a connection to the servlet container, the connection can be in one of the following states:

  • Idle
    No request is being handled over this connection.
  • Assigned
    The connecton is handling a specific request.

Once a connection is assigned to handle a particular request, the basic request informaton (e.g. HTTP headers, etc) is sent over the connection in a highly condensed form (e.g. common strings are encoded as integers). Details of that format are below in Request Packet Structure. If there is a body to the request (content-length > 0), that is sent in a separate packet immediately after.

At this point, the servlet container is presumably ready to start processing the request. As it does so, it can send the following messages back to the web server:

  • SEND_HEADERS
    Send a set of headers back to the browser.
  • SEND_BODY_CHUNK
    Send a chunk of body data back to the browser.
  • GET_BODY_CHUNK
    Get further data from the request if it hasn't all been transferred yet. This is necessary because the packets have a fixed maximum size and arbitrary amounts of data can be included the body of a request (for uploaded files, for example). (Note: this is unrelated to HTTP chunked tranfer).
  • END_RESPONSE
    Finish the request-handling cycle.

Each message is accompanied by a differently formatted packet of data. See Response Packet Structures below for details.

Basic Packet Structure

There is a bit of an XDR heritage to this protocol, but it differs in lots of ways (no 4 byte alignment, for example).

AJP13 uses network byte order for all data types.

There are four data types in the protocol: bytes, booleans, integers and strings.

Byte
A single byte.
Boolean
A single byte, 1 = true, 0 = false. Using other non-zero values as true (i.e. C-style) may work in some places, but it won't in others.
Integer
A number in the range of 0 to 2^16 (32768). Stored in 2 bytes with the high-order byte first.
String
A variable-sized string (length bounded by 2^16). Encoded with the length packed into two bytes first, followed by the string (including the terminating '\0'). Note that the encoded length does not include the trailing '\0' -- it is like strlen. This is a touch confusing on the Java side, which is littered with odd autoincrement statements to skip over these terminators. I believe the reason this was done was to allow the C code to be extra efficient when reading strings which the servlet container is sending back -- with the terminating \0 character, the C code can pass around references into a single buffer, without copying. If the \0 was missing, the C code would have to copy things out in order to get its notion of a string. Note a size of -1 (65535) indicates a null string and no data follow the length in this case.

Packet Size

According to much of the code, the max packet size is 8 * 1024 bytes (8K). The actual length of the packet is encoded in the header.

Packet Headers

Packets sent from the server to the container begin with 0x1234. Packets sent from the container to the server begin with AB (that's the ASCII code for A followed by the ASCII code for B). After those first two bytes, there is an integer (encoded as above) with the length of the payload. Although this might suggest that the maximum payload could be as large as 2^16, in fact, the code sets the maximum to be 8K.
Packet Format (Server->Container)
Byte 0 1 2 3 4...(n+3)
Contents 0x12 0x34 Data Length (n) Data
Packet Format (Container->Server)
Byte 0 1 2 3 4...(n+3)
Contents A B Data Length (n) Data

For most packets, the first byte of the payload encodes the type of message. The exception is for request body packets sent from the server to the container -- they are sent with a standard packet header (0x1234 and then length of the packet), but without any prefix code after that (this seems like a mistake to me).

The web server can send the following messages to the servlet container:
Code Type of Packet Meaning
2 Forward Request Begin the request-processing cycle with the following data
7 Shutdown The web server asks the container to shut itself down.
8 Ping The web server asks the container to take control (secure login phase).
10 CPing The web server asks the container to respond quickly with a CPong.
none Data Size (2 bytes) and corresponding body data.

To ensure some basic security, the container will only actually do the Shutdown if the request comes from the same machine on which it's hosted.

The first Data packet is send immediatly after the Forward Request by the web server.

The servlet container can send the following types of messages to the web server:
Code Type of Packet Meaning
3 Send Body Chunk Send a chunk of the body from the servlet container to the web server (and presumably, onto the browser).
4 Send Headers Send the response headers from the servlet container to the web server (and presumably, onto the browser).
5 End Response Marks the end of the response (and thus the request-handling cycle).
6 Get Body Chunk Get further data from the request if it hasn't all been transferred yet.
9 CPong Reply The reply to a CPing request

Each of the above messages has a different internal structure, detailed below.

Request Packet Structure

For messages from the server to the container of type "Forward Request":

AJP13_FORWARD_REQUEST :=
    prefix_code      (byte) 0x02 = JK_AJP13_FORWARD_REQUEST
    method           (byte)
    protocol         (string)
    req_uri          (string)
    remote_addr      (string)
    remote_host      (string)
    server_name      (string)
    server_port      (integer)
    is_ssl           (boolean)
    num_headers      (integer)
    request_headers *(req_header_name req_header_value)
    attributes      *(attribut_name attribute_value)
    request_terminator (byte) OxFF

The request_headers have the following structure:

req_header_name := 
    sc_req_header_name | (string)  [see below for how this is parsed]

sc_req_header_name := 0xA0xx (integer)

req_header_value := (string)

The attributes are optional and have the following structure:

attribute_name := sc_a_name | (sc_a_req_attribute string)

attribute_value := (string)

Not that the all-important header is "content-length', because it determines whether or not the container looks for another packet immediately.

Detailed description of the elements of Forward Request.

request_prefix

For all requests, this will be 2. See above for details on other prefix codes.

method

The HTTP method, encoded as a single byte:

Command NameCode
OPTIONS1
GET2
HEAD3
POST4
PUT5
DELETE6
TRACE7
PROPFIND8
PROPPATCH9
MKCOL10
COPY11
MOVE12
LOCK13
UNLOCK14
ACL15
REPORT16
VERSION-CONTROL17
CHECKIN18
CHECKOUT19
UNCHECKOUT20
SEARCH21
MKWORKSPACE22
UPDATE23
LABEL24
MERGE25
BASELINE_CONTROL26
MKACTIVITY27

Later version of ajp13, when used with mod_jk2, will transport additional methods, even if they are not in this list.

protocol, req_uri, remote_addr, remote_host, server_name, server_port, is_ssl

These are all fairly self-explanatory. Each of these is required, and will be sent for every request.

Headers

The structure of request_headers is the following: First, the number of headers num_headers is encoded. Then, a series of header name req_header_name / value req_header_value pairs follows. Common header names are encoded as integers, to save space. If the header name is not in the list of basic headers, it is encoded normally (as a string, with prefixed length). The list of common headers sc_req_header_nameand their codes is as follows (all are case-sensitive):

NameCode valueCode name
accept0xA001SC_REQ_ACCEPT
accept-charset0xA002SC_REQ_ACCEPT_CHARSET
accept-encoding0xA003SC_REQ_ACCEPT_ENCODING
accept-language0xA004SC_REQ_ACCEPT_LANGUAGE
authorization0xA005SC_REQ_AUTHORIZATION
connection0xA006SC_REQ_CONNECTION
content-type0xA007SC_REQ_CONTENT_TYPE
content-length0xA008SC_REQ_CONTENT_LENGTH
cookie0xA009SC_REQ_COOKIE
cookie20xA00ASC_REQ_COOKIE2
host0xA00BSC_REQ_HOST
pragma0xA00CSC_REQ_PRAGMA
referer0xA00DSC_REQ_REFERER
user-agent0xA00ESC_REQ_USER_AGENT

The Java code that reads this grabs the first two-byte integer and if it sees an '0xA0' in the most significant byte, it uses the integer in the second byte as an index into an array of header names. If the first byte is not '0xA0', it assumes that the two-byte integer is the length of a string, which is then read in.

This works on the assumption that no header names will have length greater than 0x9FFF (==0xA000 - 1), which is perfectly reasonable, though somewhat arbitrary. (If you, like me, started to think about the cookie spec here, and about how long headers can get, fear not -- this limit is on header names not header values. It seems unlikely that unmanageably huge header names will be showing up in the HTTP spec any time soon).

Note: The content-length header is extremely important. If it is present and non-zero, the container assumes that the request has a body (a POST request, for example), and immediately reads a separate packet off the input stream to get that body.

Attributes

The attributes prefixed with a ? (e.g. ?context) are all optional. For each, there is a single byte code to indicate the type of attribute, and then a string to give its value. They can be sent in any order (though the C code always sends them in the order listed below). A special terminating code is sent to signal the end of the list of optional attributes. The list of byte codes is:

InformationCode ValueNote
?context0x01Not currently implemented
?servlet_path0x02Not currently implemented
?remote_user0x03
?auth_type0x04
?query_string0x05
?route0x06
?ssl_cert0x07
?ssl_cipher0x08
?ssl_session0x09
?req_attribute0x0AName (the name of the attribut follows)
?ssl_key_size0x0B
?secret0x0C
?stored_method0x0D
are_done0xFFrequest_terminator

The context and servlet_path are not currently set by the C code, and most of the Java code completely ignores whatever is sent over for those fields (and some of it will actually break if a string is sent along after one of those codes). I don't know if this is a bug or an unimplemented feature or just vestigial code, but it's missing from both sides of the connection.

The remote_user and auth_type presumably refer to HTTP-level authentication, and communicate the remote user's username and the type of authentication used to establish their identity (e.g. Basic, Digest). I'm not clear on why the password isn't also sent, but I don't know HTTP authentication inside and out.

The query_string, ssl_cert, ssl_cipher, and ssl_session refer to the corresponding pieces of HTTP and HTTPS.

The route, as I understand it, is used to support sticky sessions -- associating a user's session with a particular Tomcat instance in the presence of multiple, load-balancing servers. I don't know the details.

Beyond this list of basic attributes, any number of other attributes can be sent via the req_attribute code (0x0A). A pair of strings to represent the attribute name and value are sent immediately after each instance of that code. Environment values are passed in via this method.

Finally, after all the attributes have been sent, the attribute terminator, 0xFF, is sent. This signals both the end of the list of attributes and also then end of the Request Packet.

Response Packet Structure

For messages which the container can send back to the server.

AJP13_SEND_BODY_CHUNK := 
  prefix_code   3
  chunk_length  (integer)
  chunk        *(byte)


AJP13_SEND_HEADERS :=
  prefix_code       4
  http_status_code  (integer)
  http_status_msg   (string)
  num_headers       (integer)
  response_headers *(res_header_name header_value)

res_header_name := 
    sc_res_header_name | (string)   [see below for how this is parsed]

sc_res_header_name := 0xA0 (byte)

header_value := (string)

AJP13_END_RESPONSE :=
  prefix_code       5
  reuse             (boolean)


AJP13_GET_BODY_CHUNK :=
  prefix_code       6
  requested_length  (integer)

Details:

Send Body Chunk

The chunk is basically binary data, and is sent directly back to the browser.

Send Headers

The status code and message are the usual HTTP things (e.g. "200" and "OK"). The response header names are encoded the same way the request header names are. See above for details about how the the codes are distinguished from the strings. The codes for common headers are:

NameCode value
Content-Type0xA001
Content-Language0xA002
Content-Length0xA003
Date0xA004
Last-Modified0xA005
Location0xA006
Set-Cookie0xA007
Set-Cookie20xA008
Servlet-Engine0xA009
Status0xA00A
WWW-Authenticate0xA00B

After the code or the string header name, the header value is immediately encoded.

End Response

Signals the end of this request-handling cycle. If the reuse flag is true (anything other than 0 in the actual C code), this TCP connection can now be used to handle new incoming requests. If reuse is false (==0), the connection should be closed.

Get Body Chunk

The container asks for more data from the request (If the body was too large to fit in the first packet sent over or when the request is chuncked). The server will send a body packet back with an amount of data which is the minimum of the request_length, the maximum send body size (8186 (8 Kbytes - 6)), and the number of bytes actually left to send from the request body.
If there is no more data in the body (i.e. the servlet container is trying to read past the end of the body), the server will send back an "empty" packet, which is a body packet with a payload length of 0. (0x12,0x34,0x00,0x00)

Questions I Have

What happens if the request headers > max packet size? There is no provision to send a second packet of request headers in case there are more than 8K (I think this is correctly handled for response headers, though I'm not certain). I don't know if there is a way to get more than 8K worth of data into that initial set of request headers, but I'll bet there is (combine long cookies with long ssl information and a lot of environment variables, and you should hit 8K easily). I think the connector would just fail before trying to send any headers in this case, but I'm not certain.

What about authentication? There doesn't seem to be any authentication of the connection between the web server and the container. This strikes me as potentially dangerous.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/ajp/ajpv13a.html0000644000000000000020000007705012555256556020201 0ustar rootbinThe Apache Tomcat Connectors - AJP Protocol Reference - AJPv13
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - AJP Protocol Reference

AJPv13

Printer Friendly Version
print-friendly
version
Intro

The original document was written by Dan Milstein, danmil@shore.net on December 2000. The present document is generated out of an xml file to allow a more easy integration in the Tomcat documentation.

This describes the Apache JServ Protocol version 1.3 (hereafter ajp13). There is, apparently, no current documentation of how the protocol works. This document is an attempt to remedy that, in order to make life easier for maintainers of JK, and for anyone who wants to port the protocol somewhere (into jakarta 4.x, for example).

author

I am not one of the designers of this protocol -- I believe that Gal Shachor was the original designer. Everything in this document is derived from the actual implementation I found in the tomcat 3.x code. I hope it is useful, but I can't make any grand claims to perfect accuracy. I also don't know why certain design decisions were made. Where I was able, I've offered some possible justifications for certain choices, but those are only my guesses. In general, the C code which Shachor wrote is very clean and comprehensible (if almost totally undocumented). I've cleaned up the Java code, and I think it's reasonably readable.

Design Goals

According to email from Gal Shachor to the jakarta-dev mailing list, the original goals of JK (and thus ajp13) were to extend mod_jserv and ajp12 by (I am only including the goals which relate to communication between the web server and the servlet container):

  • Increasing performance (speed, specifically).
  • Adding support for SSL, so that isSecure() and getScheme() will function correctly within the servlet container. The client certificates and cipher suite will be available to servlets as request attributes.

Overview of the protocol

The ajp13 protocol is packet-oriented. A binary format was presumably chosen over the more readable plain text for reasons of performance. The web server communicates with the servlet container over TCP connections. To cut down on the expensive process of socket creation, the web server will attempt to maintain persistent TCP connections to the servlet container, and to reuse a connection for multiple request/response cycles.

Once a connection is assigned to a particular request, it will not be used for any others until the request-handling cycle has terminated. In other words, requests are not multiplexed over connections. This makes for much simpler code at either end of the connection, although it does cause more connections to be open at once.

Once the web server has opened a connection to the servlet container, the connection can be in one of the following states:

  • Idle
    No request is being handled over this connection.
  • Assigned
    The connecton is handling a specific request.

Once a connection is assigned to handle a particular request, the basic request informaton (e.g. HTTP headers, etc) is sent over the connection in a highly condensed form (e.g. common strings are encoded as integers). Details of that format are below in Request Packet Structure. If there is a body to the request (content-length > 0), that is sent in a separate packet immediately after.

At this point, the servlet container is presumably ready to start processing the request. As it does so, it can send the following messages back to the web server:

  • SEND_HEADERS
    Send a set of headers back to the browser.
  • SEND_BODY_CHUNK
    Send a chunk of body data back to the browser.
  • GET_BODY_CHUNK
    Get further data from the request if it hasn't all been transferred yet. This is necessary because the packets have a fixed maximum size and arbitrary amounts of data can be included the body of a request (for uploaded files, for example). (Note: this is unrelated to HTTP chunked tranfer).
  • END_RESPONSE
    Finish the request-handling cycle.

Each message is accompanied by a differently formatted packet of data. See Response Packet Structures below for details.

Basic Packet Structure

There is a bit of an XDR heritage to this protocol, but it differs in lots of ways (no 4 byte alignment, for example).

AJP13 uses network byte order for all data types.

There are four data types in the protocol: bytes, booleans, integers and strings.

Byte
A single byte.
Boolean
A single byte, 1 = true, 0 = false. Using other non-zero values as true (i.e. C-style) may work in some places, but it won't in others.
Integer
A number in the range of 0 to 2^16 (32768). Stored in 2 bytes with the high-order byte first.
String
A variable-sized string (length bounded by 2^16). Encoded with the length packed into two bytes first, followed by the string (including the terminating '\0'). Note that the encoded length does not include the trailing '\0' -- it is like strlen. This is a touch confusing on the Java side, which is littered with odd autoincrement statements to skip over these terminators. I believe the reason this was done was to allow the C code to be extra efficient when reading strings which the servlet container is sending back -- with the terminating \0 character, the C code can pass around references into a single buffer, without copying. If the \0 was missing, the C code would have to copy things out in order to get its notion of a string. Note a size of -1 (65535) indicates a null string and no data follow the length in this case.

Packet Size

According to much of the code, the max packet size is 8 * 1024 bytes (8K). The actual length of the packet is encoded in the header.

Packet Headers

Packets sent from the server to the container begin with 0x1234. Packets sent from the container to the server begin with AB (that's the ASCII code for A followed by the ASCII code for B). After those first two bytes, there is an integer (encoded as above) with the length of the payload. Although this might suggest that the maximum payload could be as large as 2^16, in fact, the code sets the maximum to be 8K.
Packet Format (Server->Container)
Byte 0 1 2 3 4...(n+3)
Contents 0x12 0x34 Data Length (n) Data
Packet Format (Container->Server)
Byte 0 1 2 3 4...(n+3)
Contents A B Data Length (n) Data

For most packets, the first byte of the payload encodes the type of message. The exception is for request body packets sent from the server to the container -- they are sent with a standard packet header (0x1234 and then length of the packet), but without any prefix code after that (this seems like a mistake to me).

The web server can send the following messages to the servlet container:
Code Type of Packet Meaning
2 Forward Request Begin the request-processing cycle with the following data
7 Shutdown The web server asks the container to shut itself down.
8 Ping The web server asks the container to take control (secure login phase).
10 CPing The web server asks the container to respond quickly with a CPong.
none Data Size (2 bytes) and corresponding body data.

To ensure some basic security, the container will only actually do the Shutdown if the request comes from the same machine on which it's hosted.

The first Data packet is send immediatly after the Forward Request by the web server.

The servlet container can send the following types of messages to the web server:
Code Type of Packet Meaning
3 Send Body Chunk Send a chunk of the body from the servlet container to the web server (and presumably, onto the browser).
4 Send Headers Send the response headers from the servlet container to the web server (and presumably, onto the browser).
5 End Response Marks the end of the response (and thus the request-handling cycle).
6 Get Body Chunk Get further data from the request if it hasn't all been transferred yet.
9 CPong Reply The reply to a CPing request

Each of the above messages has a different internal structure, detailed below.

Request Packet Structure

For messages from the server to the container of type "Forward Request":

AJP13_FORWARD_REQUEST :=
    prefix_code      (byte) 0x02 = JK_AJP13_FORWARD_REQUEST
    method           (byte)
    protocol         (string)
    req_uri          (string)
    remote_addr      (string)
    remote_host      (string)
    server_name      (string)
    server_port      (integer)
    is_ssl           (boolean)
    num_headers      (integer)
    request_headers *(req_header_name req_header_value)
    attributes      *(attribut_name attribute_value)
    request_terminator (byte) OxFF

The request_headers have the following structure:

req_header_name := 
    sc_req_header_name | (string)  [see below for how this is parsed]

sc_req_header_name := 0xA0xx (integer)

req_header_value := (string)

The attributes are optional and have the following structure:

attribute_name := sc_a_name | (sc_a_req_attribute string)

attribute_value := (string)

Not that the all-important header is "content-length', because it determines whether or not the container looks for another packet immediately.

Detailed description of the elements of Forward Request.

request_prefix

For all requests, this will be 2. See above for details on other prefix codes.

method

The HTTP method, encoded as a single byte:

Command NameCode
OPTIONS1
GET2
HEAD3
POST4
PUT5
DELETE6
TRACE7
PROPFIND8
PROPPATCH9
MKCOL10
COPY11
MOVE12
LOCK13
UNLOCK14
ACL15
REPORT16
VERSION-CONTROL17
CHECKIN18
CHECKOUT19
UNCHECKOUT20
SEARCH21
MKWORKSPACE22
UPDATE23
LABEL24
MERGE25
BASELINE_CONTROL26
MKACTIVITY27

Later version of ajp13, when used with mod_jk2, will transport additional methods, even if they are not in this list.

protocol, req_uri, remote_addr, remote_host, server_name, server_port, is_ssl

These are all fairly self-explanatory. Each of these is required, and will be sent for every request.

Headers

The structure of request_headers is the following: First, the number of headers num_headers is encoded. Then, a series of header name req_header_name / value req_header_value pairs follows. Common header names are encoded as integers, to save space. If the header name is not in the list of basic headers, it is encoded normally (as a string, with prefixed length). The list of common headers sc_req_header_nameand their codes is as follows (all are case-sensitive):

NameCode valueCode name
accept0xA001SC_REQ_ACCEPT
accept-charset0xA002SC_REQ_ACCEPT_CHARSET
accept-encoding0xA003SC_REQ_ACCEPT_ENCODING
accept-language0xA004SC_REQ_ACCEPT_LANGUAGE
authorization0xA005SC_REQ_AUTHORIZATION
connection0xA006SC_REQ_CONNECTION
content-type0xA007SC_REQ_CONTENT_TYPE
content-length0xA008SC_REQ_CONTENT_LENGTH
cookie0xA009SC_REQ_COOKIE
cookie20xA00ASC_REQ_COOKIE2
host0xA00BSC_REQ_HOST
pragma0xA00CSC_REQ_PRAGMA
referer0xA00DSC_REQ_REFERER
user-agent0xA00ESC_REQ_USER_AGENT

The Java code that reads this grabs the first two-byte integer and if it sees an '0xA0' in the most significant byte, it uses the integer in the second byte as an index into an array of header names. If the first byte is not '0xA0', it assumes that the two-byte integer is the length of a string, which is then read in.

This works on the assumption that no header names will have length greater than 0x9FFF (==0xA000 - 1), which is perfectly reasonable, though somewhat arbitrary. (If you, like me, started to think about the cookie spec here, and about how long headers can get, fear not -- this limit is on header names not header values. It seems unlikely that unmanageably huge header names will be showing up in the HTTP spec any time soon).

Note: The content-length header is extremely important. If it is present and non-zero, the container assumes that the request has a body (a POST request, for example), and immediately reads a separate packet off the input stream to get that body.

Attributes

The attributes prefixed with a ? (e.g. ?context) are all optional. For each, there is a single byte code to indicate the type of attribute, and then a string to give its value. They can be sent in any order (though the C code always sends them in the order listed below). A special terminating code is sent to signal the end of the list of optional attributes. The list of byte codes is:

InformationCode ValueNote
?context0x01Not currently implemented
?servlet_path0x02Not currently implemented
?remote_user0x03
?auth_type0x04
?query_string0x05
?route0x06
?ssl_cert0x07
?ssl_cipher0x08
?ssl_session0x09
?req_attribute0x0AName (the name of the attribut follows)
?ssl_key_size0x0B
?secret0x0C
?stored_method0x0D
are_done0xFFrequest_terminator

The context and servlet_path are not currently set by the C code, and most of the Java code completely ignores whatever is sent over for those fields (and some of it will actually break if a string is sent along after one of those codes). I don't know if this is a bug or an unimplemented feature or just vestigial code, but it's missing from both sides of the connection.

The remote_user and auth_type presumably refer to HTTP-level authentication, and communicate the remote user's username and the type of authentication used to establish their identity (e.g. Basic, Digest). I'm not clear on why the password isn't also sent, but I don't know HTTP authentication inside and out.

The query_string, ssl_cert, ssl_cipher, and ssl_session refer to the corresponding pieces of HTTP and HTTPS.

The route, as I understand it, is used to support sticky sessions -- associating a user's session with a particular Tomcat instance in the presence of multiple, load-balancing servers. I don't know the details.

Beyond this list of basic attributes, any number of other attributes can be sent via the req_attribute code (0x0A). A pair of strings to represent the attribute name and value are sent immediately after each instance of that code. Environment values are passed in via this method.

Finally, after all the attributes have been sent, the attribute terminator, 0xFF, is sent. This signals both the end of the list of attributes and also then end of the Request Packet.

Response Packet Structure

For messages which the container can send back to the server.

AJP13_SEND_BODY_CHUNK := 
  prefix_code   3
  chunk_length  (integer)
  chunk        *(byte)


AJP13_SEND_HEADERS :=
  prefix_code       4
  http_status_code  (integer)
  http_status_msg   (string)
  num_headers       (integer)
  response_headers *(res_header_name header_value)

res_header_name := 
    sc_res_header_name | (string)   [see below for how this is parsed]

sc_res_header_name := 0xA0 (byte)

header_value := (string)

AJP13_END_RESPONSE :=
  prefix_code       5
  reuse             (boolean)


AJP13_GET_BODY_CHUNK :=
  prefix_code       6
  requested_length  (integer)

Details:

Send Body Chunk

The chunk is basically binary data, and is sent directly back to the browser.

Send Headers

The status code and message are the usual HTTP things (e.g. "200" and "OK"). The response header names are encoded the same way the request header names are. See above for details about how the the codes are distinguished from the strings. The codes for common headers are:

NameCode value
Content-Type0xA001
Content-Language0xA002
Content-Length0xA003
Date0xA004
Last-Modified0xA005
Location0xA006
Set-Cookie0xA007
Set-Cookie20xA008
Servlet-Engine0xA009
Status0xA00A
WWW-Authenticate0xA00B

After the code or the string header name, the header value is immediately encoded.

End Response

Signals the end of this request-handling cycle. If the reuse flag is true (anything other than 0 in the actual C code), this TCP connection can now be used to handle new incoming requests. If reuse is false (==0), the connection should be closed.

Get Body Chunk

The container asks for more data from the request (If the body was too large to fit in the first packet sent over or when the request is chuncked). The server will send a body packet back with an amount of data which is the minimum of the request_length, the maximum send body size (8186 (8 Kbytes - 6)), and the number of bytes actually left to send from the request body.
If there is no more data in the body (i.e. the servlet container is trying to read past the end of the body), the server will send back an "empty" packet, which is a body packet with a payload length of 0. (0x12,0x34,0x00,0x00)

Questions I Have

What happens if the request headers > max packet size? There is no provision to send a second packet of request headers in case there are more than 8K (I think this is correctly handled for response headers, though I'm not certain). I don't know if there is a way to get more than 8K worth of data into that initial set of request headers, but I'll bet there is (combine long cookies with long ssl information and a lot of environment variables, and you should hit 8K easily). I think the connector would just fail before trying to send any headers in this case, but I'm not certain.

What about authentication? There doesn't seem to be any authentication of the connection between the web server and the container. This strikes me as potentially dangerous.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/reference/0000755000000000000020000000000012555256554017217 5ustar rootbintomcat-connectors-1.2.41-src/docs/reference/workers.html0000644000000000000020000020634312555256554021611 0ustar rootbinThe Apache Tomcat Connectors - Reference Guide - workers.properties configuration
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Reference Guide

workers.properties configuration

Printer Friendly Version
print-friendly
version
Introduction

A Tomcat worker is a Tomcat instance that is waiting to execute servlets or any other content on behalf of some web server. For example, we can have a web server such as Apache forwarding servlet requests to a Tomcat process (the worker) running behind it.

The scenario described above is a very simple one; in fact one can configure multiple Tomcat workers to serve servlets on behalf of a certain web server. The reasons for such configuration can be:

  • We want different contexts to be served by different Tomcat workers to provide a development environment where all the developers share the same web server but own a Tomcat worker of their own.
  • We want different virtual hosts served by different Tomcat processes to provide a clear separation between sites belonging to different companies.
  • We want to provide load balancing, meaning run multiple Tomcat workers each on a machine of its own and distribute the requests between them.

There are probably more reasons for having multiple workers but I guess that this list is enough...

Tomcat workers are defined in a properties file dubbed workers.properties and this tutorial explains how to work with it.

Configuration File Basics

Defining workers to the Tomcat web server plugin can be done using a properties file (a sample file named workers.properties is available in the conf/ directory).

Format, Comments, Whitespace

The lines in the file define properties. The general format is

<name>=<value>

Dots are used as part of the name to represent a configuration hierarchy.

Invalid directives will be logged during web server startup and prevent the web server from working properly. Some directives have been deprecated. Although they will still work, you should replace them by their successors.

Some directives are allowed multiple times. This will be explicitly noted in the tables below.

Whitespace at the beginning and the end of a property name or value gets ignored. Comments can be placed in any line and start with a hash sign '#'. Any line contents behind the hash sign get ignored.

Boolean properties can be set either using the numbers 0 (false) and 1 (true) as values, or off (false) and on (true) or any other string starting with the letters f (false), n (false), t (true) or y (true). The values are taken case insensitive. In this documentation we will stick to false and true.

Global Properties

These directives have global scope.

DirectiveDefaultDescription
worker.listajp13 A comma separated list of workers names that the JK will use. When starting up, the web server plugin will instantiate the workers whose name appears in the worker.list property, these are also the workers to whom you can map requests.

This directive can be used multiple times.

worker.maintain60 Worker connection pool maintain interval in seconds. If set to the positive value JK will scan all connections for all workers specified in worker.list directive and check if connections needs to be recycled.

Furthermore any load balancer does a global maintenance every worker.maintain seconds. During global maintenance load counters are decayed and workers in error are checked for recover_time.

This feature has been added in jk 1.2.13.

Worker Properties

Each worker configuration directive consists of three words separated by a dot:

worker.<worker name>.<directive>=<value>

The first word is always worker. The second word is the worker name you can choose. In the case of load-balancing, the worker name has an additional meaning. Please consult the Load Balancer HowTo.

The name of the worker can contain only the alphanumeric characters [a-z][A-Z][0-9][_\-] and is case sensitive.

Variables, Environment Variables

You can define and use variables in the workers.properties file. To define a variable you use the syntax:

<variable_name>=<value>

Dots are allowed in the variable name, but you have to be careful not to use variable names, that clash with standard directives. Therefore variable names should never start with "worker.".

To use a variable, you can insert "$(variable_name)" at any place on the value side of a property line. If a variable has not been defined before its use, we will search the process environment for a variable with the same name and use their value.

Property Inheritance

Often one wants to use the same property values for various workers. To reduce duplication of configuration lines and to ease the maintenance of the file, you can inherit properties from one worker to another, or even from a template to real workers.

The directive "reference" allows to copy configurations between workers or worker templates in a hierarchical way. If worker castor sets worker.castor.reference=worker.pollux then it inherits all properties of pollux, except for the ones that are explicitly set for castor.

Please note, that the value of the directive is not only the name of the referred worker, but the complete prefix including "worker.".

To use a template worker simply define it like a real worker, but do not add it to the "worker.list" or as a member to any load balancer. Such a template worker does not have to contain mandatory directives. This approach is especially useful, if one has a lot of balanced workers in a load balancer and these workers share most of their properties. You can set all of these properties in a template worker, e.g. using the prefix "worker.template1", and then simply reference those common properties in all balanced workers.

References can be used to inherit properties over multiple hops in a hierarchical way. The maximum depth for nesting references is 20. Be careful not to introduce a reference loop!

This feature has been added in jk 1.2.19.

List of All Worker Directives

Mandatory Directives

Mandatory directives are the one that each worker must contain. Without them the worker will be unavailable or will misbehave. Those directives will be marked with a strong font in the following tables.

DirectiveDefaultDescription
typeajp13 Type of the worker (can be one of ajp13, ajp14, jni, lb or status). The type of the worker defines the directives that can be applied to the worker.

Type ajp13 is the preferred worker type that JK uses for communication between web server and Tomcat. This type of worker uses sockets as communication channel. For detailed description of the AJP13 protocol stack browse to AJPv13 protocol specification

Type ajp14 is experimental and not recommended.

JNI workers have been deprecated. They will likely not work. Do not use them.

Connection Directives

Connection directives defines the parameters needed to connect and maintain the connections pool of persistent connections between JK and remote Tomcat.

DirectiveDefaultDescription
hostlocalhost Host name or IP address of the backend Tomcat instance. The remote Tomcat must support the AJP13 protocol stack. The host name can have a port number embedded separated by the colon (':') character.
port8009 Port number of the remote Tomcat instance listening for defined protocol requests. The default value depends on the worker type. For ajp13 workers the default port is 8009, while for ajp14 type of worker that value is 8011.
source- Name or IP address used for the connection source (outgoing address). It should only be used on multi-homed hosts.

This feature is experimental and has been added in jk 1.2.41.

socket_timeout0 Socket timeout in seconds used for the communication channel between JK and remote host. If the remote host does not respond inside the timeout specified, JK will generate an error, and retry again. If set to zero (default) JK will wait for an infinite amount of time on all socket operations.
socket_connect_timeoutsocket_timeout*1000 Socket connect timeout in milliseconds used for the communication channel between JK and remote host. If the remote host does not respond inside the timeout specified, JK will generate an error, and retry again.

Note that socket_timeout is in seconds, and socket_connect_timeout in milliseconds, so in absolute terms the default socket_connect_timeout is equal to "socket_timeout.

This feature has been added in jk 1.2.27.

socket_keepalivefalse This directive should be used when you have a firewall between your webserver and the Tomcat engine, who tend to drop inactive connections. This flag will tell the Operating System to send KEEP_ALIVE messages on inactive connections (interval depend on global OS settings, generally 120 minutes), and thus prevent the firewall to cut inactive connections. To enable keepalive set this property value to true.

The problem with Firewall cutting inactive connections is that sometimes, neither webserver or Tomcat have information about the cut and couldn't handle it.

ping_mode- This flag determines, under which conditions established connections are probed to ensure they are still working. The probe is done with an empty AJP13 packet (CPing) and expects to receive an appropriate answer (CPong) within some timeout.

The value of the flag can be any combination of the following flags (multiple values are combined without any separators):

C (connect): If set, the connection will be probed once after connecting to the backend. The timeout can be set by connect_timeout. If it is not set, the value of ping_timeout will be used instead.

P (prepost): If set, the connection will be probed before sending each request to the backend. The timeout can be set by prepost_timeout. If it is not set, the value of ping_timeout will be used instead.

I (interval): If set, the connection will be probed during the regular internal maintenance cycle, but only if it is idle longer than connection_ping_interval. The timeout can be set by ping_timeout.

A If set, all of the above probes will be used.

This feature has been added in jk 1.2.27. Connect and prepost probing were already available via connect_timeout and prepost_timeout since version jk 1.2.6.

ping_timeout10000 Timeout in milliseconds used when waiting for the CPong answer of a CPing connection probe. The activation of the probes is done via ping_mode. The timeouts for ping_mode connect and prepost can be overwritten individually via connect_timeout and prepost_timeout.

For compatibility reasons, CPing/CPong is also used, whenever connect_timeout or prepost_timeout are set, even if ping_mode is empty.

This feature has been added in jk 1.2.27.

connection_ping_interval0 / (ping_timeout/1000)*10 When using interval connection probing, connections idle for longer than this interval in seconds are probed by CPing packets whether they still work.

Interval probing can be activated either by ping_mode, or by setting connection_ping_interval to some value bigger than zero. If you activate interval probing via ping_mode, then the default value of connection_ping_interval is (ping_timeout/1000) * 10. Note that ping_timeout is in milliseconds, and connection_ping_interval in seconds, so in absolute terms the default connection_ping_interval is 10 times ping_timeout.

This feature has been added in jk 1.2.27.

connection_pool_sizesee text This defines the number of connections made to the AJP backend that are maintained as a connection pool. It will limit the number of those connection that each web server child process can made.

Connection pool size property is only used for multi threaded web servers such as Apache, IIS and Netscape/Sun. The connection_pool_size property needs to reflect the number of requests one web server process should be able to send to a backend in parallel. Usually this is the same as the number of threads per web server process. JK will discover this number for the Apache web server automatically and set the pool size to this value. For IIS the default value is 250 (before version 1.2.20: 10), for Netscape/Sun the default value is 1.

We strongly recommend adjusting this value for IIS and the Netscape/Sun to the number of requests one web server process should be able to send to a backend in parallel. You should measure how many connections you need during peak activity without performance problems, and then add some percentage depending on your growth rate. Finally you should check, whether your web server processes are able to use at least as many threads, as you configured as the pool size.

Do not use connection_pool_size with values higher then 1 on Apache 2.x prefork or Apache 1.3.x!

connection_pool_minsize(pool+1)/2 Minimum size of the connection pool that will be maintained.

Its default value is (connection_pool_size+1)/2.

Do not use connection_pool_size with values higher then 1 on Apache 2.x prefork or Apache 1.3.x!

This feature has been added in jk 1.2.16.

connection_pool_timeout0 Cache timeout property should be used with connection_pool_minsize to specify how many seconds JK should keep an inactive socket in cache before closing it. This property should be used to reduce the number of threads on the Tomcat web server. The default value zero disables the closing (infinite timeout).

Each child could open an ajp13 connection if it has to forward a request to Tomcat, creating a new ajp13 thread on Tomcat side.

The problem is that after an ajp13 connection is created, the child won't drop it until killed. And since the webserver will keep its childs/threads running to handle high-load, even it the child/thread handle only static contents, you could finish having many unused ajp13 threads on the Tomcat side.

You should keep this time interval in sync with the keepAliveTimeout attribute (if it is set explicitly) or connectionTimeout attribute of your AJP connector in Tomcat's server.xml. Note however, that the value for mod_jk is given in seconds, the one in server.xml has to use milliseconds.

connection_acquire_timeoutretries*retry_interval Timeout the worker will wait for a free socket in cache before giving up.

Its default value is retries * retry_interval.

This feature has been added in jk 1.2.27.

lbfactor1 Only used for a member worker of a load balancer.

The integer number lbfactor (load-balancing factor) is how much we expect this worker to work, or the worker's work quota. Load balancing factor is compared with other workers that makes the load balancer. For example if one worker has lb_factor 5 times higher then other worker, then it will receive five times more requests.

Load Balancing Directives

Load balancer is a virtual worker that does not really communicate with Tomcat workers. Instead it is responsible for the management of several "real" workers. The worker is supposed to be a load balancer if it's worker type is lb. See worker's type directive.

Loadbalancer directives define the parameters needed to create the workers that are connecting to a remote cluster of backend Tomcat servers. Each cluster node has to have a worker defined.

Load balancer management includes:

  • Instantiating the workers in the web server.
  • Using the worker's load-balancing factor, perform weighed-round-robin load balancing where high lbfactor means stronger machine (that is going to handle more requests)
  • Keeping requests belonging to the same session executing on the same Tomcat worker.
  • Identifying failed Tomcat workers, suspending requests to them and instead fall-backing on other workers managed by the lb worker.

The overall result is that workers managed by the same lb worker are load-balanced (based on their lbfactor and current user session) and also fall-backed so a single Tomcat process death will not "kill" the entire site.

If you want to use session stickiness, you must set different jvmRoute attributes in the Engine element in Tomcat's server.xml. Furthermore the names of the workers which are managed by the balancer have to be equal to the jvmRoute of the Tomcat instance they connect with.

The restriction on the worker names can be lifted, if you use the route attribute for the workers.

The following table specifies properties that the lb worker can accept:

DirectiveDefaultDescription
balance_workers- A comma separated list of workers that the load balancer need to manage.

This directive can be used multiple times for the same load balancer.

This directive replaces old balanced_workers directive and can be used only with mod_jk versions 1.2.7 and up.

As long as these workers should only be used via the load balancer worker, there is no need to also put them into the worker.list property.

sticky_sessiontrue Specifies whether requests with SESSION ID's should be routed back to the same Tomcat worker. If sticky_session is set to true sessions are sticky, otherwise sticky_session is set to false. Set sticky_session to false when Tomcat is using a Session Manager which can persist session data across multiple instances of Tomcat.

The sticky_session setting can be overwritten using the Apache httpd environment variable JK_STICKY_IGNORE and the worker map extension for sticky_ignore. This has been added in version 1.2.33.

sticky_session_forcefalse Specifies whether requests with SESSION ID's for workers that are in error state should be rejected. If sticky_session_force is set to true and the worker that matches that SESSION ID is in error state, client will receive 500 (Server Error). If set to false failover on another worker will be issued with losing client session. This directive is used only when you set sticky_session=true.

This feature has been added in jk 1.2.9.

methodRequest Specifies what method load balancer is using for electing the best worker. Please note, that session stickiness and perfect load balancing are conflicting targets, especially when the number of sessions is small, or the usage of sessions is extremely varying For huge numbers of sessions this usually is not a problem.

Some methods note, that they aggregate in a sliding time window. They add up accesses, and on each run of the global maintain method, the load counters get divided by 2. Usually this happens once a minute, depending on the setting of worker.maintain. The value of the load counters can be inspected using the status worker.

If method is set to R[equest] the balancer will use the number of requests to find the best worker. Accesses will be distributed according to the lbfactor in a sliding time window. This is the default value and should be working well for most applications.

If method is set to S[ession] the balancer will use the number of sessions to find the best worker. Accesses will be distributed according to the lbfactor in a sliding time window. This method should be used, if sessions are your limiting resource, e.g. when you only have limited memory and your sessions need a lot of memory. Because the balancer does not keep any state, it actually does not know the number of sessions. Instead it counts each request without a session cookie or URL encoding as a new session. This method will neither know, when a session is being invalidated, nor will it correct its load numbers according to session timeouts or worker failover. If you know request URLs, that will be called without a session ID but should not be counted as new sessions, you should add them to the stateless mapping rule extension or set the Apache HTTPD environment variable JK_STATELESS for them.

If method is set to N[ext] the balancer will again use the number of sessions to find the best worker. All remarks concerning the Sessionmethod apply as well. The difference to the Session method is how the session count is handled in the sliding time window. The Next method does not divide by 2, instead it subtracts the current minimum number. This should effectively result in a round-robin session balancing, thus the name Next. Under high load, the two session balancing methods will result in a similar distribution, but Next will be better if you need to distribute small numbers of sessions.

If set to T[raffic] the balancer will use the network traffic between JK and Tomcat to find the best worker. Accesses will be distributed according to the lbfactor in a sliding time window. This method should be used, if network to and from the backends is your limiting resource.

If set to B[usyness] the balancer will pick the worker with the lowest current load, based on how many requests the worker is currently serving. This number is divided by the workers lbfactor, and the lowest value (least busy) worker is picked. This method is especially interesting, if your request take a long time to process, like for a download application. The method is not recommended for general use, because under high load on some hardware architectures the busy counter can become wrong.

This feature has been added in version 1.2.9. The Session method has been added in version 1.2.20, the Next method in version 1.2.33.

lockOptimistic Specifies what lock method the load balancer will use for synchronising shared memory runtime data. If lock is set to O[ptimistic] balancer will not use shared memory lock to find the best worker. If set to P[essimistic] balancer will use shared memory lock. The balancer will work more accurately in case of Pessimistic locking, but can slow down the average response time.

This feature has been added in jk 1.2.13.

retries2

This directive also exists for normal workers. For those it has a different meaning.

If the load balancer can not get a valid member worker or in case of failover, it will try again a number of times given by retries. Before each retry, it will make a pause define by retry_interval directive.

Until version 1.2.16 the default value was 3.

Status Worker Directives

The status worker does not communicate with Tomcat. Instead it is responsible for the load balancer management.

DirectiveDefaultDescription
css- Specifies the url for cascading stylesheet to use.
read_onlyfalse A status worker with read_only=true will not allow any operations, that change the runtime state or configuration of the other workers. These are edit/update/reset/recover.

This feature has been added in jk 1.2.20.

user- It is a list of users which gets compared to the user name authenticated by the web server. If the name is not contained in this list, access is denied. Per default the list is empty and then access is allowed to anybody.

This directive can be used multiple times.

This feature has been added in jk 1.2.20.

user_case_insensitivefalse By default, the user names are matched case sensitively. You can set user_case_insensitive=true to make the comparison case insensitive. This may be especially useful on the Windows platform.

This feature has been added in jk 1.2.21.

gooda.o,a.n,a.b,a.r For every load balancer worker, the status worker shows a summary of the state of its members. There are three such states, "good", "bad" and "degraded".

These states are determined depending on the activation of the members (active, disabled, stopped) and their runtime state (ok, n/a, busy, recovering, probing, forced recovery, error). By default, members are assumed to be "good", if their activation is "active" and their runtime state is not "error".

You can change this mapping, by assigning a list of values to the attribute "good". Each value gives a possible match for the members, and one match suffices. Each value is either a single character, or two characters combined with a dot ".". The single characters are the first characters in the words "active", "disabled", "stopped", "ok", "na", "busy", "recovering", "error". The additional states "probing" and "forced recovery" are always rated equivalent to "recovering". If a value consists only of a single character, then all members with this activation or runtime state will be assumed good. A combination of an activation and a runtime state concatenated with a dot "." does only apply to a member, that has exactly this activation and state.

Members of a load balancer will first be matched against the state "bad", if they don't match, the state "good" will be tried, and if they still don't match, their state will be "degraded".

This directive can be used multiple times.

This feature has been added in jk 1.2.20.

bads,e See: "good".

By default, members are assumed to be "bad", if their activation is "stopped" or their runtime state is "error".

This directive can be used multiple times.

This feature has been added in jk 1.2.20.

prefixworker The prefix, which will be used by the status worker when producing properties output (mime=prop). Each property key will be prefixed by this value.

This feature has been added in jk 1.2.20.

nsjk: This directive can be used to customise the XML output from the status worker. If set to - no namespace will be used.

This feature has been added in jk 1.2.20.

xmlns- This directive can be used to customise the XML output from the status worker. If set to - no xmlns will be used.

Default value is set to xmlns:jk="http://tomcat.apache.org"

This feature has been added in jk 1.2.20.

doctype- This directive can be used to customise the XML output from the status worker. This value will be inserted to the output xml after the xml header.

This feature has been added in jk 1.2.20.

Advanced Worker Directives

This table lists more advanced configuration options. Most of them only apply to some types of workers. We use the abbreviations AJP for ajp13/ajp14 workers used directly via the workers.list, LB for load balancer workers, and SUB for the workers used indirectly in a load balancer worker as a sub worker or member.

DirectiveWorker TypeDefaultDescription
connect_timeoutAJP,SUB0 Connect timeout property told webserver to send a PING request on ajp13 connection after connection is established. The parameter is the delay in milliseconds to wait for the PONG reply. The default value zero disables the timeout (infinite timeout).

This features has been added in jk 1.2.6 to avoid problem with hung Tomcat's and require ajp13 ping/pong support which has been implemented on Tomcat 3.3.2+, 4.1.28+ and 5.0.13+. Disabled by default.

prepost_timeoutAJP,SUB0 Prepost timeout property told webserver to send a PING request on ajp13 connection before forwarding to it a request. The parameter is the delay in milliseconds to wait for the PONG reply. The default value zero disables the timeout (infinite timeout).

This features has been added in jk 1.2.6 to avoid problem with hung Tomcat's and require ajp13 ping/pong support which has been implemented on Tomcat 3.3.2+, 4.1.28+ and 5.0.13+. Disabled by default.

reply_timeoutAJP,SUB0 The parameter is the number of milliseconds to wait for success during a read event. So this is not a timeout for the complete answer time of a request, but only for the maximum time between two packets received from Tomcat. Usually the longest pause is between sending the request and getting the first packet of the response.

If the timeout passes without any data received from Tomcat, the webserver will no longer wait for the rest of the response and send an error to the client (browser). Usually this does not mean, that the request is also aborted on the Tomcat backend. If the worker is a member of a load balancer, the load balancer might place the worker into an error state and retry the request on another member. See also max_reply_timeouts, retries and recovery_options.

By default (value zero) the webserver will wait forever which could be an issue for you. If you set a reply_timeout, adjust it carefully if you have long running servlets.

The reply_timeout can be overwritten using the Apache httpd environment variable JK_REPLY_TIMEOUT and the worker map extension for reply_timeout.

This features has been added in jk 1.2.6 to avoid problem with hung Tomcat's and works on all servlet engines supporting ajp13. The variable JK_REPLY_TIMEOUT and the worker map extension have been added in version 1.2.27.

retriesAJP,SUB2

This directive also exists for load balancer workers. For those it has a different meaning.

The maximum number of times that the worker will send a request to Tomcat in case of a communication error. Each retry will be done over another connection. The first time already gets counted, so retries=2 means one retry after error. Before a retry, the worker waits for a configurable sleeping time.

See also the attribute recovery_options for a more fine-grained control of retries and retry_interval for the sleep time configuration.

Until version 1.2.16 the default value was 3.

retry_intervalAJP,SUB100 The amount of time in milliseconds the worker sleeps before doing any retry.

This features has been added in jk 1.2.27.

recovery_optionsAJP,SUB0 Recovery options influence, how we should handle retries, in case we detect a problem with Tomcat. How often we will retry is controlled by the attribute retries.

This attribute is a bit mask. The following bits are allowed:
1: don't recover if Tomcat failed after getting the request
2: don't recover if Tomcat failed after sending the headers to client
4: close the connection to Tomcat, if we detect an error when writing back the answer to the client (browser)
8: always recover requests for HTTP method HEAD (even if Bits 1 or 2 are set)
16: always recover requests for HTTP method GET (even if Bits 1 or 2 are set)

This features has been added in jk 1.2.6. Option 4 has been added in version 1.2.16, options 8 and 16 in version 1.2.24.

fail_on_statusAJP,SUB0 Set this value to the HTTP status code that will cause a worker to fail if returned from Servlet container. Use this directive to deal with cases when the servlet container can temporary return non-200 responses for a short amount of time, e.g during redeployment.

The error page, headers and status codes of the original response will not be send back to the client. Instead the request will result in a 503 response. If the worker is a member of a load balancer, the member will be put into an error state. Request failover and worker recovery will be handled with the usual load balancer procedures.

This feature has been added in jk 1.2.20.

Starting with jk 1.2.22 it is possible to define multiple status codes separated by space or comma characters. For example: worker.xxx.fail_on_status=500,503

Starting with jk 1.2.25 you can also tell the load balancer to not put a member into an error state, if a response returned with one of the status codes in fail_on_status. This feature gets enabled, by putting a minus sign in front of those status codes. For example: worker.xxx.fail_on_status=-404,-500,503

busy_limitAJP,SUB0 If set to a positive number, the worker will only be used for a request, if it is currently working on less than this number of concurrent requests.

Note that this is not related to the Busyness load balancing method.

This feature is experimental and has been added in jk 1.2.41.

max_packet_sizeAJP,SUB8192 This attribute sets the maximal AJP packet size in Bytes. The maximum value is 65536. If you change it from the default, you must also change the packetSize attribute of your AJP connector on the Tomcat side! The attribute packetSize is only available in Tomcat 5.5.20+ and 6.0.2+.

Normally it is not necessary to change the maximum packet size. Problems with the default value have been reported when sending certificates or certificate chains.

This feature has been added in jk 1.2.19.

prefer_ipv6AJP,SUBfalse When compiled with IPV6 support, this directive forces IPV6 address resolution for host names which have both IPV6 and IPV4 addresses. In case there is no IPV6 address defined for the given hostname this directive in ineffective. This directive will be also ineffective if there is only IPV6 address defined or if IP address is used for "host", either in IPV4 or IPV6 notation.

This feature has been added in jk 1.2.38.

secretAJP,SUB,LB- You can set a secret keyword on the Tomcat AJP Connector. Then only requests from workers with the same secret keyword will be accepted.

Use request.secret="secret key word" in your Tomcat AJP Connector configuration in Tomcat 5.5 or 6.0 and requiredSecret="secret key word" in Tomcat 7.0 onwards.

If you set a secret on a load balancer, all its members will inherit this secret.

This feature has been added in jk 1.2.12.

mountAJP,LB- Space delimited list of uri maps the worker should handle. It is only used, if the worker is included in worker.list.

This directive can be used multiple times for the same worker.

max_reply_timeoutsLB0 If you use a reply_timeout for the members of a load balancer worker, and you want to tolerate a few requests taking longer than reply_timeout, you can set this attribute to some positive value.

Long running requests will still time out after reply_timeout milliseconds waiting for data, but the corresponding member worker will only be put into an error state, if more than max_reply_timeouts requests have timed out. More precisely, the counter for those bad requests will be divided by two, whenever the load balancer does its internal maintenance (by default every 60 seconds).

This features has been added in jk 1.2.24 to make reply_timeout less sensitive for sporadic long running requests.

recover_timeLB60 The recover time is the time in seconds the load balancer will not try to use a worker, after it went into error state. Only after this time has passed, a worker in error state will be marked as in recovering, so that it will be tried for new requests.

This interval is not checked every time a request is being processed. Instead it is being checked during global maintenance. The time between two runs of global maintenance is controlled by worker.maintain.

Do not set recover_time to a very short time unless you understand the implications. Every recovery attempt for a worker in error is done by a real request!

error_escalation_timeLBrecover_time / 2 Setting a member of a load balancer into an error state is quite serious. E.g. it means that if you need stickyness, all access to the sessions of the respective node is blocked.

Some types of error detection do not provide a precise information, whether a node is completely broken or not. In those cases an LB will not immediately put the node into the error state. Only when there have been no successful responses for error_escalation_time seconds after such an error, will the node be put into error state.

This features has been added in jk 1.2.28.

session_cookieLBJSESSIONID The name of the cookie that contains the routing identifier needed for session stickyness. The routing identifier is everything after a "." character in the value of the cookie.

This feature has been added in jk 1.2.27.

session_pathLB;jsessionid The name of the path parameter that contains the routing identifier needed for session stickyness. The routing identifier is everything after a "." character in the value of the path parameter.

This feature has been added in jk 1.2.27.

set_session_cookieLBfalse Activates generation of session stickyness cookies. Typically you don't need this.

Some web frameworks replace Tomcat session management and use a different way of generating session IDs. As a consequence the routing ID added by Tomcat to the end of the session ID is lost and we no longer can do sticky load balancing. As a workaround you can use the following steps:

  • Choose a non-standard cookie name using the "session_cookie" attribute.
  • Activate cookie sending by setting the attribute "set_session_cookie" to true.
  • Set the attribute "session_cookie_path" to the correct application URI, like e.g. "/myapp/".

The cookie will only be send if the request does not already contain a cookie of the same name, or that cookie does not contain a routing ID which the load balancer can fulfill. Especially after a node failover we will send a new cookie to switch stickyness to the new node.

This feature has been added in jk 1.2.38.

session_cookie_pathLB- This attribute is only used if "set_session_cookie" is set to true. See "set_session_cookie" for a description. If the value of "session_cookie_path" is empty (default), then the send cookie will not contain a PATH information.

This feature has been added in jk 1.2.38.

activationSUBActive Using this directive, a balanced worker of a load balancer can be configured as disabled or stopped. A disabled worker only gets requests, which belong to sessions for that worker. A stopped worker does not get any requests. Users of a stopped worker will lose their sessions, unless session replication via clustering is used.

Use d or D to disable and s or S to stop. If this directive is not present the deprecated directives "disabled" or "stopped" are used.

This flag can be changed at runtime using status worker.

This feature has been added in jk 1.2.19.

routeSUBworker name Normally the name of a balanced worker in a load balancer is equal to the jvmRoute of the corresponding Tomcat instance. If you want to include a worker corresponding to a Tomcat instance into several load balancers with different balancing configuration (e.g. disabled, stopped) you can use this attribute.

Define a separate worker per lb and per Tomcat instance with an arbitrary worker name and set the route attribute of the worker equal to the jvmRoute of the target Tomcat instance.

If this attribute is left empty, the name of the worker will be used.

This attribute can be changed at runtime using status worker.

If the route name contains a period, the part before the first period will be used as domain name, unless domain is set explicitly.

This feature has been added in jk 1.2.16.
The automatic domain rule has been added in jk 1.2.20.
The attribute has been renamed from jvm_route to route in jk 1.2.20.

distanceSUB0 An integer number to express preferences between the balanced workers of an lb worker. A load balancer will never choose some balanced worker in case there is another usable worker with lower distance.

Only in case all workers below a given distance are in error, disabled or stopped, workers of a larger distance are eligible for balancing.

This feature has been added in jk 1.2.16.

domainSUB- Domain directive can be used only when the worker is a member of the load balancer. Workers that share the same domain name are treated as single worker. If sticky_session is used, then the domain name is used as session route.

This directive is used for large system with more then 6 Tomcats, to be able to cluster the Tomcats in two groups and thus lowering the session replication transfer between them.

This feature has been added in jk 1.2.8.

redirectSUB- Set to the name of the preferred failover worker. If worker matching SESSION ID is in error state then the redirect worker will be used instead. It will be used even if being disabled, thus offering hot standby.

If you explicitly set a route via the "route" attribute, you must set "redirect" to this route of the preferred failover worker and not to its name.

This feature has been added in jk 1.2.9.

Deprecated Worker Directives

The following directives have been deprecated in the past. We include their documentation in case you need to use an older version of mod_jk. We urge you to update and not use them any more. Please migrate your existing configurations.

DirectiveSuccessorDefaultDescription
cachesizeconnection_pool_sizesee text

This directive has been deprecated since 1.2.16.

Cachesize defines the number of connections made to the AJP backend that are maintained as a connection pool. It will limit the number of those connection that each web server child process can make.

Cachesize property is used only for multi threaded web servers such as Apache 2.0 (worker), IIS and Netscape. The cachesize property should reflect the number of threads per child process. JK will discover the number of threads per child process on Apache 2 web server with worker-mpm and set its default value to match the ThreadsPerChild Apache directive. For IIS the default value is 10. For other web servers than Apache or IIS this value has to be set manually.

Do not use cachesize with values higher then 1 on Apache 2.x prefork or Apache 1.3.x!

cache_timeoutconnection_pool_timeout0

This directive has been deprecated since 1.2.16.

Cache timeout property should be used with cachesize to specify how to time JK should keep an open socket in cache before closing it. This property should be used to reduce the number of threads on the Tomcat web server.

Each child could open an ajp13 connection if it have to forward a request to Tomcat, creating a new ajp13 thread on Tomcat side.

The problem is that after an ajp13 connection is created, the child won't drop it until killed. And since the webserver will keep its childs/threads running to handle high-load, even it the child/thread handle only static contents, you could finish having many unused ajp13 threads on the Tomcat side.

recycle_timeoutconnection_pool_timeout0

This directive has been deprecated since 1.2.16.

The number of seconds that told webserver to cut an ajp13 connection after some time of inactivity. When choosing an endpoint for a request and the assigned socket is open, it will be closed if it was not used for the configured time. It's a good way to ensure that there won't too old threads living on Tomcat side, with the extra cost you need to reopen the socket next time a request be forwarded. This property is very similar to cache_timeout but works also in non-cache mode. If set to value zero (default) no recycle will took place.
balanced_workersbalance_workers-

This directive has been deprecated since 1.2.7.

A comma separated list of workers that the load balancer need to manage.
disabledactivationfalse

This directive has been deprecated since 1.2.19.

If set to true the worker will be disabled if member of load balancer. This flag can be changed at runtime using status worker.

This feature has been added in jk 1.2.9.

stoppedactivationfalse

This directive has been deprecated since 1.2.19.

If set to true the worker will be stopped if member of load balancer. The flag is needed for stop complete traffic of a sticky session worker. It is only useful, when you have a cluster that replicated the sessions. This flag can be changed at runtime using status worker.

This feature has been added in jk 1.2.11.

jvm_routerouteworker name

This directive has been deprecated since 1.2.20.

Normally the name of a balanced worker in a load balancer is equal to the jvmRoute of the corresponding Tomcat instance. If you want to include a worker corresponding to a Tomcat instance into several load balancers with different balancing configuration (e.g. disabled, stopped) you can use this attribute.

Define a separate worker per lb and per Tomcat instance with an arbitrary worker name and set the jvm_route attribute of the worker equal to the jvmRoute of the target Tomcat instance.

If this attribute is left empty, the name of the worker will be used.

This attribute can be changed at runtime using status worker.

This feature has been added in jk 1.2.16.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/reference/apache.html0000644000000000000020000016251212555256554021335 0ustar rootbinThe Apache Tomcat Connectors - Reference Guide - Configuring Apache
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Reference Guide

Configuring Apache

Printer Friendly Version
print-friendly
version
Configuration Directives

Most of the directives are allowed once in the global part of the Apache httpd configuration and once in every <VirtualHost> elements. Exceptions from this rule are explicitly listed in the table below.

Most values are inherited from the main server to the virtual hosts. Since version 1.2.20 they can be overwritten in the virtual hosts. Exceptions from this rule are again explicitly listed in the table below. See especially JkMountCopy.

Warning: If Apache httpd and Tomcat are configured to serve content from the same filing system location then care must be taken to ensure that httpd is not able to serve inappropriate content such as the contents of the WEB-INF directory or JSP source code.

This could occur if the httpd DocumentRoot overlaps with a Tomcat Host's appBase or the docBase of any Context. It could also occur when using the httpd Alias directive with a Tomcat Host's appBase or the docBase of any Context.

Here are the all directives supported by Apache:

DirectiveDescription
JkWorkersFile

The name of a worker file for the Tomcat servlet containers.
This directive is only allowed once. It must be put into the global part of the configuration.
If you don't use the JkWorkerProperty directives, then you must define your workers with a valid JkWorkersFile. There is no default value.

JkWorkerProperty

Enables setting worker properties inside Apache configuration file. The syntax is the same as in the JkWorkersFile (usually workers.properties). Simply prefix each line with "JkWorkerProperty" to put it directly into the Apache httpd config files.
This directive is allowed multiple times. It must be put into the global part of the configuration.
If you don't use the JkWorkerProperty directives, then you must define your workers with a valid JkWorkersFile. There is no default value.
This directive is available in jk1.2.7 version and later.

JkShmFile

Shared memory file name. Used only on unix platforms. The shm file is used by balancer and status workers.
This directive is only allowed once. It must be put into the global part of the configuration.
The default value is logs/jk-runtime-status. It is highly recommended that the shm file be placed on a local drive and not an NFS share.

The shared memory contains configuration and runtime information for load balancer workers and their members. It is need in order that all apache children

  • share the same status information for load balancing members (OK, ERROR, ...),
  • share the information about load taken by the individual workers,
  • share the information for the parts of the configuration, which are changeable during runtime by status workers.

JkShmSize

Size of the shared memory file name.
This directive is only allowed once. It must be put into the global part of the configuration.
The default value depends on the platform. It is usually less than 64KB.

JkMountFile

File containing multiple mappings from a context to a Tomcat worker. It is usually called uriworkermap.properties.
For inheritance rules, see: JkMountCopy.
There is no default value.

JkMountFileReload

This directive configures the reload check interval in seconds. The JkMountFile is checked periodically for changes. A changed file gets reloaded automatically. If you set this directive to "0", reload checking is turned off.
The default value is 60 seconds.
This directive has been added in version 1.2.20 of mod_jk.

JkMount

A mount point from a context to a Tomcat worker.
This directive is allowed multiple times. It is allowed in the global configuration and in VirtualHost.
You can also use it inside Location with a different syntax. Inside Location, one omits the first argument (path), which gets inherited verbatim from the Location argument. Whereas <Location /myapp> matches any URI beginning with "/myapp", any JkMount nested in such a Location block will only match for requests with exact URI /myapp. Therefore nesting JkMount in Location is typically not the right thing to do.
By default JkMount entries are not inherited from the global server to other VirtualHosts or between VirtualHosts. For the complete inheritance rules, see: JkMountCopy.
You might append rule extensions to the worker name. The extensions are separated from the worker name by a semicolon ";" using the same syntax as in the uriworkermap.properties file.

JkUnMount

An exclusion mount point from a context to a Tomcat worker. All exclusion mounts are checked after mapping a request to a tomcat worker. If the request maps also to an exclusion, it will not be forwarded to tomcat, and instead be served locally.
This directive is allowed multiple times. It is allowed in the global configuration and in VirtualHost.
You can also use it inside Location with a different syntax. Inside Location, one omits the first argument (path), which gets inherited verbatim from the Location argument. Whereas <Location /myapp> matches any URI beginning with "/myapp", any JkUnMount nested in such a Location block will only match for requests with exact URI /myapp. Therefore nesting JkUnMount in Location is typically not the right thing to do.
For inheritance rules, see: JkMountCopy.
This directive is available in jk1.2.7 version and later.

JkAutoAlias

Automatically Alias webapp context directories into the Apache document space.
Care should be taken to ensure that only static content is served via httpd as a result of using this directive. Any static content served by httpd will bypass any security constraints defined in the application's web.xml.
For inheritance rules, see: JkMountCopy.
There is no default value.

JkMountCopy

If this directive is set to "On" in some virtual server, the mounts from the global server will be copied to this virtual server, more precisely all mounts defined by JkMount or JkUnMount. The Mounts defined by JkMountFile and JkAutoAlias will only be inherited, if the VirtualHost does not define it's own JkMountFile or JkAutoAlias.
If you want all vhost to inherit mounts from the main server, you can set JkMountCopy to 'All' in the main server.
This directive is only allowed inside VirtualHost (with value "On") and in the global server (with value "All").
The default is Off, so no mounts will be inherited from the global server to any VirtualHost.
Starting with version 1.2.26 you can also set it to "All" in the global virtual server. This will switch the default to On.

JkWorkerIndicator

Name of the Apache environment variable that can be used to set worker names in combination with SetHandler jakarta-servlet.
This directive is only allowed once per virtual server. It is allowed in the global configuration and in VirtualHost.
The default value is JK_WORKER_NAME.

JkWatchdogInterval

This directive configures the watchdog thread interval in seconds. The workers are maintained periodically by a background thread running periodically every watchdog_interval seconds. Worker maintenance checks for idle connections, corrects load status and is able to detect backend health status.
The maintenance only happens, if since the last maintenance at least worker.maintain seconds have passed. So setting the JkWatchdogInterval much smaller than worker.maintain is not useful.
The default value is 0 seconds, meaning the watchdog thread will not be created, and the maintenance is done in combination with normal requests instead.
This directive is only allowed once. It must be put into the global part of the configuration.
This directive has been added in version 1.2.27 of mod_jk. It is available only for httpd 2.x and above using APR libraries including thread support.

JkLogFile

Full or server relative path to the mod_jk log file. It will also work with pipe, by using a value of the form "| ...".
The default value is logs/mod_jk.log.
Pipes are supported for Apache 1.3 only since version 1.2.16. The default value exists only since version 1.2.20.

JkLogLevel

The mod_jk log level, can be debug, info, warn error or trace.
The default value is info.

JkLogStampFormat

The mod_jk date log format, using an extended strftime syntax. This format will be used for the time stamps in the JkLogFile. The maximum length of the format is 63 characters.
Starting with version 1.2.24 of mod_jk you can also use %Q for adding milliseconds to the log and %q for microseconds. These conversion specifiers are an extension to strftime. They will only work on platforms with a gettimeofday() function. You can use %Q and %q only once in the pattern and also not both together in the same pattern.
The default value is "[%a %b %d %H:%M:%S %Y] " and beginning with version 1.2.24 on platforms with a gettimeofday() function it is "[%a %b %d %H:%M:%S.%Q %Y] ".

JkRequestLogFormat

Request log format string. See detailed description below.
There is no default value. Without defining a value, the request logging is turned off.

JkExtractSSL

Turns on SSL processing and information gathering by mod_jk
The default value is On.
In order to make SSL data available for mod_jk in Apache, you need to set SSLOptions +StdEnvVars. For the certificate information you also need to add SSLOptions +ExportCertData.

Specifically, mod_jk will export the following environment variables from Apache httpd to Tomcat under these request attributes as per the Servlet Specification 3.0, section 3.8:

Env VarRequest Attribute NameTypeExample
SSL_CIPHER
(or JkKEYSIZEIndicator)
javax.servlet.request.cipher_suite java.lang.String DHE-RSA-AES256-SHA
SSL_CIPHER_USEKEYSIZE
(or JkKEYSIZEIndicator)
javax.servlet.request.key_size java.lang.Integer 256
SSL_SESSION_ID
(or JkSESSIONIndicator)
javax.servlet.request.ssl_session java.lang.String 905...32E (a hex string)
SSL_CLIENT_CERT_CHAIN_n
(or JkCERTCHAINPrefixn)
javax.servlet.request.X509Certificate java.security.X509Certificate[] (A chain of certs in ascending order of trust, the first one being ths client's certificate, the second being the signer of that certificate, and so on)

In addition mod_jk sends the name of the SSL protocol used as a proprietary request attribute named AJP_SSL_PROTOCOL. Modern Tomcat versions will expose this attribute under the name org.apache.tomcat.util.net.secure_protocol_version. This feature has been added in version 1.2.41 of mod_jk. See also JkSSLPROTOCOLIndicator.

For all other SSL-related variables, use JkEnvVar for each variable you want. Please note that, like JkEnvVar, these variables are available from the request attributes, not as environment variables or as request headers.

JkHTTPSIndicator

Name of the Apache environment variable that contains SSL indication.
The default value is "HTTPS".

JkSSLPROTOCOLIndicator

Name of the Apache environment variable that contains the SSL protocol name.
The default value is "SSL_PROTOCOL".
This directive has been added in version 1.2.41 of mod_jk.

JkCERTSIndicator

Name of the Apache environment variable that contains SSL client certificates.
The default value is "SSL_CLIENT_CERT".

JkCIPHERIndicator

Name of the Apache environment variable that contains SSL client cipher.
The default value is "SSL_CIPHER".

JkCERTCHAINPrefix

Name of the Apache environment (prefix) that contains SSL client chain certificates.
The default value is "SSL_CLIENT_CERT_CHAIN_".

JkSESSIONIndicator

Name of the Apache environment variable that contains SSL session.
The default value is "SSL_SESSION_ID".

JkKEYSIZEIndicator

Name of the Apache environment variable that contains SSL key size in use.
The default value is "SSL_CIPHER_USEKEYSIZE".

JkLocalNameIndicator

Name of the Apache environment variable which can be used to overwrite the forwarded local name. Use this only if you need to adjust the data (see the proxy documentation).
The default value is "JK_LOCAL_NAME".
This directive has been added in version 1.2.28 of mod_jk.

JkIgnoreCLIndicator

Name of the Apache environment variable which forces to ignore an existing Content-Length request header. This can be used to make mod_jk conpatible with mod_deflate request body inflation (see below).
The default value is "JK_IGNORE_CL".
This directive has been added in version 1.2.41 of mod_jk.

JkLocalAddrIndicator

Name of the Apache environment variable which can be used to overwrite the forwarded local IP address. Use this only if you need to adjust the data (see the proxy documentation).
The default value is "JK_LOCAL_ADDR".
This directive has been added in version 1.2.41 of mod_jk.

JkLocalPortIndicator

Name of the Apache environment variable which can be used to overwrite the forwarded local port. Use this only if you need to adjust the data (see the proxy documentation).
The default value is "JK_LOCAL_PORT".
This directive has been added in version 1.2.28 of mod_jk.

JkRemoteHostIndicator

Name of the Apache environment variable which can be used to overwrite the forwarded remote (client) host name. Use this only if you need to adjust the data (see the proxy documentation).
The default value is "JK_REMOTE_HOST".
This directive has been added in version 1.2.28 of mod_jk.

JkRemoteAddrIndicator

Name of the Apache environment variable which can be used to overwrite the forwarded remote (client) IP address. Use this only if you need to adjust the data (see the proxy documentation).
The default value is "JK_REMOTE_ADDR".
This directive has been added in version 1.2.28 of mod_jk.

JkRemotePortIndicator

Name of the Apache environment variable which can be used to overwrite the forwarded remote (client) IP address. Use this only if you need to adjust the data (see the proxy documentation).
The default value is "JK_REMOTE_PORT".
This directive has been added in version 1.2.32 of mod_jk.

JkRemoteUserIndicator

Name of the Apache environment variable which can be used to overwrite the forwarded user name. Use this only if you need to adjust the data (see the proxy documentation).
The default value is "JK_REMOTE_USER".
This directive has been added in version 1.2.28 of mod_jk.

JkAuthTypeIndicator

Name of the Apache environment variable which can be used to overwrite the forwarded authentication type. Use this only if you need to adjust the data (see the proxy documentation).
The default value is "JK_AUTH_TYPE".
This directive has been added in version 1.2.28 of mod_jk.

JkOptions

Set one of more options to configure the mod_jk module. See below for details about this directive.
This directive can be used multiple times per virtual server.
The default value is "ForwardURIProxy" since version 1.2.24. It was "ForwardURICompatUnparsed" in version 1.2.23 and "ForwardURICompat" until version 1.2.22.

JkEnvVar

Adds a name and an optional default value of environment variable that should be sent to servlet-engine as a request attribute. If the default value is not given explicitly, the variable will only be send, if it is set during runtime.
The default is empty, so no additional variables will be sent.
This directive can be used multiple times per virtual server. The settings will be merged between the global server and any virtual server.
You can retrieve the variables on Tomcat as request attributes via request.getAttribute(attributeName). Note that the variables send via JkEnvVar will not be listed in request.getAttributeNames().
Empty default values are supported since version 1.2.20. Not sending variables with empty defaults and empty runtime value has been introduced in version 1.2.21.

JkStripSession

If this directive is set to On in some virtual server, the session IDs ;jsessionid=... will be removed for URLs which are not forwarded but instead are handled by the local server.
This directive is only allowed inside VirtualHost.
The default is Off.
This directive has been introduced in version 1.2.21.
With version 1.2.27 and later this directive can have optional session ID identifier. If not specified it defaults to ;jsessionid.

Configuration Directives Types

We'll discuss here the mod_jk directive types.

Define workers

JkWorkersFile specify the location where mod_jk will find the workers definitions. Take a look at Workers documentation for detailed description.

  JkWorkersFile     /etc/httpd/conf/workers.properties


Logging

JkLogFile specify the location where mod_jk is going to place its log file.

  JkLogFile     /var/log/httpd/mod_jk.log

Since JK 1.2.3 for Apache 2.x and JK 1.2.16 for Apache 1.3 this can also be used for piped logging:

  JkLogFile     "|/usr/bin/rotatelogs /var/log/httpd/mod_jk.log 86400"

JkLogLevel set the log level between :

  • info log will contain standard mod_jk activity (default).
  • warn log will contain non fatal error reports.
  • error log will contain also error reports.
  • debug log will contain all information on mod_jk activity
  • trace log will contain all tracing information on mod_jk activity
  
  JkLogLevel    info

info should be your default selection for normal operations.

JkLogStampFormat will configure the date/time format found on mod_jk log file. See above for details.

  JkLogStampFormat "[%Y-%m-%d %H:%M:%S.%Q] "



You can log mod_jk information using the Apache standard module mod_log_config. The module sets several notes in the Apache httpd notes table. Most of them are are only useful in combination with a load balancer worker.

NoteDescription
JK_WORKER_NAMEName of the worker selected by the URI mapping
JK_WORKER_TYPEType of the worker selected by the URI mapping
JK_WORKER_ROUTEActual worker name selected by the URI mapping (usually a member of the load balancer).
Before version 1.2.26 only available if JkRequestLogFormat is set.
JK_REQUEST_DURATIONRequest duration in seconds and microseconds.
Before version 1.2.26 only available if JkRequestLogFormat is set.
JK_LB_FIRST_NAMELoad-Balancer: Name of the first worker tried
JK_LB_FIRST_TYPELoad-Balancer: Type of the first worker tried
JK_LB_FIRST_ACCESSEDLoad-Balancer: Access count for the first worker tried
JK_LB_FIRST_SESSIONSLoad-Balancer: Count of created sessions for the first worker tried
JK_LB_FIRST_READLoad-Balancer: Bytes read for the first worker tried
JK_LB_FIRST_TRANSFERREDLoad-Balancer: Bytes transferred for the first worker tried
JK_LB_FIRST_ERRORSLoad-Balancer: Error count for the first worker tried
JK_LB_FIRST_BUSYLoad-Balancer: Busy count for the first worker tried
JK_LB_FIRST_ACTIVATIONLoad-Balancer: Activation state for the first worker tried
JK_LB_FIRST_STATELoad-Balancer: Error state for the first worker tried
JK_LB_LAST_NAMELoad-Balancer: Name of the last worker tried
JK_LB_LAST_TYPELoad-Balancer: Type of the last worker tried
JK_LB_LAST_ACCESSEDLoad-Balancer: Access count for the last worker tried
JK_LB_LAST_SESSIONSLoad-Balancer: Count of created sessions for the last worker tried
JK_LB_LAST_READLoad-Balancer: Bytes read for the last worker tried
JK_LB_LAST_TRANSFERREDLoad-Balancer: Bytes transferred for the last worker tried
JK_LB_LAST_ERRORSLoad-Balancer: Error count for the last worker tried
JK_LB_LAST_BUSYLoad-Balancer: Busy count for the last worker tried
JK_LB_LAST_ACTIVATIONLoad-Balancer: Activation state for the last worker tried
JK_LB_LAST_STATELoad-Balancer: Error state for the last worker tried

  LogFormat     "%h %l %u %t \"%r\" %>s %b %{JK_WORKER_NAME}n %{JK_LB_FIRST_NAME}n \
                 %{JK_LB_FIRST_BUSY}n %{JK_LB_LAST_NAME}n %{JK_LB_LAST_BUSY}n" mod_jk_log
  CustomLog     logs/access_log     mod_jk_log


You can also log a request protocol in the mod_jk log file instead of the access log. This is not recommended and mostly a backward compatibility feature. The directive JkRequestLogFormat will configure the format of this protocol. It gets configured and enabled on a per virtual host basis. To enable request logging for a virtual host just add a JkRequestLogFormat config. The syntax of the format string is similar to the Apache LogFormat command, here is a list of the available request log format options:

OptionsDescription
%bBytes sent, excluding HTTP headers (CLF format)
%BBytes sent, excluding HTTP headers
%HThe request protocol
%mThe request method
%pThe canonical Port of the server serving the request
%qThe query string (prepended with a ? if a query string exists, otherwise an empty string)
%rFirst line of request
%sRequest HTTP status code
%TRequest duration, elapsed time to handle request in seconds '.' micro seconds
%UThe URL path requested, not including any query string.
%vThe canonical ServerName of the server serving the request
%VThe server name according to the UseCanonicalName setting
%wTomcat worker name
%RReal worker name

  JkRequestLogFormat     "%w %V %T"


Forwarding

The directive JkOptions allow you to set many forwarding options which will enable (+) or disable (-) following option. Without any leading signs, options will be enabled.

The four following options +ForwardURIxxx are mutually exclusive. Exactly one of them is required, a negative sign prefix is not allowed with them. The default value is "ForwardURIProxy" since version 1.2.24. It was "ForwardURICompatUnparsed" in version 1.2.23 and "ForwardURICompat" until version 1.2.22. You can turn the default off by switching on one of the other two options. You should leave this at it's default value, unless you have a very good reason to change it.

All options are inherited from the global server to virtual hosts. Options that support enabling (plus options) and disabling (minus options), are inherited in the following way:

options(vhost) = plus_options(global) - minus_options(global) + plus_options(vhost) - minus_options(vhost)

Using JkOptions ForwardURIProxy, the forwarded URI will be partially reencoded after processing inside Apache httpd and before forwarding to Tomcat. This will be compatible with local URL manipulation by mod_rewrite and with URL encoded session ids.

  JkOptions     +ForwardURIProxy


Using JkOptions ForwardURICompatUnparsed, the forwarded URI will be unparsed. It's spec compliant and secure. It will always forward the original request URI, so rewriting URIs with mod_rewrite and then forwarding the rewritten URI will not work.

  JkOptions     +ForwardURICompatUnparsed


Using JkOptions ForwardURICompat, the forwarded URI will be decoded by Apache httpd. Encoded characters will be decoded and explicit path components like ".." will already be resolved. This is less spec compliant and is not safe if you are using prefix JkMount. This option will allow to rewrite URIs with mod_rewrite before forwarding.

  JkOptions     +ForwardURICompat


Using JkOptions ForwardURIEscaped, the forwarded URI will be the encoded form of the URI used by ForwardURICompat. Explicit path components like ".." will already be resolved. This will not work in combination with URL encoded session IDs, but it will allow to rewrite URIs with mod_rewrite before forwarding.

  JkOptions     +ForwardURIEscaped


JkOptions RejectUnsafeURI will block all URLs, which contain percent signs '%' or backslashes '\' after decoding.

Most web apps do not use such URLs. Using the option RejectUnsafeURI, you can block several well known URL encoding attacks. By default, this option is not set.

You can also realise such a check with mod_rewrite, which is more powerful but also slightly more complicated.

  
  JkOptions     +RejectUnsafeURI


JkOptions CollapseSlashesAll will collapse multiple adjacent slashes in request URLs before looking for mount or unmount matches.

  JkOptions     +CollapseSlashesAll


JkOptions CollapseSlashesUnmount will collapse multiple adjacent slashes in request URLs only before looking for unmount matches. This is the default value.

  JkOptions     +CollapseSlashesUnmount


JkOptions CollapseSlashesNone will never collapse multiple adjacent slashes in request URLs before looking for mount or unmount matches. Using this value might make you vulnerable for attacks bypassing your unmount rules.

  JkOptions     +CollapseSlashesNone


JkOptions ForwardDirectories is used in conjunction with DirectoryIndex directive of Apache web server. As such mod_dir should be available to Apache, statically or dynamically (DSO)

When DirectoryIndex is configured, Apache will create sub-requests for each of the local-url's specified in the directive, to determine if there is a local file that matches (this is done by stat-ing the file).

If ForwardDirectories is set to false (default) and Apache doesn't find any files that match, Apache will serve the content of the directory (if directive Options specifies Indexes for that directory) or a 403 Forbidden response (if directive Options doesn't specify Indexes for that directory).

If ForwardDirectories is set to true and Apache doesn't find any files that match, the request will be forwarded to Tomcat for resolution. This is used in cases when Apache cannot see the index files on the file system for various reasons: Tomcat is running on a different machine, the JSP file has been precompiled etc.

Note that locally visible files will take precedence over the ones visible only to Tomcat (i.e. if Apache can see the file, that's the one that's going to get served). This is important if there is more then one type of file that Tomcat normally serves - for instance Velocity pages and JSP pages.

  
  JkOptions     +ForwardDirectories


Setting JkOptions ForwardLocalAddress, you ask mod_jk to send the local address, of the Apache web server instead remote client address. This can be used by Tomcat remote address valve for allowing connections only from registered Apache web servers.

  
  JkOptions     +ForwardLocalAddress


Setting JkOptions ForwardPhysicalAddress, you ask mod_jk to send the physical peer TCP IP address as the client address. By default mod_jk uses the logical address as provided by the web server. For example the module mod_remoteip sets the logical IP address to the client IP forwarded by proxies in the X-Forwarded-For header.

  
  JkOptions     +ForwardPhysicalAddress


JkOptions FlushPackets, you ask mod_jk to flush Apache's connection buffer after each AJP packet chunk received from Tomcat. This option can have a strong performance penalty for Apache and Tomcat as writes are performed more often than would normally be required (ie: at the end of each response).

  
  JkOptions     +FlushPackets


JkOptions FlushHeader, you ask mod_jk to flush Apache's connection buffer after the response headers have been received from Tomcat.

  
  JkOptions     +FlushHeader


JkOptions DisableReuse, you ask mod_jk to close connections immediately after their use. Normally mod_jk uses persistent connections and pools idle connections to reuse them, when new requests have to be sent to Tomcat.

Using this option will have a strong performance penalty for Apache and Tomcat. Use this only as a last resort in case of unfixable network problems. If a firewall between Apache and Tomcat silently kills idle connections, try to use the worker attribute socket_keepalive in combination with an appropriate TCP keepalive value in your OS.

  
  JkOptions     +DisableReuse


JkOptions ForwardKeySize, you ask mod_jk, when using ajp13, to forward also the SSL Key Size as required by Servlet API 2.3. This flag shouldn't be set when servlet engine is Tomcat 3.2.x (on by default).

  
  JkOptions     +ForwardKeySize


JkOptions ForwardSSLCertChain, you ask mod_jk, when using ajp13, to forward SSL certificate chain (off by default). Mod_jk only passes the SSL_CLIENT_CERT to the AJP connector. This is not a problem with self-signed certificates or certificates directly signed by the root CA certificate. However, there's a large number of certificates signed by an intermediate CA certificate, where this is a significant problem: A servlet will not have the possibility to validate the client certificate on its own. The bug would be fixed by passing on the SSL_CLIENT_CERT_CHAIN to Tomcat via the AJP connector.
This directive exists only since version 1.2.22.

  
  JkOptions     +ForwardSSLCertChain


The directive JkEnvVar allows you to forward environment variables from Apache server to Tomcat engine. You can add a default value as a second parameter to the directive. If the default value is not given explicitly, the variable will only be send, if it is set during runtime.
The variables can be retrieved on the Tomcat side as request attributes via request.getAttribute(attributeName). Note that the variables send via JkEnvVar will not be listed in request.getAttributeNames().

The variables are inherited from the global server to virtual hosts.

  
  JkEnvVar     SSL_CLIENT_V_START     undefined


Assigning URLs to Tomcat

If you have created a custom or local version of mod_jk.conf-local as noted above, you can change settings such as the workers or URL prefix.

JkMount directive assign specific URLs to Tomcat. In general the structure of a JkMount directive is:

  
  JkMount [URL prefix] [Worker name]
  # send all requests ending in .jsp to worker1
  JkMount /*.jsp worker1
  # send all requests ending /servlet to worker1
  JkMount /*/servlet/ worker1
  # send all requests jsp requests to files located in /otherworker will go worker2
  JkMount /otherworker/*.jsp worker2

You can use the JkMount directive at the top level or inside <VirtualHost> sections of your httpd.conf file.

JkUnMount directive acts as an opposite to JkMount and blocks access to a particular URL. The purpose is to be able to filter out the particular content types from mounted context. The following example mounts /servlet/* context, but all .gif files that belongs to that context are not served.

  # send all requests ending with /servlet to worker1
  JkMount /servlet/* worker1
  # do not send requests ending with .gif to worker1
  JkUnMount /servlet/*.gif worker1

JkUnMount takes precedence over JkMount directives, meaning that the JK will first try to mount and then checks, if there is an exclusion defined by a JkUnMount. A JkUnMount overrides a JkMount only, if the worker names in the JkMount and in the JkUnMount are the same.

The following example will block all .gif files although there is a JkMount for them:

  # do not send requests ending with .gif to worker1
  JkUnMount /*.gif worker1
  # The .gif files will not be mounted cause JkUnMount takes
  # precedence over JkMount directive
  JkMount /servlet/*.gif worker1

Starting with version 1.2.26 of JK you can apply a JkUnMount to any worker, by using the star character '*' as the worker name in the JkUnMount. More complex patterns in JkUnMount worker names are not allowed.

  # Mapping the webapps myapp1 and myapp2:
  /myapp1/*=worker1
  /myapp2/*=worker2
  # Exclude the all subdirectories static for all workers:
  !/*/static/*=*
  # Exclude some suffixes for all workers:
  !*.html=*

JkAutoAlias directive automatically Alias webapp context directories into the Apache document space. It enables Apache to serve a static context while Tomcat serving dynamic context. This directive is used for convenience so that you don't have to put an apache Alias directive for each application directory inside Tomcat's webapp directory. For security reasons it is strongly recommended that JkMount is used to pass all requests to Tomcat by default and JkUnMount is used to explicitly exclude static content to be served by httpd. It should also be noted that content served by httpd will bypass any security constraints defined in the application's web.xml.

  # enter the full path to the tomcat webapps directory
  JkAutoAlias /opt/tomtact/webapps

The following example shows how to serve a dynamic context by Tomcat and static using Apache. The webapps directory has to be accessible by apache.

  # enter the full path to the tomcat webapps directory
  JkAutoAlias /opt/tomtact/webapps

  # Mount 'servlets-examples' directory. It's physical location
  # is assumed to be in the /opt/tomtact/webapps/servlets-examples
  # ajp13w is a worker defined in the workers.properties
  JkMount /servlets-examples/* ajp13w

  # Unmount desired static content from servlets-examples webapp.
  # This content will be served by the httpd directly.
  JkUnMount /servlets-examples/*.gif ajp13w
  JkUnMount /servlets-examples/*.jpg ajp13w

Note that you can have a single JkAutoAlias directive per virtual host inside your httpd.conf

JkWorkerProperty is a new directive available from JK 1.2.7 version. It is a convenient method for setting directives that are usually set inside workers.propeties file. The parameter for that directive is raw line from workers.properties file.

  # Just like workers.properties but exact line is prefixed
  # with JkWorkerProperty

  # Minimal jk configuration
  JkWorkerProperty worker.list=ajp13w
  JkWorkerProperty worker.ajp13w.type=ajp13
  JkWorkerProperty worker.ajp13w.host=localhost
  JkWorkerProperty worker.ajp13w.port=8009   

JkMountFile is a new directive available from JK 1.2.9 version. It is used for dynamic updates of mount points at runtime. When the mount file is changed, JK will reload it's content.

  # Load mount points

  JkMountFile conf/uriworkermap.properties

If the mount point uri starts with an exclamation mark '!' it defines an exclusion in the same way JkUnMount does. If the mount point uri starts with minus sign '-' the mount point will only be disabled. A disabled mount can be reenabled by deleting the minus sign and waiting for the JkMountFile to reload. An exclusion can be disabled by prefixing it with a minus sign.

  # Sample uriworkermap.properties file

  /servlets-examples/*=ajp13w
  # Do not map .jpeg files
  !/servlets-examples/*.jpeg=ajp13w
  # Make jsp examples initially disabled  
  -/jsp-examples/*=ajp13w

At run time you can change the content of this file. For example removing minus signs will enable the previously disabled uri mappings. You can add any number of new entries at runtime that reflects the newly deployed applications. Apache will reload the file and update the mount points within 60 second interval.

There is no way to delete entries by dynamic reloading, but you can disable or exclude mappings.

Using SetHandler and Environment Variables

Alternatively to the mod_jk specific directives, you can also use SetHandler and environment variables to control, which requests are being forwarded via which worker. This gives you more flexibility, but the results might be more difficult to understand. If you mix both ways of defining the forwards, in general to mod_jk directives will win.

SetHandler jakarta-servlet forces requests to be handled by mod_jk. If you neither specify any workers via JkMount and the related directives, not via the environment variable described below, the first worker in the list of all worker will be chosen. You can use SetHandler for example in Location blocks or with Apache 2.2 and later also in RewriteRule.

In order to control the worker using SetEnvIf or RewriteRule for more complex rules, you can set the environment variable JK_WORKER_NAME to the name of your chosen target worker. This enables you to decide on the chosen worker in a more flexible way, including dependencies on cookie values. This feature has been added in version 1.2.19 of mod_jk. Furthermore you might append rule extensions to the worker name. The extensions are separated from the worker name by a semicolon ";" using the same syntax as in the uriworkermap.properties file. Supporting rule extensions in the worker name has been added in version 1.2.33.

In order to use another variable than JK_WORKER_NAME, you can set the name of this variable via the JkWorkerIndicator directive.

You can also define exclusions from mod_jk forwards by setting the environment variable no-jk.

  # Automatically map all encoded urls
  <Location *;jsessionid=>
    SetHandler jakarta-servlet
    SetEnv JK_WORKER_NAME my_worker
  </Location>

  # Map all subdirs to workers via naming rule
  # and exclude static content.
  <Location /apps/>
    SetHandler jakarta-servlet
    SetEnvIf REQUEST_URI ^/apps/([^/]*)/ JK_WORKER_NAME=$1
    SetEnvIf REQUEST_URI ^/apps/([^/]*)/static no-jk
  </Location>
Advanced Environment Variables

Environment variables allow to overwrite the default behaviour of mod_jk depending on request properties like e.g. the request URI, header values or cookie. This can be done using the SetEnvIf or RewriteRule directives.

The environment variable JK_ROUTE can be set to explicitely choose a member of a load balancer worker. The value must be equal to the route attribute of the member, or if that attribute is not used, equal to the member name. Note that this is only needed if session IDs and routes are encoded in a non standard way in the request. Stickyness using the Java Servlet compliant way of encoding the IDs is supported by default. This is available since version 1.2.33.

The environment variable JK_REPLY_TIMEOUT can be set to dynamically define a reply timeout. The value must be given in milliseconds. This is available since version 1.2.27.

The environment variable JK_STICKY_IGNORE can be set to disable session stickyness for individual requests. If the variable is set to an empty string or a nonzero number, session stickyness will be disabled. Setting it to 0 will reset to the behaviour defined by the worker configuration. This is available since version 1.2.33.

This feature can be useful to optimize load balancing when using cookie based session stickyness. In this case, as long as she keeps her browser open, any request by a user who started a session will be send to the same Tomcat instance, even if he left the part of the application which uses the session. You can for instance set this environment variable when a user requests a login form to ensure, that this initial session request is balanced non-sticky.

The environment variable JK_STATELESS can be used to improve load balancing for the session based balancing methods Session and Next. In this case normally any request which does not come with a session id counts as a new session. This can be problematic, if for instance static content is retrieved without a session id. If you set the environment variable JK_STATELESS for a request, then the request will not count as a new session, even if it does not come with a session id. This is available since version 1.2.33.

The environment variable JK_IGNORE_CL can be set to force ignoring the request Content-Length header (if it exists). mod_jk will then stream the request body until the web server indicates that the full body was read. No Content-Length header will be send to the backend. This is available since version 1.2.41.

This feature can be used to make mod_jk compatible with filters which change the size of the request body. One such filter is mod_deflate when used to inflate the body of a request with gzip encoded body. In this case mod_jk will by default forward a truncated body, because it gets the wrong body size from the web server. Telling mod_jk to ignore the Content-Length header will result in streaming all request body data it can read from the web server to the backend.

You should only set the JK_IGNORE_CL environment variables for requests that actually need it. Unfortunately there's no way for mod_jk to detect the need automatically.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/reference/status.html0000644000000000000020000007340212555256554021436 0ustar rootbinThe Apache Tomcat Connectors - Reference Guide - Status Worker Reference
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Reference Guide

Status Worker Reference

Printer Friendly Version
print-friendly
version
Introduction

Tomcat Connectors has a special type of worker, the so-called status worker. The status worker does not forward requests to Tomcat instances. Instead it allows to retrieve status and configuration information at runtime, and furthermore to change many configuration items dynamically. This can be done via a simple embedded web interface.

The status worker is especially powerful, when used together with load balancing workers.

This document does not explain the HTML user interface of the status worker. Until now it is very simple, so just go ahead and use it. This doc instead tries to explain the less obvious features of the status worker. We also will give a complete coverage of the various request parameters and their meaning, so that you can include the status worker in your automation scripts.

The documentation of the status worker starts with jk 1.2.20

Usage Patterns

Actions

The status worker knows about the following actions:

  • list: lists the configurations and runtime information of all configured workers. The output will be grouped by global information first (version data), then load balancer information, after that AJP worker information and finally the legend. For load balancers, there will be a summary part, and after that details for each member worker. For all workers, we also include the URL mappings (forward definitions).
  • show: the same as list, but only shows data for one chosen worker
  • edit: produces a form to edit configuration data for a chosen worker. There is a special subtype of "edit", that makes it easy to change one attribute for all members of a load balancer, e.g. their activation state.
  • update: commit changes made in an edit form. Caution: the changes will not be persisted to the configuration files. As soon as your restart your web server, all changes made through the status worker will be lost! On the other hand, the changes done by the status worker will be applied during runtime without a restart of the web server.
  • reset: reset all runtime statistics for a worker.
  • recover: Mark a member of a load balancer, that is in error state, for immediate recovery.
  • version: only show version information of the web server and the JK software
  • dump: list the original workers configuration. Caution: the dump will only contain the configuration that was used during startup. Any changes applied later by the dynamic management interface of the status worker itself will not be contained in this dump. The dump action has been added in version 1.2.27.

Output Format

For most actions you can choose between 4 output formats.

  • HTML: Used interactively with a browser
  • XML: Mostly useful for automation, when your scripting environment is XML friendly. This format has rich structure information, but does not work line based, so you would really like to use it together with XML tools.
  • Properties: This format is a line based format, that conforms to the rules of Java property files. Most structure information is contained in the hierarchical key. For information, that is of configuration nature, the format should produce lines very similar to the ones you can use in workers.properties. It will not produce a complete configuration file!
  • Text: A simple textual output format.
The "edit" action does only make sense for the HTML output type.

User Interface Features

In the HTML view, there is an automatic refresh feature, implemented via the meta refresh option of HTML. Once you start the automatic refresh, the UI will will respect it for all actions except edit, update and maintain. Even if you navigate through one of those, the automatic refresh will start again as soon as you come back to one of the other actions.

Many parts of the HTML page can be minimised, if they are not interesting for you. There are a couple of "Hide" links, which will collapse parts of the information. The feature exists for the following blocks of information:

  • Legend: Do not show the legend for the information presented in "list" and "show" actions
  • URI mappings: Do not show the URI mapping for the workers
  • Load Balancing Workers: Do not show workers of type "lb"
  • AJP Workers: Do not show workers of type ajp
  • Balancer Members: Do not show detailed information concerning each member of load balancers
  • Load Balancer Configuration: Do not show configuration data for load balancers
  • Load Balancer Summary: Do not show status summary for load balancers
  • AJP Configuration: Do not show configuration data for ajp workers load balancer members
The last three minimisation features have been added in version 1.2.27.

Special Considerations concerning URL Maps and Virtual Hosts

Note: The following restriction has been removed starting with version 1.2.26.

The Apache module mod_jk makes use of the internal Apache httpd infrastructure concerning virtual hosts. The downside of this is, that the status worker can only show URL maps, for the virtual host it is defined in. It is not able to reach the configuration objects for other virtual hosts. Of course you can define a status worker in any virtual host you are using. All information presented apart from the URL maps will be the same, independent of the virtual host the status worker has been called in.

Logging

The status worker will log changes made to the configuration with log level "info" to the usual JK log file. Invalid requests will be logged with log level "warn". If you want to report some broken behaviour, log file content of level "debug" or even "trace" will be useful.

Configuration

Basic Configuration

The basic configuration of a status worker is very similar to that of a usual ajp worker. You need to specify a name for the worker, and the URLs you want to map to it. The first part of the configuration happens in the workers.properties file. We define a worker named mystatus of type status:

worker.list=mystatus
worker.mystatus.type=status
Then we define a URL, which should be mapped to this worker, i.e. the URL we use to reach the functionality of the status worker. You can use any method mod_jk supports for the web server of your choice. Possibilities are maps inside uriworkermap.properties, an additional mount attribute in workers.properties, or in Apache JkMount. Here's an example for a uriworkermap.properties line:
/private/admin/mystatus=mystatus
The URI pattern is case sensitive.

As you will learn in the following sections, the status worker is very powerful. You should use the usual authentication and authorisation methods of your web server to secure this URL.

You can also define multiple instances of the status worker, by using different names and URL mappings. For instance you might want to configure them individually and then allow special groups of people to use them

Output Customisation

There are a couple of attributes for the workers.properties entries, which allow to customise various aspects of the output of the status worker.

The attribute css can be set to the URL of a stylesheet:

worker.mystatus.css=/private/admin/static/mystatus.css
When writing HTML output, the status worker then includes the line
<link rel="stylesheet" type="text/css" href="/private/admin/static/mystatus.css" />
There is no sample stylesheet included with the mod_jk release, and by default the attribute css is empty, so no stylesheet reference will be included in the pages. The HTML code of the status worker output pages does not include any class attributes. If you like to contribute a stylesheet or improvements to the HTML layout, please contact us on the tomcat developers list.

The properties output format can be customised via the attribute prefix. The names of all properties the status worker does output, will begin with this prefix. The default is "worker".

Several attributes influence the format when writing XML output. The attribute ns allows to set a namespace prefix, that will be used for every status worker+element. The default is "jk:". Setting it to "-" disables the namespace prefix.

With the attribute xmlns you can map the prefix to a namespace URL. The default value is xmlns:jk="http://tomcat.apache.org". Setting it to "-" disables the output of the URL.

Finally you can specify an XML document type via the attribute doctype. The specified string will be inserted at the beginning of the document, directly after the xml header. The default is empty.

Securing Access

We urge you to use the builtin access control features of your web server to control access to the status worker URLs you have chosen. Nevertheless two configuration attributes of status workers are helpful. The attribute "read_only" disables all features of the status worker, that can be used to change configurations or runtime status of the other workers. A read_only status worker will not allow access to the edit, update, reset or recover actions. The default value is false, ie. read/write. To enable read_only you need to set it to true.

You could configure two status workers, one has read_only and will be made available to a larger admin group, the other one will be used fully featured, but only by fewer people:

worker.list=jk-watch
worker.jk-watch.type=status
worker.jk-watch.read_only=true
worker.jk-watch.mount=/user/status/jk
worker.list=jk-manage
worker.jk-manage.type=status
worker.jk-manage.mount=/admin/status/jk
Starting with version 1.2.21, a read/write status worker can also be switched temporarily into read-only mode by the user via a link in the HTML GUI. The user can always switch it back to read/write. Only a status worker configured as read-only via the "read_only" attribute is completely safe from applying any changes.

The other attribute you can use is user. By default this list is empty, which means no limit on the users. You can set "user" to a comma separated list of user names. If your web server is configured such that it sends the user names with the request, the status worker will check, if the name attached with the request is contained in it's "user" list.

The user list can be split over multiple occurrences of the "user" attribute.

By default, the user names are matched case sensitively. Starting with version 1.2.21 you can set the attribute user_case_insensitive to true. Then the comparison will be made case insensitive.

Service Availability Rating

For load balancing workers the status worker shows some interesting overview information. It categorises the members of the load balancer into the classes "good", "bad" and degraded". This feature can be combined with external escalation procedures. Depending on your global system design and your operating practises your preferred categorisation might vary.

The categorisation is based on the activation state of the workers (active, disabled or stopped), which is a pure configuration state, and the runtime state (OK or ERR with possible substates idle, busy, recovering, probing, and forced recovery) which only depends on the runtime situation.

The runtime substates have the following meaning:

  • OK (idle): This worker didn't receive any request since the last balancer maintenance. By default balancer maintenance runs every 60 seconds. The worker should be OK, but since we didn't have to use it for some time, we can't be sure. This state has been called N/A before version 1.2.24.
  • OK (busy): All connections for this worker are in use for requests.
  • ERROR (recovering): The worker was in error state for some time and is now marked for recovery. The next request suitable for this worker will use it.
  • ERROR (probing): After setting the worker to recovering, we received a request suitable for this worker. This request is now using the worker.
  • ERROR (forced recovery): The worker is in error, but we don't have an alternative worker, so we keep using it.

By default the status worker groups into "good" all members, that have activation "active" and runtime state not equal to "error" with empty substate. The "bad" group consists of the members, that have either activation "stopped", or are in runtime state "error" with empty substate.

Workers that fit neither of the two groups, are considered to be "degraded".

You can define other rules for the grouping into good, bad and degraded. The two attributes "good" and "bad" can be populated by a comma-separated list ob single characters or dot-separated pairs. Each character stands for the first character of one of the possible states "active", "disabled", "stopped", "ok", "idle", "busy", "recovering" and "error". The additional states "probing" and "forced recovery" are always rated equivalent to "recovering". Comma-separated entries will be combined with logical "or", if you combine a configuration and a runtime state with a dot. the are combined with logical "and". So the default value for "good" is "a.o,a.i,a.b,a.r", for "bad" it is "e,s".

The status worker first tries to match against the "bad" definitions, if this doesn't succeed it tries to match against "good", and finally it chooses "degraded", if no "bad" or "good" match can be found.

Request Parameters

This section should help you building automation scripts based on the jk status management interface. This interface is stable in the sense, that we only expect to add further parameters in the future. Existing parameters from previous versions will keep their original semantics. We also expect the output formats XML, Properties and Text to be kept stable. So please use those, if you want to parse status worker output in your automation scripts.

Actions

The action is determined by the parameter cmd. It can have the values "list", "show", "edit", "update", "reset", "recover", "version" and "dump". If you omit the cmd parameter, the default "list" will be used. All actions except for "list", "refresh", "version" and "dump" need additional parameters.

The action "dump" has been added in version 1.2.27.

Output Format

The format is determined by the parameter mime. It can have the values "html", "xml", "txt" and "prop". If you omit the mime parameter, the default "html" will be used. The action "edit" (the edit form) does only make sense for "mime=html".

Worker Selection

Actions that operate on a single worker need one or two additional parameters to select this worker. The parameter w contains the name of the worker from the worker list. If an action operates on a member (sub worker) of a load balancer, the parameter w contains the name of the load balancer worker, and the additional parameter sw contains the name of the sub worker.

Automatic Refresh

During automatic refresh, the parameter re contain the refresh interval in seconds. If you omit this parameter, automatic refresh will be off.

Hide Options

The parameter opt contains a bit mask of activated options. The default is 0, so by default no options are activated. The following options exist:

  • 0x0001: hide members of lb workers
  • 0x0002: hide URL maps
  • 0x0004: hide the legend
  • 0x0008: hide load balancer workers
  • 0x0010: hide ajp workers
  • 0x0020: only allow read_only actions for a read/write status worker.
  • 0x0040: hide load balancer configuration
  • 0x0080: hide load balancer status summary
  • 0x0100: hide configuration for ajp and load balancer member workers
Values 0x0040-0x0100 have been added in version 1.2.27.

Data Parameters for the standard Update Action

You can use the edit action with a final click to the update button, to change settings of workers. But you can also make direct calls to the update action. The following request parameters contain the configuration information, you want to change. First the list for load balancer workers:

  • vlr: retries (number)
  • vlt: recover_time (seconds)
  • vlee: error_escalation_time (seconds)
  • vlx: max_reply_timeouts (number)
  • vls: sticky_session (0/f/n/off=off, 1/t/y/on=on; case insensitive)
  • vlf: sticky_session_force (0/f/n/off=off, 1/t/y/on=on; case insensitive)
  • vlm: method (0/r="Requests", 1/t="Traffic", 2/b="Busyness", 3/s="Sessions", 4/s="Next"; case insensitive, only first character is used)
  • vll: lock (0/o="Optimistic", 1/p="Pessimistic"; case insensitive, only first character is used)
And now the list of parameters you can use to change settings for load balancer members:
  • vwa: activation flag (0/a="active", 1/d="disabled", 2/s="stopped"; case insensitive, only first character is used)
  • vwf: load balancing factor (integer weight)
  • vwn: route for use with sticky sessions (string)
  • vwr: redirect to define simple failover rules (string)
  • vwc: domain to tell JK about your replication design (string)
  • vwd: distance to express preferences (integer)
Finally the list of parameters you can use to change settings for ajp workers and ajp load balancer members:
  • vahst: host (string)
  • vaprt: port (number)
  • vacpt: connection_pool_timeout (number)
  • vact: connect_timeout (number)
  • vapt: prepost_timeout (number)
  • vart: reply_timeout (number)
  • var: retries (number)
  • varo: recovery_options (number)
  • vabl: busy_limit (number)
  • vamps: max_packet_size (number)
Note that changing the host name or port will only take effect for new connections. Already established connections to the old address will still be used. Nevertheless this feature is interesting, because you can provision load balancer members with port "0", which will automatically be stopped during startup. Later when you know the final names and ports, you can set them and they will be automatically activated.

The leading character "v" has been added to the parameters in version 1.2.27. Changing settings for ajp workers has also been introduced in version 1.2.27.

For the details of all parameters, we refer to the workers.properties Reference.

Aspect Editing for Load Balancer Members

You can use the edit action to edit all settings for a load balancer or for a member of a load balancer respectively on one page. If you want to edit one configuration aspect for all members of a load balancer simultaneously, this will be triggered by the parameter att. The value of the parameter indicates, which aspect you want to edit. The list is the same as in the previous section, except for "vahst" and "vaprt": "vwa", "vwf", "vwn", "vwr", "vwc", "vwd", "vacpt", "vact", "vapt", "vart", "var", "varo", "vabl" and "vamps". But here you need to put the name into the parameter att, instead of using it as a request parameter name.

The values of the common aspect for all the load balancer members will be given in parameters named "val0", "val1", ....


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/reference/uriworkermap.html0000644000000000000020000006252312555256554022644 0ustar rootbinThe Apache Tomcat Connectors - Reference Guide - uriworkermap.properties configuration
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Reference Guide

uriworkermap.properties configuration

Printer Friendly Version
print-friendly
version
Introduction

The forwarding of requests from the web server to tomcat gets configured by defining mapping rules. Such a rule maps requests to workers. The request part of the map is described by a URI pattern, the worker by it's worker name.

The so-called uriworkermap file is a mechanism of defining rules, which works for all web servers. There exist also other web server specific configuration options for defining rules, which will be mostly discussed on the reference pages for configuring tomcat connectors for the individual web servers.

The name of the file is usually uriworkermap.properties, although this is configurable in the web server. Please consult the web server specific documentation pages on how to enable the uriworkermap file.

The main features supported by the uriworkermap file are

  • Support for comments in the rule file.
  • Exact and wildchar matches, shortcuts to map a directory and all including content.
  • Exclusion rules, disabling of rules and rule priorities.
  • Rule extensions, modifying worker behaviour per rule.
  • Virtual host integration: uri mapping rules can be expressed per virtual host. The details are web server specific though.
  • Dynamic reloading: The file gets checked periodically for changes. New versions are automatically reloaded without web server restarts.
  • Integration with the status worker.
The following sections describe these aspects in more detail.

Syntax

Line format

The file has a line based format. There are no continuation characters, so each rule needs to be defined on a single line. Each rule is a pair consisting of a URI pattern and a worker name, combined by an equals sign '=':

  /myapp=myworker
The URI pattern is case sensitive.

Comments, white space

All text after and including the character '#' gets ignored and can be used for comments. Leading and trailing white space gets trimmed around the URI pattern and also around the worker name. The following definitions are all equivalent:

  # This is a white space example
  /myapp=myworker
     /myapp=myworker
  /myapp  =  myworker

URI patterns

Inside the URI pattern three special characters can be used, '*', '?' and '|'. The character '*' is a wildchar that matches any number of arbitrary characters in the URI, '?' matches exactly one character. Each URI pattern has to start with the character '/', or with '*' or with '?', optionally prefixed by any combination of the modifiers '!' and '-' (see next section).

  # Mapping the URI /myapp1 and everything under /myapp1/:
  /myapp1=myworker-a
  /myapp1/*=myworker-a
  # Mapping all URI which end with a common suffix:
  *.jsp=myworker
  *.do=myworker
Since the first case of mapping a certain location and everything inside it is very common, the character '|' gives a handy shortcut:
  # Mapping the URI /myapp1 and everything under /myapp1/:
  /myapp1|/*=myworker-a
The pattern 'X|Y' is exactly equivalent to the two maps 'X' and 'XY'.

Exclusion, Disabling and Priorities

Exclusions and rule disabling

Exclusion rules allows to define exclusions from URI rules, which would forward requests to tomcat. If the exclusion rule matches, the request will not be forwarded. This is usually used to serve static content by the web server. A rule is an exclusion rule, if it is suffixed with '!':

  # Mapping the URI /myapp and everything under /myapp/:
  /myapp|/*=myworker
  # Exclude the subdirectory static:
  !/myapp/static|/*=myworker
  # Exclude some suffixes:
  !*.html=myworker
An exclusion rule overrides a normal mapping rule only, if the worker names in the normal rule and in the exclusion rule are the same. Starting with version 1.2.26 of JK you can apply an exclusion rule to any worker, by using the star character '*' as the worker name in the exclusion rule. More complex patterns in exclusion worker names are not allowed.
  # Mapping the webapps /myapp1 and /myapp2:
  /myapp1|/*=myworker1
  /myapp2|/*=myworker2
  # Exclude the all subdirectories static for all workers:
  !/*/static|/*=*
  # Exclude some suffixes for all workers:
  !*.html=*

Rule disabling comes into play, if your web server merges rules from various sources, and you want to disable any rule defined previously. Since the uriworkermap file gets reloaded dynamically, you can use this to temporarily disable request forwarding: A rule gets disabled, if it is suffixed with '-':

  # We are not in maintenance.
  # The maintenance rule got defined somewhere else.
  -/*=maintenance
Exclusion rules can get disabled as well, then the rule starts with '-!'.

Mapping priorities

The most restrictive URI pattern is applied first. More precisely the URI patterns are sorted by the number of '/' characters in the pattern (highest number first), and rules with equal numbers are sorted by their string length (longest first).

If both distinctions still do not suffice, then the defining source of the rule is considered. Rules defined in uriworkermap.properties come first, before rules defined by JkMount (Apache) and inside workers.properties using the mount attribute.

All disabled rules are ignored. Exclusion rules are applied after all normal rules have been applied.

There is no defined behaviour, for the following configuration conflict: using literally the same URI pattern in the same defining source but with different worker targets.

Rule extensions

Rule extensions were added in version 1.2.27 and are not available in earlier versions.

Syntax

Rule extensions are additional attributes, that can be attached to any rule. They are added at the end of the rule, each extension separated by a semicolon:

  # This is an extension example,
  # setting a reply_timeout of 1 minute
  # only for this mapping.
  /myapp=myworker;reply_timeout=60000
  #
  # This is an example using multiple extensions
  /myapp=myloadbalancer;reply_timeout=60000;stopped=member1
Attributes set via rule extensions always overwrite conflicting configurations in the worker definition file.

Extension reply_timeout

The extension reply_timeout sets a reply timeout for a single mapping rule.

  # Setting a reply_timeout of 1 minute
  # only for this mapping.
  /myapp=myworker;reply_timeout=60000
It overrides any reply_timeout defined for the worker. The extension allows to set a reasonable default reply timeout to the worker, and a more relaxed reply timeout to URLs, which are known to start time intensive tasks. For a general description of reply timeouts see the timeouts documentation.

Extension sticky_ignore

The extension sticky_ignore will disable session stickyness for a single mapping rule.

  # Disable session stickyness
  # only for this mapping.
  /myapp/loginform.jsp=myworker;sticky_ignore=1
This extension can be useful to optimize load balancing when using cookie based session stickyness. In this case, as long as she keeps her browser open, any request by a user who started a session will be send to the same Tomcat instance, even if he left the part of the application which uses the session. You can for instance set this environment variable when a user requests a login form to ensure, that this initial session request is balanced non-sticky.

This extension is available since version 1.2.33.

Extension stateless

The extension stateless is only useful when using session based load balancing. In this case normally any request which does not come with a session id counts as a new session. If you mark a mapping rule with the stateless extension, then the requests matching the mapping rule will not count as a new session, even if they do not come with a session id.

  # Don't let static content trash our session balancing
  /myapp/static/*=myworker;stateless=1
This extension is available since version 1.2.33.

Extensions active/disabled/stopped

The extensions active, disabled, and stopped can be used in a load balancer mapping rule to set selected members of the load balancer into a special activation state.

  # Stop forwarding only for member1 of loadbalancer
  /myapp=myloadbalancer;stopped=member1
Multiple members must be separated by commas or white space:
  # Stop forwarding for member01 and member02 of loadbalancer
  # Disable forwarding for member21 and member22 of loadbalancer
  /myapp=myloadbalancer;stopped=member01,member02;disabled=member21,member22
For the precise meaning of the activation states see the description of activation.

Extension fail_on_status

The extension fail_on_status can be used in any rule:

  # Send 503 instead of 404 and 500,
  # and if we get a 503 also set the worker to error
  /myapp=myworker;fail_on_status=-404,-500,503
Multiple status codes must be separated by commas. For the precise meaning of the attribute see the description of fail_on_status.

Extension use_server_errors

The extension use_server_errors allows to let the web server send an error page, instead of the backend (e.g. Tomcat) error page. This is useful, if one wants to send customized error pages, but those are not part of all web applications. They can then be put onto the web server.

The value of use_server_errors is a positive number. Any request send to the backend, that returns with an http status code bigger or equal to use_server_errors, will be answered to the client with the error page of the web server for this status code.

  # Use web server error page for all errors
  /myapp=myworker;use_server_errors=400
  # Use web server error page only for technical errors
  /myotherapp=myworker;use_server_errors=500

Extensions controlling load balancer stickyness

The extensions

  • session_cookie
  • session_path
  • set_session_cookie
  • session_cookie_path
allow to define the load balancer worker attributes of the same name per mount. See their descriptions in the worker.properties configuration reference.

Virtual host integration

IIS

When using IIS you can restrict individual rules to special virtual hosts by prefixing the URI pattern with the virtual host information. The rules is that the url must be prefixed with the host name.

  # Use www.foo.org as virtual host
  /www.foo.org/myapp/*=myworker
  # Use www.bar.org as virtual host
  /www.bar.org/myapp/*=myworker
  # Normal mapping
  /mysecondapp/*=myworker

Note that /mysecondapp/* will be mapped to all virtual hosts present. In case one needs to prevent the mappings to some particular virtual host then the exclusion rule must be used

  # Make sure the myapp is accessible by all virtual hosts
  /myapp/*=myworker
  # Disable mapping myapp for www.foo.org virtual host
  !/www.foo.org/myapp/*=myworker

Apache httpd

For Apache you can define individual uriworkermap files per virtual host. The directive JkMountFile can be used in the main server and in each virtual host. If a virtual host does not use JkMountfile, but JkMountCopy is set to 'On', then it inherits the JkMountFile from the main server. If you want all vhost to inherit mounts from the main server, you can set JkMountCopy to 'All' in the main server.

Dynamic reloading

When a request is being processed, tomcat connectors check the file modification time of the uriworkermap file. To keep the performance penalty low, this happens only, if the last check happened at least n seconds ago.

For Apache you can configure the interval "n" using the directive JkMountFileReload, for IIS you would use the attribute worker_mount_reload. The default value is 60 seconds. A value of "0" turns off the reloading.

If the file changed, it gets reloaded completely. If there exist rules coming from other sources than the uriworkermap file (e.g. the workers.properties mount attribute or JkMount with Apache httpd), the new uriworkermap file gets dynamically merged with these ones exactly like when you do a web server restart.

Until version 1.2.19 reloading behaved slightly differently: it continuously added the full contents of the uriworkermap file to the rule mapping. The merging rules were, that duplicated got eliminated and old rules could be disabled, by defining the rule as disabled in the new file. Rules never got deleted.

Status worker integration

The configuration view of the status worker also shows the various mapping rules. After each worker's configuration, the rules are listed, that forward to this worker. The list contains four columns:

  • the name of the virtual server
  • the URI pattern, prefixed with '-' for a disabled pattern and '!' for an exclusion pattern
  • the type of the rule: Exact or Wildchar
  • and the source of the rule definition: 'worker definition' for the workers.properties file (mount attribute), 'JkMount' for Apache httpd JkMount and it's relatives and finally 'uriworkermap' for the uriworkermap file.

Note: The following restriction has been removed starting with version 1.2.26.
For Apache httpd, there is an important subtlety: the request going to the status worker gets executed in the context of some server (main or virtual). The status worker will only show the mapping rules, that are defined for this server (main or virtual).
Until version 1.2.25 the list contained three columns:

  • the type of the rule: Exact or Wildchar, eventually prefixed with Disabled or Unmount (for exclusion rules)
  • the URI pattern
  • and the source of the rule definition: 'worker definition' for the workers.properties file (mount attribute), 'JkMount' for Apache httpd JkMount and it's relatives and finally 'uriworkermap' for the uriworkermap file.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/reference/iis.html0000644000000000000020000005322212555256554020675 0ustar rootbinThe Apache Tomcat Connectors - Reference Guide - Configuring IIS
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Reference Guide

Configuring IIS

Printer Friendly Version
print-friendly
version
Requirements

The Tomcat redirector requires three entities:

  • isapi_redirect.dll - The IIS server plugin, either obtain a pre-built DLL or build it yourself (see the build section).
  • workers.properties - A file that describes the host(s) and port(s) used by the workers (Tomcat processes). A sample workers.properties can be found under the conf directory.
  • uriworkermap.properties - A file that maps URL-Path patterns to workers. A sample uriworkermap.properties can be found under the conf directory as well.

The installation includes the following parts:

  • Configuring the ISAPI redirector with a default /examples context and checking that you can serve servlets with IIS.
  • Adding more contexts to the configuration.

Note that in a 64 Bit environment - at least for IIS 7 - the used IIS Application Pool should have "Enable 32-bit Applications" set to "False". Otherwise the redirector will not be called and returns an http code 404. If you think, the 32bit version of isapi_redirect.dll would do the job instead, you will get an http code 500, because the library is not loadable into a 64 Bit IIS.

Registry settings

ISAPI redirector reads configuration from the registry, create a new registry key named :

"HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0"

Attributes described below as a "string value representing a boolean" can be set either using the numbers 0 (false) and 1 (true) as values, or off (false) and on (true) or any other string starting with the letters f (false), n (false), t (true) or y (true). The values are taken case insensitive. In this documentation we will stick to false and true.

Key NameDescription
extension_uri

A string value pointing to the ISAPI extension /jakarta/isapi_redirect.dll

log_file

A value pointing to location where log file will be created. (for example c:\tomcat\logs\isapi.log)
If one of the log rotation settings (log_rotationtime or log_filesize) are specified then the actual log file name is based on this setting. If the log file name includes any '%' characters, then it is treated as a format string for strftime(3), e.g. c:\tomcat\logs\isapi-%Y-%m-%d-%H_%M_%S.log. Otherwise, the suffix .nnnnnnnnnn is automatically added and is the time in seconds. A full list of format string substitutions can be found in the Apache rotatelogs documentation

log_level

A string value for log level (can be debug, info, warn, error or trace).

This directive was added in version 1.2.31

log_rotationtime

The time between log file rotations in seconds. Setting this to 0 (the default) disables log rotation based on time.

This directive was added in version 1.2.31

log_filesize

The maximum log file size in megabytes, after which the log file will be rotated. Setting this to 0 (the default) disables log rotation based on file size.
The value can have an optional M suffix, i.e. both 5 and 5M will rotate the log file when it grows to 5MB.
If log_rotationtime is specified, then this setting is ignored.

worker_file

A string value which is the full path to workers.properties file (for example c:\tomcat\conf\workers.properties)

worker_mount_file

A string value which is the full path to uriworkermap.properties file (for example c:\tomcat\conf\uriworkermap.properties)

rewrite_rule_file

A string value which is the full path to rewrite.properties file (for example c:\tomcat\conf\rewrite.properties)

shm_size

A DWORD value size of the shared memory. Set this value to be the number of all defined workers * 400. (Set this value only if you have more then 64 workers)

This directive has been added in version 1.2.20

Starting with version 1.2.27 the size of the shared memory is determined automatically, even for large numbers of workers. This attribute is not needed any longer.

worker_mount_reload

A DWORD value specifying the time in seconds upon which the worker_mount_file will be reloaded.

This directive has been added in version 1.2.20

strip_session

A string value representing a boolean. If it is set to true, URL session suffixes of the form ";jsessionid=..." get stripped of URLs, if the are served locally by the web server.

The default value is false.

This directive has been added in version 1.2.21

auth_complete

A DWORD value representing "0" or "1". This is needed because of minor incompatibilities with IIS 5.1.

By default its value is 1, which means we use the SF_NOTIFY_AUTH_COMPLETE event. If you set this to 0, then we use SF_NOTIFY_PREPROC_HEADERS. This might be needed for IIS 5.1 when handling requests using the PUT HTTP method.

This directive has been added in version 1.2.21

uri_select

A string value which influences, how URIs are decoded and re-encoded between IIS and Tomcat. You should leave this at it's default value, unless you have a very good reason to change it.

If the value is "parsed", the forwarded URI will be decoded and explicit path components like ".." will already be resolved. This is less spec compliant and is not safe if you are using prefix forwarding rules.

If the value is "unparsed", the forwarded URI will be the original request URI. It's spec compliant and also the safest option. Rewriting the URI and then forwarding the rewritten URI will not work.

If the value is "escaped", the forwarded URI will be the re-encoded form of the URI used by "parsed". Explicit path components like ".." will already be resolved. This will not work in combination with URL encoded session IDs.

If the value is "proxy", the forwarded URI will be a partially re-encoded form of the URI used by "parsed". Explicit path components like ".." will already be resolved. and problematic are re-encoded.

The default value since version 1.2.24 is "proxy". Before it was "parsed".

reject_unsafe

A string value representing a boolean. If it is set to true, URLs still containing percent signs '%' or backslashes '\' after decoding will be rejected.

Most web apps do not use such URLs. By enabling reject_unsafe you can block several well known URL encoding attacks.

The default value is false.

This directive has been added in version 1.2.24

collapse_slashes

One of the string values "all", "none" or "unmount". It controls whether multiple adjacent slashes in request URLs are collapsed before looking for a mount or unmount match.

Value "all" will result in collapsing before mount and unmount checks, value "none" will result in never collapsing, value "unmount" will check mount rules without collapsing but unmount with collapsing.

Before version 1.2.41 collapsing was never done. Starting with version 1.2.41 collapsing before looking for unmount matches is the default to prevent easy bypassing of unmount rules.

This directive has been added in version 1.2.41

watchdog_interval

A DWORD value representing the watchdog thread interval in seconds. The workers are maintained periodically by a background thread running periodically every watchdog_interval seconds. Worker maintenance checks for idle connections, corrects load status and is able to detect backend health status.

The maintenance only happens, if since the last maintenance at least worker.maintain seconds have passed. So setting the watchdog_interval much smaller than worker.maintain is not useful.

The default value is 0 seconds, meaning the watchdog thread will not be created, and the maintenance is done in combination with normal requests instead.

This directive has been added in version 1.2.27

error_page

A string value representing the error page url redirection when backend returns non-200 response. This directive can be used to customise the error messages returned from backend server.

The url must point to a valid server url and can contain format string number (%d) that can be used to separate the pages by error number. The redirect url in that case is formatted by replacing %d from error_page to returned error number.

This directive has been added in version 1.2.27

enable_chunked_encoding

A string value representing a boolean. If it is set to true, chunked encoding is supported by the server.

The default value is false.

This directive has been added in version 1.2.27. Until version 1.2.30 it was considered experimental and only available when a special build containing chunking support was used. Starting with 1.2.30 it is no longer considered experimental.

Using a properties file for configuration

The ISAPI redirector can read it's configuration from a properties file instead of the registry. This has the advantage that you can use multiple ISAPI redirectors with independent configurations on the same server. The redirector will check for the properties file during initialisation, and use it in preference to the registry if present.

Create a properties file in the same directory as the ISAPI redirector called isapi_redirect.properties i.e. with the same name as the ISAPI redirector DLL but with a .properties extension. A sample isapi_redirect.properties can be found under the conf directory.

The property names and values in the properties file are the same as for the registry settings described above. For example:

# Configuration file for the Tomcat ISAPI Redirector

# The path to the ISAPI Redirector Extension, relative to the website
# This must be in a virtual directory with execute privileges
extension_uri=/jakarta/isapi_redirect.dll

# Full path to the log file for the ISAPI Redirector
log_file=c:\tomcat\logs\isapi_redirect.log

# Log level (debug, info, warn, error or trace)
log_level=info

# Full path to the workers.properties file
worker_file=c:\tomcat\conf\workers.properties

# Full path to the uriworkermap.properties file
worker_mount_file=c:\tomcat\conf\uriworkermap.properties

Notes:

  • Back-slashes - '\' - are not escape characters.
  • Comment lines begin with '#'.

Starting with version 1.2.27 two environment variables are automatically added to the environment that can be used inside .properties files.

  • JKISAPI_PATH - Full path to the ISAPI Redirector.
  • JKISAPI_NAME - Name of the ISAPI Redirector dll without extension

# Use the logs in the installation path of ISAPI Redirector
log_file=$(JKISAPI_PATH)\$(JKISAPI_NAME).log

Log file rotation

The ISAPI redirector with version 1.2.31 can perform log rotation, with configuration and behaviour similar to the rotatelogs program provided with Apache HTTP Server.

To configure log rotation, configure a log_file, and one of the log_rotationtime or log_filesize options. If both are specified, the log_rotationtime will take precedence, and log_filesize will be ignored.
For example, to configure daily rotation of the log file:

# Configuration file for the Tomcat ISAPI Redirector
...

# Full path to the log file for the ISAPI Redirector
log_file=c:\tomcat\logs\isapi_redirect.%Y-%m-%d.log

# Log level (debug, info, warn, error or trace)
log_level=info

# Rotate the log file every day
log_rotationtime=86400

...

Or to configure rotation of the log file when it reaches 5MB in size:

# Configuration file for the Tomcat ISAPI Redirector
...

# Full path to the log file for the ISAPI Redirector
log_file=c:\tomcat\logs\isapi_redirect.%Y-%m-%d-%H.log

# Log level (debug, info, warn, error or trace)
log_level=info

# Rotate the log file at 5 MB
log_filesize=5M

...

The log will be rotated whenever the configured limit is reached, but only if the log file name would change. If you configure a log file name with strftime(3) format codes in it, then ensure it specifies the same granularity as the rotation time configured, e.g. %Y-%m-%d if rotating daily (log_rotationtime=86400).
See the rotatelogs documentation for more examples.

Using a simple rewrite rules

The ISAPI redirector with version 1.2.16 can do a simple URL rewriting. Although not as powerful as Apache Httpd's mod_rewrite, it allows a simple exchange of request URIs

The rule is in the form original-url-prefix=forward-url-prefix. For example:

# Simple rewrite rules, making /jsp-examples
# and /servlets-examples available under shorter URLs
/jsp/=/jsp-examples/
/servlets/=/servlets-examples/

You can also use regular expressions, if you prefix the rule with a tilde ~:

# Complex rewrite rule, adding "-examples"
# to the first path component of all requests
~/([^/]*)=/$1-examples

Note that uriworkermap.properties must use the URLs before rewriting.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/reference/printer/0000755000000000000020000000000012555256555020703 5ustar rootbintomcat-connectors-1.2.41-src/docs/reference/printer/workers.html0000644000000000000020000020010412555256555023262 0ustar rootbinThe Apache Tomcat Connectors - Reference Guide - workers.properties configuration
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Reference Guide

workers.properties configuration

Introduction

A Tomcat worker is a Tomcat instance that is waiting to execute servlets or any other content on behalf of some web server. For example, we can have a web server such as Apache forwarding servlet requests to a Tomcat process (the worker) running behind it.

The scenario described above is a very simple one; in fact one can configure multiple Tomcat workers to serve servlets on behalf of a certain web server. The reasons for such configuration can be:

  • We want different contexts to be served by different Tomcat workers to provide a development environment where all the developers share the same web server but own a Tomcat worker of their own.
  • We want different virtual hosts served by different Tomcat processes to provide a clear separation between sites belonging to different companies.
  • We want to provide load balancing, meaning run multiple Tomcat workers each on a machine of its own and distribute the requests between them.

There are probably more reasons for having multiple workers but I guess that this list is enough...

Tomcat workers are defined in a properties file dubbed workers.properties and this tutorial explains how to work with it.

Configuration File Basics

Defining workers to the Tomcat web server plugin can be done using a properties file (a sample file named workers.properties is available in the conf/ directory).

Format, Comments, Whitespace

The lines in the file define properties. The general format is

<name>=<value>

Dots are used as part of the name to represent a configuration hierarchy.

Invalid directives will be logged during web server startup and prevent the web server from working properly. Some directives have been deprecated. Although they will still work, you should replace them by their successors.

Some directives are allowed multiple times. This will be explicitly noted in the tables below.

Whitespace at the beginning and the end of a property name or value gets ignored. Comments can be placed in any line and start with a hash sign '#'. Any line contents behind the hash sign get ignored.

Boolean properties can be set either using the numbers 0 (false) and 1 (true) as values, or off (false) and on (true) or any other string starting with the letters f (false), n (false), t (true) or y (true). The values are taken case insensitive. In this documentation we will stick to false and true.

Global Properties

These directives have global scope.

DirectiveDefaultDescription
worker.listajp13 A comma separated list of workers names that the JK will use. When starting up, the web server plugin will instantiate the workers whose name appears in the worker.list property, these are also the workers to whom you can map requests.

This directive can be used multiple times.

worker.maintain60 Worker connection pool maintain interval in seconds. If set to the positive value JK will scan all connections for all workers specified in worker.list directive and check if connections needs to be recycled.

Furthermore any load balancer does a global maintenance every worker.maintain seconds. During global maintenance load counters are decayed and workers in error are checked for recover_time.

This feature has been added in jk 1.2.13.

Worker Properties

Each worker configuration directive consists of three words separated by a dot:

worker.<worker name>.<directive>=<value>

The first word is always worker. The second word is the worker name you can choose. In the case of load-balancing, the worker name has an additional meaning. Please consult the Load Balancer HowTo.

The name of the worker can contain only the alphanumeric characters [a-z][A-Z][0-9][_\-] and is case sensitive.

Variables, Environment Variables

You can define and use variables in the workers.properties file. To define a variable you use the syntax:

<variable_name>=<value>

Dots are allowed in the variable name, but you have to be careful not to use variable names, that clash with standard directives. Therefore variable names should never start with "worker.".

To use a variable, you can insert "$(variable_name)" at any place on the value side of a property line. If a variable has not been defined before its use, we will search the process environment for a variable with the same name and use their value.

Property Inheritance

Often one wants to use the same property values for various workers. To reduce duplication of configuration lines and to ease the maintenance of the file, you can inherit properties from one worker to another, or even from a template to real workers.

The directive "reference" allows to copy configurations between workers or worker templates in a hierarchical way. If worker castor sets worker.castor.reference=worker.pollux then it inherits all properties of pollux, except for the ones that are explicitly set for castor.

Please note, that the value of the directive is not only the name of the referred worker, but the complete prefix including "worker.".

To use a template worker simply define it like a real worker, but do not add it to the "worker.list" or as a member to any load balancer. Such a template worker does not have to contain mandatory directives. This approach is especially useful, if one has a lot of balanced workers in a load balancer and these workers share most of their properties. You can set all of these properties in a template worker, e.g. using the prefix "worker.template1", and then simply reference those common properties in all balanced workers.

References can be used to inherit properties over multiple hops in a hierarchical way. The maximum depth for nesting references is 20. Be careful not to introduce a reference loop!

This feature has been added in jk 1.2.19.

List of All Worker Directives

Mandatory Directives

Mandatory directives are the one that each worker must contain. Without them the worker will be unavailable or will misbehave. Those directives will be marked with a strong font in the following tables.

DirectiveDefaultDescription
typeajp13 Type of the worker (can be one of ajp13, ajp14, jni, lb or status). The type of the worker defines the directives that can be applied to the worker.

Type ajp13 is the preferred worker type that JK uses for communication between web server and Tomcat. This type of worker uses sockets as communication channel. For detailed description of the AJP13 protocol stack browse to AJPv13 protocol specification

Type ajp14 is experimental and not recommended.

JNI workers have been deprecated. They will likely not work. Do not use them.

Connection Directives

Connection directives defines the parameters needed to connect and maintain the connections pool of persistent connections between JK and remote Tomcat.

DirectiveDefaultDescription
hostlocalhost Host name or IP address of the backend Tomcat instance. The remote Tomcat must support the AJP13 protocol stack. The host name can have a port number embedded separated by the colon (':') character.
port8009 Port number of the remote Tomcat instance listening for defined protocol requests. The default value depends on the worker type. For ajp13 workers the default port is 8009, while for ajp14 type of worker that value is 8011.
source- Name or IP address used for the connection source (outgoing address). It should only be used on multi-homed hosts.

This feature is experimental and has been added in jk 1.2.41.

socket_timeout0 Socket timeout in seconds used for the communication channel between JK and remote host. If the remote host does not respond inside the timeout specified, JK will generate an error, and retry again. If set to zero (default) JK will wait for an infinite amount of time on all socket operations.
socket_connect_timeoutsocket_timeout*1000 Socket connect timeout in milliseconds used for the communication channel between JK and remote host. If the remote host does not respond inside the timeout specified, JK will generate an error, and retry again.

Note that socket_timeout is in seconds, and socket_connect_timeout in milliseconds, so in absolute terms the default socket_connect_timeout is equal to "socket_timeout.

This feature has been added in jk 1.2.27.

socket_keepalivefalse This directive should be used when you have a firewall between your webserver and the Tomcat engine, who tend to drop inactive connections. This flag will tell the Operating System to send KEEP_ALIVE messages on inactive connections (interval depend on global OS settings, generally 120 minutes), and thus prevent the firewall to cut inactive connections. To enable keepalive set this property value to true.

The problem with Firewall cutting inactive connections is that sometimes, neither webserver or Tomcat have information about the cut and couldn't handle it.

ping_mode- This flag determines, under which conditions established connections are probed to ensure they are still working. The probe is done with an empty AJP13 packet (CPing) and expects to receive an appropriate answer (CPong) within some timeout.

The value of the flag can be any combination of the following flags (multiple values are combined without any separators):

C (connect): If set, the connection will be probed once after connecting to the backend. The timeout can be set by connect_timeout. If it is not set, the value of ping_timeout will be used instead.

P (prepost): If set, the connection will be probed before sending each request to the backend. The timeout can be set by prepost_timeout. If it is not set, the value of ping_timeout will be used instead.

I (interval): If set, the connection will be probed during the regular internal maintenance cycle, but only if it is idle longer than connection_ping_interval. The timeout can be set by ping_timeout.

A If set, all of the above probes will be used.

This feature has been added in jk 1.2.27. Connect and prepost probing were already available via connect_timeout and prepost_timeout since version jk 1.2.6.

ping_timeout10000 Timeout in milliseconds used when waiting for the CPong answer of a CPing connection probe. The activation of the probes is done via ping_mode. The timeouts for ping_mode connect and prepost can be overwritten individually via connect_timeout and prepost_timeout.

For compatibility reasons, CPing/CPong is also used, whenever connect_timeout or prepost_timeout are set, even if ping_mode is empty.

This feature has been added in jk 1.2.27.

connection_ping_interval0 / (ping_timeout/1000)*10 When using interval connection probing, connections idle for longer than this interval in seconds are probed by CPing packets whether they still work.

Interval probing can be activated either by ping_mode, or by setting connection_ping_interval to some value bigger than zero. If you activate interval probing via ping_mode, then the default value of connection_ping_interval is (ping_timeout/1000) * 10. Note that ping_timeout is in milliseconds, and connection_ping_interval in seconds, so in absolute terms the default connection_ping_interval is 10 times ping_timeout.

This feature has been added in jk 1.2.27.

connection_pool_sizesee text This defines the number of connections made to the AJP backend that are maintained as a connection pool. It will limit the number of those connection that each web server child process can made.

Connection pool size property is only used for multi threaded web servers such as Apache, IIS and Netscape/Sun. The connection_pool_size property needs to reflect the number of requests one web server process should be able to send to a backend in parallel. Usually this is the same as the number of threads per web server process. JK will discover this number for the Apache web server automatically and set the pool size to this value. For IIS the default value is 250 (before version 1.2.20: 10), for Netscape/Sun the default value is 1.

We strongly recommend adjusting this value for IIS and the Netscape/Sun to the number of requests one web server process should be able to send to a backend in parallel. You should measure how many connections you need during peak activity without performance problems, and then add some percentage depending on your growth rate. Finally you should check, whether your web server processes are able to use at least as many threads, as you configured as the pool size.

Do not use connection_pool_size with values higher then 1 on Apache 2.x prefork or Apache 1.3.x!

connection_pool_minsize(pool+1)/2 Minimum size of the connection pool that will be maintained.

Its default value is (connection_pool_size+1)/2.

Do not use connection_pool_size with values higher then 1 on Apache 2.x prefork or Apache 1.3.x!

This feature has been added in jk 1.2.16.

connection_pool_timeout0 Cache timeout property should be used with connection_pool_minsize to specify how many seconds JK should keep an inactive socket in cache before closing it. This property should be used to reduce the number of threads on the Tomcat web server. The default value zero disables the closing (infinite timeout).

Each child could open an ajp13 connection if it has to forward a request to Tomcat, creating a new ajp13 thread on Tomcat side.

The problem is that after an ajp13 connection is created, the child won't drop it until killed. And since the webserver will keep its childs/threads running to handle high-load, even it the child/thread handle only static contents, you could finish having many unused ajp13 threads on the Tomcat side.

You should keep this time interval in sync with the keepAliveTimeout attribute (if it is set explicitly) or connectionTimeout attribute of your AJP connector in Tomcat's server.xml. Note however, that the value for mod_jk is given in seconds, the one in server.xml has to use milliseconds.

connection_acquire_timeoutretries*retry_interval Timeout the worker will wait for a free socket in cache before giving up.

Its default value is retries * retry_interval.

This feature has been added in jk 1.2.27.

lbfactor1 Only used for a member worker of a load balancer.

The integer number lbfactor (load-balancing factor) is how much we expect this worker to work, or the worker's work quota. Load balancing factor is compared with other workers that makes the load balancer. For example if one worker has lb_factor 5 times higher then other worker, then it will receive five times more requests.

Load Balancing Directives

Load balancer is a virtual worker that does not really communicate with Tomcat workers. Instead it is responsible for the management of several "real" workers. The worker is supposed to be a load balancer if it's worker type is lb. See worker's type directive.

Loadbalancer directives define the parameters needed to create the workers that are connecting to a remote cluster of backend Tomcat servers. Each cluster node has to have a worker defined.

Load balancer management includes:

  • Instantiating the workers in the web server.
  • Using the worker's load-balancing factor, perform weighed-round-robin load balancing where high lbfactor means stronger machine (that is going to handle more requests)
  • Keeping requests belonging to the same session executing on the same Tomcat worker.
  • Identifying failed Tomcat workers, suspending requests to them and instead fall-backing on other workers managed by the lb worker.

The overall result is that workers managed by the same lb worker are load-balanced (based on their lbfactor and current user session) and also fall-backed so a single Tomcat process death will not "kill" the entire site.

If you want to use session stickiness, you must set different jvmRoute attributes in the Engine element in Tomcat's server.xml. Furthermore the names of the workers which are managed by the balancer have to be equal to the jvmRoute of the Tomcat instance they connect with.

The restriction on the worker names can be lifted, if you use the route attribute for the workers.

The following table specifies properties that the lb worker can accept:

DirectiveDefaultDescription
balance_workers- A comma separated list of workers that the load balancer need to manage.

This directive can be used multiple times for the same load balancer.

This directive replaces old balanced_workers directive and can be used only with mod_jk versions 1.2.7 and up.

As long as these workers should only be used via the load balancer worker, there is no need to also put them into the worker.list property.

sticky_sessiontrue Specifies whether requests with SESSION ID's should be routed back to the same Tomcat worker. If sticky_session is set to true sessions are sticky, otherwise sticky_session is set to false. Set sticky_session to false when Tomcat is using a Session Manager which can persist session data across multiple instances of Tomcat.

The sticky_session setting can be overwritten using the Apache httpd environment variable JK_STICKY_IGNORE and the worker map extension for sticky_ignore. This has been added in version 1.2.33.

sticky_session_forcefalse Specifies whether requests with SESSION ID's for workers that are in error state should be rejected. If sticky_session_force is set to true and the worker that matches that SESSION ID is in error state, client will receive 500 (Server Error). If set to false failover on another worker will be issued with losing client session. This directive is used only when you set sticky_session=true.

This feature has been added in jk 1.2.9.

methodRequest Specifies what method load balancer is using for electing the best worker. Please note, that session stickiness and perfect load balancing are conflicting targets, especially when the number of sessions is small, or the usage of sessions is extremely varying For huge numbers of sessions this usually is not a problem.

Some methods note, that they aggregate in a sliding time window. They add up accesses, and on each run of the global maintain method, the load counters get divided by 2. Usually this happens once a minute, depending on the setting of worker.maintain. The value of the load counters can be inspected using the status worker.

If method is set to R[equest] the balancer will use the number of requests to find the best worker. Accesses will be distributed according to the lbfactor in a sliding time window. This is the default value and should be working well for most applications.

If method is set to S[ession] the balancer will use the number of sessions to find the best worker. Accesses will be distributed according to the lbfactor in a sliding time window. This method should be used, if sessions are your limiting resource, e.g. when you only have limited memory and your sessions need a lot of memory. Because the balancer does not keep any state, it actually does not know the number of sessions. Instead it counts each request without a session cookie or URL encoding as a new session. This method will neither know, when a session is being invalidated, nor will it correct its load numbers according to session timeouts or worker failover. If you know request URLs, that will be called without a session ID but should not be counted as new sessions, you should add them to the stateless mapping rule extension or set the Apache HTTPD environment variable JK_STATELESS for them.

If method is set to N[ext] the balancer will again use the number of sessions to find the best worker. All remarks concerning the Sessionmethod apply as well. The difference to the Session method is how the session count is handled in the sliding time window. The Next method does not divide by 2, instead it subtracts the current minimum number. This should effectively result in a round-robin session balancing, thus the name Next. Under high load, the two session balancing methods will result in a similar distribution, but Next will be better if you need to distribute small numbers of sessions.

If set to T[raffic] the balancer will use the network traffic between JK and Tomcat to find the best worker. Accesses will be distributed according to the lbfactor in a sliding time window. This method should be used, if network to and from the backends is your limiting resource.

If set to B[usyness] the balancer will pick the worker with the lowest current load, based on how many requests the worker is currently serving. This number is divided by the workers lbfactor, and the lowest value (least busy) worker is picked. This method is especially interesting, if your request take a long time to process, like for a download application. The method is not recommended for general use, because under high load on some hardware architectures the busy counter can become wrong.

This feature has been added in version 1.2.9. The Session method has been added in version 1.2.20, the Next method in version 1.2.33.

lockOptimistic Specifies what lock method the load balancer will use for synchronising shared memory runtime data. If lock is set to O[ptimistic] balancer will not use shared memory lock to find the best worker. If set to P[essimistic] balancer will use shared memory lock. The balancer will work more accurately in case of Pessimistic locking, but can slow down the average response time.

This feature has been added in jk 1.2.13.

retries2

This directive also exists for normal workers. For those it has a different meaning.

If the load balancer can not get a valid member worker or in case of failover, it will try again a number of times given by retries. Before each retry, it will make a pause define by retry_interval directive.

Until version 1.2.16 the default value was 3.

Status Worker Directives

The status worker does not communicate with Tomcat. Instead it is responsible for the load balancer management.

DirectiveDefaultDescription
css- Specifies the url for cascading stylesheet to use.
read_onlyfalse A status worker with read_only=true will not allow any operations, that change the runtime state or configuration of the other workers. These are edit/update/reset/recover.

This feature has been added in jk 1.2.20.

user- It is a list of users which gets compared to the user name authenticated by the web server. If the name is not contained in this list, access is denied. Per default the list is empty and then access is allowed to anybody.

This directive can be used multiple times.

This feature has been added in jk 1.2.20.

user_case_insensitivefalse By default, the user names are matched case sensitively. You can set user_case_insensitive=true to make the comparison case insensitive. This may be especially useful on the Windows platform.

This feature has been added in jk 1.2.21.

gooda.o,a.n,a.b,a.r For every load balancer worker, the status worker shows a summary of the state of its members. There are three such states, "good", "bad" and "degraded".

These states are determined depending on the activation of the members (active, disabled, stopped) and their runtime state (ok, n/a, busy, recovering, probing, forced recovery, error). By default, members are assumed to be "good", if their activation is "active" and their runtime state is not "error".

You can change this mapping, by assigning a list of values to the attribute "good". Each value gives a possible match for the members, and one match suffices. Each value is either a single character, or two characters combined with a dot ".". The single characters are the first characters in the words "active", "disabled", "stopped", "ok", "na", "busy", "recovering", "error". The additional states "probing" and "forced recovery" are always rated equivalent to "recovering". If a value consists only of a single character, then all members with this activation or runtime state will be assumed good. A combination of an activation and a runtime state concatenated with a dot "." does only apply to a member, that has exactly this activation and state.

Members of a load balancer will first be matched against the state "bad", if they don't match, the state "good" will be tried, and if they still don't match, their state will be "degraded".

This directive can be used multiple times.

This feature has been added in jk 1.2.20.

bads,e See: "good".

By default, members are assumed to be "bad", if their activation is "stopped" or their runtime state is "error".

This directive can be used multiple times.

This feature has been added in jk 1.2.20.

prefixworker The prefix, which will be used by the status worker when producing properties output (mime=prop). Each property key will be prefixed by this value.

This feature has been added in jk 1.2.20.

nsjk: This directive can be used to customise the XML output from the status worker. If set to - no namespace will be used.

This feature has been added in jk 1.2.20.

xmlns- This directive can be used to customise the XML output from the status worker. If set to - no xmlns will be used.

Default value is set to xmlns:jk="http://tomcat.apache.org"

This feature has been added in jk 1.2.20.

doctype- This directive can be used to customise the XML output from the status worker. This value will be inserted to the output xml after the xml header.

This feature has been added in jk 1.2.20.

Advanced Worker Directives

This table lists more advanced configuration options. Most of them only apply to some types of workers. We use the abbreviations AJP for ajp13/ajp14 workers used directly via the workers.list, LB for load balancer workers, and SUB for the workers used indirectly in a load balancer worker as a sub worker or member.

DirectiveWorker TypeDefaultDescription
connect_timeoutAJP,SUB0 Connect timeout property told webserver to send a PING request on ajp13 connection after connection is established. The parameter is the delay in milliseconds to wait for the PONG reply. The default value zero disables the timeout (infinite timeout).

This features has been added in jk 1.2.6 to avoid problem with hung Tomcat's and require ajp13 ping/pong support which has been implemented on Tomcat 3.3.2+, 4.1.28+ and 5.0.13+. Disabled by default.

prepost_timeoutAJP,SUB0 Prepost timeout property told webserver to send a PING request on ajp13 connection before forwarding to it a request. The parameter is the delay in milliseconds to wait for the PONG reply. The default value zero disables the timeout (infinite timeout).

This features has been added in jk 1.2.6 to avoid problem with hung Tomcat's and require ajp13 ping/pong support which has been implemented on Tomcat 3.3.2+, 4.1.28+ and 5.0.13+. Disabled by default.

reply_timeoutAJP,SUB0 The parameter is the number of milliseconds to wait for success during a read event. So this is not a timeout for the complete answer time of a request, but only for the maximum time between two packets received from Tomcat. Usually the longest pause is between sending the request and getting the first packet of the response.

If the timeout passes without any data received from Tomcat, the webserver will no longer wait for the rest of the response and send an error to the client (browser). Usually this does not mean, that the request is also aborted on the Tomcat backend. If the worker is a member of a load balancer, the load balancer might place the worker into an error state and retry the request on another member. See also max_reply_timeouts, retries and recovery_options.

By default (value zero) the webserver will wait forever which could be an issue for you. If you set a reply_timeout, adjust it carefully if you have long running servlets.

The reply_timeout can be overwritten using the Apache httpd environment variable JK_REPLY_TIMEOUT and the worker map extension for reply_timeout.

This features has been added in jk 1.2.6 to avoid problem with hung Tomcat's and works on all servlet engines supporting ajp13. The variable JK_REPLY_TIMEOUT and the worker map extension have been added in version 1.2.27.

retriesAJP,SUB2

This directive also exists for load balancer workers. For those it has a different meaning.

The maximum number of times that the worker will send a request to Tomcat in case of a communication error. Each retry will be done over another connection. The first time already gets counted, so retries=2 means one retry after error. Before a retry, the worker waits for a configurable sleeping time.

See also the attribute recovery_options for a more fine-grained control of retries and retry_interval for the sleep time configuration.

Until version 1.2.16 the default value was 3.

retry_intervalAJP,SUB100 The amount of time in milliseconds the worker sleeps before doing any retry.

This features has been added in jk 1.2.27.

recovery_optionsAJP,SUB0 Recovery options influence, how we should handle retries, in case we detect a problem with Tomcat. How often we will retry is controlled by the attribute retries.

This attribute is a bit mask. The following bits are allowed:
1: don't recover if Tomcat failed after getting the request
2: don't recover if Tomcat failed after sending the headers to client
4: close the connection to Tomcat, if we detect an error when writing back the answer to the client (browser)
8: always recover requests for HTTP method HEAD (even if Bits 1 or 2 are set)
16: always recover requests for HTTP method GET (even if Bits 1 or 2 are set)

This features has been added in jk 1.2.6. Option 4 has been added in version 1.2.16, options 8 and 16 in version 1.2.24.

fail_on_statusAJP,SUB0 Set this value to the HTTP status code that will cause a worker to fail if returned from Servlet container. Use this directive to deal with cases when the servlet container can temporary return non-200 responses for a short amount of time, e.g during redeployment.

The error page, headers and status codes of the original response will not be send back to the client. Instead the request will result in a 503 response. If the worker is a member of a load balancer, the member will be put into an error state. Request failover and worker recovery will be handled with the usual load balancer procedures.

This feature has been added in jk 1.2.20.

Starting with jk 1.2.22 it is possible to define multiple status codes separated by space or comma characters. For example: worker.xxx.fail_on_status=500,503

Starting with jk 1.2.25 you can also tell the load balancer to not put a member into an error state, if a response returned with one of the status codes in fail_on_status. This feature gets enabled, by putting a minus sign in front of those status codes. For example: worker.xxx.fail_on_status=-404,-500,503

busy_limitAJP,SUB0 If set to a positive number, the worker will only be used for a request, if it is currently working on less than this number of concurrent requests.

Note that this is not related to the Busyness load balancing method.

This feature is experimental and has been added in jk 1.2.41.

max_packet_sizeAJP,SUB8192 This attribute sets the maximal AJP packet size in Bytes. The maximum value is 65536. If you change it from the default, you must also change the packetSize attribute of your AJP connector on the Tomcat side! The attribute packetSize is only available in Tomcat 5.5.20+ and 6.0.2+.

Normally it is not necessary to change the maximum packet size. Problems with the default value have been reported when sending certificates or certificate chains.

This feature has been added in jk 1.2.19.

prefer_ipv6AJP,SUBfalse When compiled with IPV6 support, this directive forces IPV6 address resolution for host names which have both IPV6 and IPV4 addresses. In case there is no IPV6 address defined for the given hostname this directive in ineffective. This directive will be also ineffective if there is only IPV6 address defined or if IP address is used for "host", either in IPV4 or IPV6 notation.

This feature has been added in jk 1.2.38.

secretAJP,SUB,LB- You can set a secret keyword on the Tomcat AJP Connector. Then only requests from workers with the same secret keyword will be accepted.

Use request.secret="secret key word" in your Tomcat AJP Connector configuration in Tomcat 5.5 or 6.0 and requiredSecret="secret key word" in Tomcat 7.0 onwards.

If you set a secret on a load balancer, all its members will inherit this secret.

This feature has been added in jk 1.2.12.

mountAJP,LB- Space delimited list of uri maps the worker should handle. It is only used, if the worker is included in worker.list.

This directive can be used multiple times for the same worker.

max_reply_timeoutsLB0 If you use a reply_timeout for the members of a load balancer worker, and you want to tolerate a few requests taking longer than reply_timeout, you can set this attribute to some positive value.

Long running requests will still time out after reply_timeout milliseconds waiting for data, but the corresponding member worker will only be put into an error state, if more than max_reply_timeouts requests have timed out. More precisely, the counter for those bad requests will be divided by two, whenever the load balancer does its internal maintenance (by default every 60 seconds).

This features has been added in jk 1.2.24 to make reply_timeout less sensitive for sporadic long running requests.

recover_timeLB60 The recover time is the time in seconds the load balancer will not try to use a worker, after it went into error state. Only after this time has passed, a worker in error state will be marked as in recovering, so that it will be tried for new requests.

This interval is not checked every time a request is being processed. Instead it is being checked during global maintenance. The time between two runs of global maintenance is controlled by worker.maintain.

Do not set recover_time to a very short time unless you understand the implications. Every recovery attempt for a worker in error is done by a real request!

error_escalation_timeLBrecover_time / 2 Setting a member of a load balancer into an error state is quite serious. E.g. it means that if you need stickyness, all access to the sessions of the respective node is blocked.

Some types of error detection do not provide a precise information, whether a node is completely broken or not. In those cases an LB will not immediately put the node into the error state. Only when there have been no successful responses for error_escalation_time seconds after such an error, will the node be put into error state.

This features has been added in jk 1.2.28.

session_cookieLBJSESSIONID The name of the cookie that contains the routing identifier needed for session stickyness. The routing identifier is everything after a "." character in the value of the cookie.

This feature has been added in jk 1.2.27.

session_pathLB;jsessionid The name of the path parameter that contains the routing identifier needed for session stickyness. The routing identifier is everything after a "." character in the value of the path parameter.

This feature has been added in jk 1.2.27.

set_session_cookieLBfalse Activates generation of session stickyness cookies. Typically you don't need this.

Some web frameworks replace Tomcat session management and use a different way of generating session IDs. As a consequence the routing ID added by Tomcat to the end of the session ID is lost and we no longer can do sticky load balancing. As a workaround you can use the following steps:

  • Choose a non-standard cookie name using the "session_cookie" attribute.
  • Activate cookie sending by setting the attribute "set_session_cookie" to true.
  • Set the attribute "session_cookie_path" to the correct application URI, like e.g. "/myapp/".

The cookie will only be send if the request does not already contain a cookie of the same name, or that cookie does not contain a routing ID which the load balancer can fulfill. Especially after a node failover we will send a new cookie to switch stickyness to the new node.

This feature has been added in jk 1.2.38.

session_cookie_pathLB- This attribute is only used if "set_session_cookie" is set to true. See "set_session_cookie" for a description. If the value of "session_cookie_path" is empty (default), then the send cookie will not contain a PATH information.

This feature has been added in jk 1.2.38.

activationSUBActive Using this directive, a balanced worker of a load balancer can be configured as disabled or stopped. A disabled worker only gets requests, which belong to sessions for that worker. A stopped worker does not get any requests. Users of a stopped worker will lose their sessions, unless session replication via clustering is used.

Use d or D to disable and s or S to stop. If this directive is not present the deprecated directives "disabled" or "stopped" are used.

This flag can be changed at runtime using status worker.

This feature has been added in jk 1.2.19.

routeSUBworker name Normally the name of a balanced worker in a load balancer is equal to the jvmRoute of the corresponding Tomcat instance. If you want to include a worker corresponding to a Tomcat instance into several load balancers with different balancing configuration (e.g. disabled, stopped) you can use this attribute.

Define a separate worker per lb and per Tomcat instance with an arbitrary worker name and set the route attribute of the worker equal to the jvmRoute of the target Tomcat instance.

If this attribute is left empty, the name of the worker will be used.

This attribute can be changed at runtime using status worker.

If the route name contains a period, the part before the first period will be used as domain name, unless domain is set explicitly.

This feature has been added in jk 1.2.16.
The automatic domain rule has been added in jk 1.2.20.
The attribute has been renamed from jvm_route to route in jk 1.2.20.

distanceSUB0 An integer number to express preferences between the balanced workers of an lb worker. A load balancer will never choose some balanced worker in case there is another usable worker with lower distance.

Only in case all workers below a given distance are in error, disabled or stopped, workers of a larger distance are eligible for balancing.

This feature has been added in jk 1.2.16.

domainSUB- Domain directive can be used only when the worker is a member of the load balancer. Workers that share the same domain name are treated as single worker. If sticky_session is used, then the domain name is used as session route.

This directive is used for large system with more then 6 Tomcats, to be able to cluster the Tomcats in two groups and thus lowering the session replication transfer between them.

This feature has been added in jk 1.2.8.

redirectSUB- Set to the name of the preferred failover worker. If worker matching SESSION ID is in error state then the redirect worker will be used instead. It will be used even if being disabled, thus offering hot standby.

If you explicitly set a route via the "route" attribute, you must set "redirect" to this route of the preferred failover worker and not to its name.

This feature has been added in jk 1.2.9.

Deprecated Worker Directives

The following directives have been deprecated in the past. We include their documentation in case you need to use an older version of mod_jk. We urge you to update and not use them any more. Please migrate your existing configurations.

DirectiveSuccessorDefaultDescription
cachesizeconnection_pool_sizesee text

This directive has been deprecated since 1.2.16.

Cachesize defines the number of connections made to the AJP backend that are maintained as a connection pool. It will limit the number of those connection that each web server child process can make.

Cachesize property is used only for multi threaded web servers such as Apache 2.0 (worker), IIS and Netscape. The cachesize property should reflect the number of threads per child process. JK will discover the number of threads per child process on Apache 2 web server with worker-mpm and set its default value to match the ThreadsPerChild Apache directive. For IIS the default value is 10. For other web servers than Apache or IIS this value has to be set manually.

Do not use cachesize with values higher then 1 on Apache 2.x prefork or Apache 1.3.x!

cache_timeoutconnection_pool_timeout0

This directive has been deprecated since 1.2.16.

Cache timeout property should be used with cachesize to specify how to time JK should keep an open socket in cache before closing it. This property should be used to reduce the number of threads on the Tomcat web server.

Each child could open an ajp13 connection if it have to forward a request to Tomcat, creating a new ajp13 thread on Tomcat side.

The problem is that after an ajp13 connection is created, the child won't drop it until killed. And since the webserver will keep its childs/threads running to handle high-load, even it the child/thread handle only static contents, you could finish having many unused ajp13 threads on the Tomcat side.

recycle_timeoutconnection_pool_timeout0

This directive has been deprecated since 1.2.16.

The number of seconds that told webserver to cut an ajp13 connection after some time of inactivity. When choosing an endpoint for a request and the assigned socket is open, it will be closed if it was not used for the configured time. It's a good way to ensure that there won't too old threads living on Tomcat side, with the extra cost you need to reopen the socket next time a request be forwarded. This property is very similar to cache_timeout but works also in non-cache mode. If set to value zero (default) no recycle will took place.
balanced_workersbalance_workers-

This directive has been deprecated since 1.2.7.

A comma separated list of workers that the load balancer need to manage.
disabledactivationfalse

This directive has been deprecated since 1.2.19.

If set to true the worker will be disabled if member of load balancer. This flag can be changed at runtime using status worker.

This feature has been added in jk 1.2.9.

stoppedactivationfalse

This directive has been deprecated since 1.2.19.

If set to true the worker will be stopped if member of load balancer. The flag is needed for stop complete traffic of a sticky session worker. It is only useful, when you have a cluster that replicated the sessions. This flag can be changed at runtime using status worker.

This feature has been added in jk 1.2.11.

jvm_routerouteworker name

This directive has been deprecated since 1.2.20.

Normally the name of a balanced worker in a load balancer is equal to the jvmRoute of the corresponding Tomcat instance. If you want to include a worker corresponding to a Tomcat instance into several load balancers with different balancing configuration (e.g. disabled, stopped) you can use this attribute.

Define a separate worker per lb and per Tomcat instance with an arbitrary worker name and set the jvm_route attribute of the worker equal to the jvmRoute of the target Tomcat instance.

If this attribute is left empty, the name of the worker will be used.

This attribute can be changed at runtime using status worker.

This feature has been added in jk 1.2.16.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/reference/printer/apache.html0000644000000000000020000015427612555256554023030 0ustar rootbinThe Apache Tomcat Connectors - Reference Guide - Configuring Apache
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Reference Guide

Configuring Apache

Configuration Directives

Most of the directives are allowed once in the global part of the Apache httpd configuration and once in every <VirtualHost> elements. Exceptions from this rule are explicitly listed in the table below.

Most values are inherited from the main server to the virtual hosts. Since version 1.2.20 they can be overwritten in the virtual hosts. Exceptions from this rule are again explicitly listed in the table below. See especially JkMountCopy.

Warning: If Apache httpd and Tomcat are configured to serve content from the same filing system location then care must be taken to ensure that httpd is not able to serve inappropriate content such as the contents of the WEB-INF directory or JSP source code.

This could occur if the httpd DocumentRoot overlaps with a Tomcat Host's appBase or the docBase of any Context. It could also occur when using the httpd Alias directive with a Tomcat Host's appBase or the docBase of any Context.

Here are the all directives supported by Apache:

DirectiveDescription
JkWorkersFile

The name of a worker file for the Tomcat servlet containers.
This directive is only allowed once. It must be put into the global part of the configuration.
If you don't use the JkWorkerProperty directives, then you must define your workers with a valid JkWorkersFile. There is no default value.

JkWorkerProperty

Enables setting worker properties inside Apache configuration file. The syntax is the same as in the JkWorkersFile (usually workers.properties). Simply prefix each line with "JkWorkerProperty" to put it directly into the Apache httpd config files.
This directive is allowed multiple times. It must be put into the global part of the configuration.
If you don't use the JkWorkerProperty directives, then you must define your workers with a valid JkWorkersFile. There is no default value.
This directive is available in jk1.2.7 version and later.

JkShmFile

Shared memory file name. Used only on unix platforms. The shm file is used by balancer and status workers.
This directive is only allowed once. It must be put into the global part of the configuration.
The default value is logs/jk-runtime-status. It is highly recommended that the shm file be placed on a local drive and not an NFS share.

The shared memory contains configuration and runtime information for load balancer workers and their members. It is need in order that all apache children

  • share the same status information for load balancing members (OK, ERROR, ...),
  • share the information about load taken by the individual workers,
  • share the information for the parts of the configuration, which are changeable during runtime by status workers.

JkShmSize

Size of the shared memory file name.
This directive is only allowed once. It must be put into the global part of the configuration.
The default value depends on the platform. It is usually less than 64KB.

JkMountFile

File containing multiple mappings from a context to a Tomcat worker. It is usually called uriworkermap.properties.
For inheritance rules, see: JkMountCopy.
There is no default value.

JkMountFileReload

This directive configures the reload check interval in seconds. The JkMountFile is checked periodically for changes. A changed file gets reloaded automatically. If you set this directive to "0", reload checking is turned off.
The default value is 60 seconds.
This directive has been added in version 1.2.20 of mod_jk.

JkMount

A mount point from a context to a Tomcat worker.
This directive is allowed multiple times. It is allowed in the global configuration and in VirtualHost.
You can also use it inside Location with a different syntax. Inside Location, one omits the first argument (path), which gets inherited verbatim from the Location argument. Whereas <Location /myapp> matches any URI beginning with "/myapp", any JkMount nested in such a Location block will only match for requests with exact URI /myapp. Therefore nesting JkMount in Location is typically not the right thing to do.
By default JkMount entries are not inherited from the global server to other VirtualHosts or between VirtualHosts. For the complete inheritance rules, see: JkMountCopy.
You might append rule extensions to the worker name. The extensions are separated from the worker name by a semicolon ";" using the same syntax as in the uriworkermap.properties file.

JkUnMount

An exclusion mount point from a context to a Tomcat worker. All exclusion mounts are checked after mapping a request to a tomcat worker. If the request maps also to an exclusion, it will not be forwarded to tomcat, and instead be served locally.
This directive is allowed multiple times. It is allowed in the global configuration and in VirtualHost.
You can also use it inside Location with a different syntax. Inside Location, one omits the first argument (path), which gets inherited verbatim from the Location argument. Whereas <Location /myapp> matches any URI beginning with "/myapp", any JkUnMount nested in such a Location block will only match for requests with exact URI /myapp. Therefore nesting JkUnMount in Location is typically not the right thing to do.
For inheritance rules, see: JkMountCopy.
This directive is available in jk1.2.7 version and later.

JkAutoAlias

Automatically Alias webapp context directories into the Apache document space.
Care should be taken to ensure that only static content is served via httpd as a result of using this directive. Any static content served by httpd will bypass any security constraints defined in the application's web.xml.
For inheritance rules, see: JkMountCopy.
There is no default value.

JkMountCopy

If this directive is set to "On" in some virtual server, the mounts from the global server will be copied to this virtual server, more precisely all mounts defined by JkMount or JkUnMount. The Mounts defined by JkMountFile and JkAutoAlias will only be inherited, if the VirtualHost does not define it's own JkMountFile or JkAutoAlias.
If you want all vhost to inherit mounts from the main server, you can set JkMountCopy to 'All' in the main server.
This directive is only allowed inside VirtualHost (with value "On") and in the global server (with value "All").
The default is Off, so no mounts will be inherited from the global server to any VirtualHost.
Starting with version 1.2.26 you can also set it to "All" in the global virtual server. This will switch the default to On.

JkWorkerIndicator

Name of the Apache environment variable that can be used to set worker names in combination with SetHandler jakarta-servlet.
This directive is only allowed once per virtual server. It is allowed in the global configuration and in VirtualHost.
The default value is JK_WORKER_NAME.

JkWatchdogInterval

This directive configures the watchdog thread interval in seconds. The workers are maintained periodically by a background thread running periodically every watchdog_interval seconds. Worker maintenance checks for idle connections, corrects load status and is able to detect backend health status.
The maintenance only happens, if since the last maintenance at least worker.maintain seconds have passed. So setting the JkWatchdogInterval much smaller than worker.maintain is not useful.
The default value is 0 seconds, meaning the watchdog thread will not be created, and the maintenance is done in combination with normal requests instead.
This directive is only allowed once. It must be put into the global part of the configuration.
This directive has been added in version 1.2.27 of mod_jk. It is available only for httpd 2.x and above using APR libraries including thread support.

JkLogFile

Full or server relative path to the mod_jk log file. It will also work with pipe, by using a value of the form "| ...".
The default value is logs/mod_jk.log.
Pipes are supported for Apache 1.3 only since version 1.2.16. The default value exists only since version 1.2.20.

JkLogLevel

The mod_jk log level, can be debug, info, warn error or trace.
The default value is info.

JkLogStampFormat

The mod_jk date log format, using an extended strftime syntax. This format will be used for the time stamps in the JkLogFile. The maximum length of the format is 63 characters.
Starting with version 1.2.24 of mod_jk you can also use %Q for adding milliseconds to the log and %q for microseconds. These conversion specifiers are an extension to strftime. They will only work on platforms with a gettimeofday() function. You can use %Q and %q only once in the pattern and also not both together in the same pattern.
The default value is "[%a %b %d %H:%M:%S %Y] " and beginning with version 1.2.24 on platforms with a gettimeofday() function it is "[%a %b %d %H:%M:%S.%Q %Y] ".

JkRequestLogFormat

Request log format string. See detailed description below.
There is no default value. Without defining a value, the request logging is turned off.

JkExtractSSL

Turns on SSL processing and information gathering by mod_jk
The default value is On.
In order to make SSL data available for mod_jk in Apache, you need to set SSLOptions +StdEnvVars. For the certificate information you also need to add SSLOptions +ExportCertData.

Specifically, mod_jk will export the following environment variables from Apache httpd to Tomcat under these request attributes as per the Servlet Specification 3.0, section 3.8:

Env VarRequest Attribute NameTypeExample
SSL_CIPHER
(or JkKEYSIZEIndicator)
javax.servlet.request.cipher_suite java.lang.String DHE-RSA-AES256-SHA
SSL_CIPHER_USEKEYSIZE
(or JkKEYSIZEIndicator)
javax.servlet.request.key_size java.lang.Integer 256
SSL_SESSION_ID
(or JkSESSIONIndicator)
javax.servlet.request.ssl_session java.lang.String 905...32E (a hex string)
SSL_CLIENT_CERT_CHAIN_n
(or JkCERTCHAINPrefixn)
javax.servlet.request.X509Certificate java.security.X509Certificate[] (A chain of certs in ascending order of trust, the first one being ths client's certificate, the second being the signer of that certificate, and so on)

In addition mod_jk sends the name of the SSL protocol used as a proprietary request attribute named AJP_SSL_PROTOCOL. Modern Tomcat versions will expose this attribute under the name org.apache.tomcat.util.net.secure_protocol_version. This feature has been added in version 1.2.41 of mod_jk. See also JkSSLPROTOCOLIndicator.

For all other SSL-related variables, use JkEnvVar for each variable you want. Please note that, like JkEnvVar, these variables are available from the request attributes, not as environment variables or as request headers.

JkHTTPSIndicator

Name of the Apache environment variable that contains SSL indication.
The default value is "HTTPS".

JkSSLPROTOCOLIndicator

Name of the Apache environment variable that contains the SSL protocol name.
The default value is "SSL_PROTOCOL".
This directive has been added in version 1.2.41 of mod_jk.

JkCERTSIndicator

Name of the Apache environment variable that contains SSL client certificates.
The default value is "SSL_CLIENT_CERT".

JkCIPHERIndicator

Name of the Apache environment variable that contains SSL client cipher.
The default value is "SSL_CIPHER".

JkCERTCHAINPrefix

Name of the Apache environment (prefix) that contains SSL client chain certificates.
The default value is "SSL_CLIENT_CERT_CHAIN_".

JkSESSIONIndicator

Name of the Apache environment variable that contains SSL session.
The default value is "SSL_SESSION_ID".

JkKEYSIZEIndicator

Name of the Apache environment variable that contains SSL key size in use.
The default value is "SSL_CIPHER_USEKEYSIZE".

JkLocalNameIndicator

Name of the Apache environment variable which can be used to overwrite the forwarded local name. Use this only if you need to adjust the data (see the proxy documentation).
The default value is "JK_LOCAL_NAME".
This directive has been added in version 1.2.28 of mod_jk.

JkIgnoreCLIndicator

Name of the Apache environment variable which forces to ignore an existing Content-Length request header. This can be used to make mod_jk conpatible with mod_deflate request body inflation (see below).
The default value is "JK_IGNORE_CL".
This directive has been added in version 1.2.41 of mod_jk.

JkLocalAddrIndicator

Name of the Apache environment variable which can be used to overwrite the forwarded local IP address. Use this only if you need to adjust the data (see the proxy documentation).
The default value is "JK_LOCAL_ADDR".
This directive has been added in version 1.2.41 of mod_jk.

JkLocalPortIndicator

Name of the Apache environment variable which can be used to overwrite the forwarded local port. Use this only if you need to adjust the data (see the proxy documentation).
The default value is "JK_LOCAL_PORT".
This directive has been added in version 1.2.28 of mod_jk.

JkRemoteHostIndicator

Name of the Apache environment variable which can be used to overwrite the forwarded remote (client) host name. Use this only if you need to adjust the data (see the proxy documentation).
The default value is "JK_REMOTE_HOST".
This directive has been added in version 1.2.28 of mod_jk.

JkRemoteAddrIndicator

Name of the Apache environment variable which can be used to overwrite the forwarded remote (client) IP address. Use this only if you need to adjust the data (see the proxy documentation).
The default value is "JK_REMOTE_ADDR".
This directive has been added in version 1.2.28 of mod_jk.

JkRemotePortIndicator

Name of the Apache environment variable which can be used to overwrite the forwarded remote (client) IP address. Use this only if you need to adjust the data (see the proxy documentation).
The default value is "JK_REMOTE_PORT".
This directive has been added in version 1.2.32 of mod_jk.

JkRemoteUserIndicator

Name of the Apache environment variable which can be used to overwrite the forwarded user name. Use this only if you need to adjust the data (see the proxy documentation).
The default value is "JK_REMOTE_USER".
This directive has been added in version 1.2.28 of mod_jk.

JkAuthTypeIndicator

Name of the Apache environment variable which can be used to overwrite the forwarded authentication type. Use this only if you need to adjust the data (see the proxy documentation).
The default value is "JK_AUTH_TYPE".
This directive has been added in version 1.2.28 of mod_jk.

JkOptions

Set one of more options to configure the mod_jk module. See below for details about this directive.
This directive can be used multiple times per virtual server.
The default value is "ForwardURIProxy" since version 1.2.24. It was "ForwardURICompatUnparsed" in version 1.2.23 and "ForwardURICompat" until version 1.2.22.

JkEnvVar

Adds a name and an optional default value of environment variable that should be sent to servlet-engine as a request attribute. If the default value is not given explicitly, the variable will only be send, if it is set during runtime.
The default is empty, so no additional variables will be sent.
This directive can be used multiple times per virtual server. The settings will be merged between the global server and any virtual server.
You can retrieve the variables on Tomcat as request attributes via request.getAttribute(attributeName). Note that the variables send via JkEnvVar will not be listed in request.getAttributeNames().
Empty default values are supported since version 1.2.20. Not sending variables with empty defaults and empty runtime value has been introduced in version 1.2.21.

JkStripSession

If this directive is set to On in some virtual server, the session IDs ;jsessionid=... will be removed for URLs which are not forwarded but instead are handled by the local server.
This directive is only allowed inside VirtualHost.
The default is Off.
This directive has been introduced in version 1.2.21.
With version 1.2.27 and later this directive can have optional session ID identifier. If not specified it defaults to ;jsessionid.

Configuration Directives Types

We'll discuss here the mod_jk directive types.

Define workers

JkWorkersFile specify the location where mod_jk will find the workers definitions. Take a look at Workers documentation for detailed description.

  JkWorkersFile     /etc/httpd/conf/workers.properties


Logging

JkLogFile specify the location where mod_jk is going to place its log file.

  JkLogFile     /var/log/httpd/mod_jk.log

Since JK 1.2.3 for Apache 2.x and JK 1.2.16 for Apache 1.3 this can also be used for piped logging:

  JkLogFile     "|/usr/bin/rotatelogs /var/log/httpd/mod_jk.log 86400"

JkLogLevel set the log level between :

  • info log will contain standard mod_jk activity (default).
  • warn log will contain non fatal error reports.
  • error log will contain also error reports.
  • debug log will contain all information on mod_jk activity
  • trace log will contain all tracing information on mod_jk activity
  
  JkLogLevel    info

info should be your default selection for normal operations.

JkLogStampFormat will configure the date/time format found on mod_jk log file. See above for details.

  JkLogStampFormat "[%Y-%m-%d %H:%M:%S.%Q] "



You can log mod_jk information using the Apache standard module mod_log_config. The module sets several notes in the Apache httpd notes table. Most of them are are only useful in combination with a load balancer worker.

NoteDescription
JK_WORKER_NAMEName of the worker selected by the URI mapping
JK_WORKER_TYPEType of the worker selected by the URI mapping
JK_WORKER_ROUTEActual worker name selected by the URI mapping (usually a member of the load balancer).
Before version 1.2.26 only available if JkRequestLogFormat is set.
JK_REQUEST_DURATIONRequest duration in seconds and microseconds.
Before version 1.2.26 only available if JkRequestLogFormat is set.
JK_LB_FIRST_NAMELoad-Balancer: Name of the first worker tried
JK_LB_FIRST_TYPELoad-Balancer: Type of the first worker tried
JK_LB_FIRST_ACCESSEDLoad-Balancer: Access count for the first worker tried
JK_LB_FIRST_SESSIONSLoad-Balancer: Count of created sessions for the first worker tried
JK_LB_FIRST_READLoad-Balancer: Bytes read for the first worker tried
JK_LB_FIRST_TRANSFERREDLoad-Balancer: Bytes transferred for the first worker tried
JK_LB_FIRST_ERRORSLoad-Balancer: Error count for the first worker tried
JK_LB_FIRST_BUSYLoad-Balancer: Busy count for the first worker tried
JK_LB_FIRST_ACTIVATIONLoad-Balancer: Activation state for the first worker tried
JK_LB_FIRST_STATELoad-Balancer: Error state for the first worker tried
JK_LB_LAST_NAMELoad-Balancer: Name of the last worker tried
JK_LB_LAST_TYPELoad-Balancer: Type of the last worker tried
JK_LB_LAST_ACCESSEDLoad-Balancer: Access count for the last worker tried
JK_LB_LAST_SESSIONSLoad-Balancer: Count of created sessions for the last worker tried
JK_LB_LAST_READLoad-Balancer: Bytes read for the last worker tried
JK_LB_LAST_TRANSFERREDLoad-Balancer: Bytes transferred for the last worker tried
JK_LB_LAST_ERRORSLoad-Balancer: Error count for the last worker tried
JK_LB_LAST_BUSYLoad-Balancer: Busy count for the last worker tried
JK_LB_LAST_ACTIVATIONLoad-Balancer: Activation state for the last worker tried
JK_LB_LAST_STATELoad-Balancer: Error state for the last worker tried

  LogFormat     "%h %l %u %t \"%r\" %>s %b %{JK_WORKER_NAME}n %{JK_LB_FIRST_NAME}n \
                 %{JK_LB_FIRST_BUSY}n %{JK_LB_LAST_NAME}n %{JK_LB_LAST_BUSY}n" mod_jk_log
  CustomLog     logs/access_log     mod_jk_log


You can also log a request protocol in the mod_jk log file instead of the access log. This is not recommended and mostly a backward compatibility feature. The directive JkRequestLogFormat will configure the format of this protocol. It gets configured and enabled on a per virtual host basis. To enable request logging for a virtual host just add a JkRequestLogFormat config. The syntax of the format string is similar to the Apache LogFormat command, here is a list of the available request log format options:

OptionsDescription
%bBytes sent, excluding HTTP headers (CLF format)
%BBytes sent, excluding HTTP headers
%HThe request protocol
%mThe request method
%pThe canonical Port of the server serving the request
%qThe query string (prepended with a ? if a query string exists, otherwise an empty string)
%rFirst line of request
%sRequest HTTP status code
%TRequest duration, elapsed time to handle request in seconds '.' micro seconds
%UThe URL path requested, not including any query string.
%vThe canonical ServerName of the server serving the request
%VThe server name according to the UseCanonicalName setting
%wTomcat worker name
%RReal worker name

  JkRequestLogFormat     "%w %V %T"


Forwarding

The directive JkOptions allow you to set many forwarding options which will enable (+) or disable (-) following option. Without any leading signs, options will be enabled.

The four following options +ForwardURIxxx are mutually exclusive. Exactly one of them is required, a negative sign prefix is not allowed with them. The default value is "ForwardURIProxy" since version 1.2.24. It was "ForwardURICompatUnparsed" in version 1.2.23 and "ForwardURICompat" until version 1.2.22. You can turn the default off by switching on one of the other two options. You should leave this at it's default value, unless you have a very good reason to change it.

All options are inherited from the global server to virtual hosts. Options that support enabling (plus options) and disabling (minus options), are inherited in the following way:

options(vhost) = plus_options(global) - minus_options(global) + plus_options(vhost) - minus_options(vhost)

Using JkOptions ForwardURIProxy, the forwarded URI will be partially reencoded after processing inside Apache httpd and before forwarding to Tomcat. This will be compatible with local URL manipulation by mod_rewrite and with URL encoded session ids.

  JkOptions     +ForwardURIProxy


Using JkOptions ForwardURICompatUnparsed, the forwarded URI will be unparsed. It's spec compliant and secure. It will always forward the original request URI, so rewriting URIs with mod_rewrite and then forwarding the rewritten URI will not work.

  JkOptions     +ForwardURICompatUnparsed


Using JkOptions ForwardURICompat, the forwarded URI will be decoded by Apache httpd. Encoded characters will be decoded and explicit path components like ".." will already be resolved. This is less spec compliant and is not safe if you are using prefix JkMount. This option will allow to rewrite URIs with mod_rewrite before forwarding.

  JkOptions     +ForwardURICompat


Using JkOptions ForwardURIEscaped, the forwarded URI will be the encoded form of the URI used by ForwardURICompat. Explicit path components like ".." will already be resolved. This will not work in combination with URL encoded session IDs, but it will allow to rewrite URIs with mod_rewrite before forwarding.

  JkOptions     +ForwardURIEscaped


JkOptions RejectUnsafeURI will block all URLs, which contain percent signs '%' or backslashes '\' after decoding.

Most web apps do not use such URLs. Using the option RejectUnsafeURI, you can block several well known URL encoding attacks. By default, this option is not set.

You can also realise such a check with mod_rewrite, which is more powerful but also slightly more complicated.

  
  JkOptions     +RejectUnsafeURI


JkOptions CollapseSlashesAll will collapse multiple adjacent slashes in request URLs before looking for mount or unmount matches.

  JkOptions     +CollapseSlashesAll


JkOptions CollapseSlashesUnmount will collapse multiple adjacent slashes in request URLs only before looking for unmount matches. This is the default value.

  JkOptions     +CollapseSlashesUnmount


JkOptions CollapseSlashesNone will never collapse multiple adjacent slashes in request URLs before looking for mount or unmount matches. Using this value might make you vulnerable for attacks bypassing your unmount rules.

  JkOptions     +CollapseSlashesNone


JkOptions ForwardDirectories is used in conjunction with DirectoryIndex directive of Apache web server. As such mod_dir should be available to Apache, statically or dynamically (DSO)

When DirectoryIndex is configured, Apache will create sub-requests for each of the local-url's specified in the directive, to determine if there is a local file that matches (this is done by stat-ing the file).

If ForwardDirectories is set to false (default) and Apache doesn't find any files that match, Apache will serve the content of the directory (if directive Options specifies Indexes for that directory) or a 403 Forbidden response (if directive Options doesn't specify Indexes for that directory).

If ForwardDirectories is set to true and Apache doesn't find any files that match, the request will be forwarded to Tomcat for resolution. This is used in cases when Apache cannot see the index files on the file system for various reasons: Tomcat is running on a different machine, the JSP file has been precompiled etc.

Note that locally visible files will take precedence over the ones visible only to Tomcat (i.e. if Apache can see the file, that's the one that's going to get served). This is important if there is more then one type of file that Tomcat normally serves - for instance Velocity pages and JSP pages.

  
  JkOptions     +ForwardDirectories


Setting JkOptions ForwardLocalAddress, you ask mod_jk to send the local address, of the Apache web server instead remote client address. This can be used by Tomcat remote address valve for allowing connections only from registered Apache web servers.

  
  JkOptions     +ForwardLocalAddress


Setting JkOptions ForwardPhysicalAddress, you ask mod_jk to send the physical peer TCP IP address as the client address. By default mod_jk uses the logical address as provided by the web server. For example the module mod_remoteip sets the logical IP address to the client IP forwarded by proxies in the X-Forwarded-For header.

  
  JkOptions     +ForwardPhysicalAddress


JkOptions FlushPackets, you ask mod_jk to flush Apache's connection buffer after each AJP packet chunk received from Tomcat. This option can have a strong performance penalty for Apache and Tomcat as writes are performed more often than would normally be required (ie: at the end of each response).

  
  JkOptions     +FlushPackets


JkOptions FlushHeader, you ask mod_jk to flush Apache's connection buffer after the response headers have been received from Tomcat.

  
  JkOptions     +FlushHeader


JkOptions DisableReuse, you ask mod_jk to close connections immediately after their use. Normally mod_jk uses persistent connections and pools idle connections to reuse them, when new requests have to be sent to Tomcat.

Using this option will have a strong performance penalty for Apache and Tomcat. Use this only as a last resort in case of unfixable network problems. If a firewall between Apache and Tomcat silently kills idle connections, try to use the worker attribute socket_keepalive in combination with an appropriate TCP keepalive value in your OS.

  
  JkOptions     +DisableReuse


JkOptions ForwardKeySize, you ask mod_jk, when using ajp13, to forward also the SSL Key Size as required by Servlet API 2.3. This flag shouldn't be set when servlet engine is Tomcat 3.2.x (on by default).

  
  JkOptions     +ForwardKeySize


JkOptions ForwardSSLCertChain, you ask mod_jk, when using ajp13, to forward SSL certificate chain (off by default). Mod_jk only passes the SSL_CLIENT_CERT to the AJP connector. This is not a problem with self-signed certificates or certificates directly signed by the root CA certificate. However, there's a large number of certificates signed by an intermediate CA certificate, where this is a significant problem: A servlet will not have the possibility to validate the client certificate on its own. The bug would be fixed by passing on the SSL_CLIENT_CERT_CHAIN to Tomcat via the AJP connector.
This directive exists only since version 1.2.22.

  
  JkOptions     +ForwardSSLCertChain


The directive JkEnvVar allows you to forward environment variables from Apache server to Tomcat engine. You can add a default value as a second parameter to the directive. If the default value is not given explicitly, the variable will only be send, if it is set during runtime.
The variables can be retrieved on the Tomcat side as request attributes via request.getAttribute(attributeName). Note that the variables send via JkEnvVar will not be listed in request.getAttributeNames().

The variables are inherited from the global server to virtual hosts.

  
  JkEnvVar     SSL_CLIENT_V_START     undefined


Assigning URLs to Tomcat

If you have created a custom or local version of mod_jk.conf-local as noted above, you can change settings such as the workers or URL prefix.

JkMount directive assign specific URLs to Tomcat. In general the structure of a JkMount directive is:

  
  JkMount [URL prefix] [Worker name]
  # send all requests ending in .jsp to worker1
  JkMount /*.jsp worker1
  # send all requests ending /servlet to worker1
  JkMount /*/servlet/ worker1
  # send all requests jsp requests to files located in /otherworker will go worker2
  JkMount /otherworker/*.jsp worker2

You can use the JkMount directive at the top level or inside <VirtualHost> sections of your httpd.conf file.

JkUnMount directive acts as an opposite to JkMount and blocks access to a particular URL. The purpose is to be able to filter out the particular content types from mounted context. The following example mounts /servlet/* context, but all .gif files that belongs to that context are not served.

  # send all requests ending with /servlet to worker1
  JkMount /servlet/* worker1
  # do not send requests ending with .gif to worker1
  JkUnMount /servlet/*.gif worker1

JkUnMount takes precedence over JkMount directives, meaning that the JK will first try to mount and then checks, if there is an exclusion defined by a JkUnMount. A JkUnMount overrides a JkMount only, if the worker names in the JkMount and in the JkUnMount are the same.

The following example will block all .gif files although there is a JkMount for them:

  # do not send requests ending with .gif to worker1
  JkUnMount /*.gif worker1
  # The .gif files will not be mounted cause JkUnMount takes
  # precedence over JkMount directive
  JkMount /servlet/*.gif worker1

Starting with version 1.2.26 of JK you can apply a JkUnMount to any worker, by using the star character '*' as the worker name in the JkUnMount. More complex patterns in JkUnMount worker names are not allowed.

  # Mapping the webapps myapp1 and myapp2:
  /myapp1/*=worker1
  /myapp2/*=worker2
  # Exclude the all subdirectories static for all workers:
  !/*/static/*=*
  # Exclude some suffixes for all workers:
  !*.html=*

JkAutoAlias directive automatically Alias webapp context directories into the Apache document space. It enables Apache to serve a static context while Tomcat serving dynamic context. This directive is used for convenience so that you don't have to put an apache Alias directive for each application directory inside Tomcat's webapp directory. For security reasons it is strongly recommended that JkMount is used to pass all requests to Tomcat by default and JkUnMount is used to explicitly exclude static content to be served by httpd. It should also be noted that content served by httpd will bypass any security constraints defined in the application's web.xml.

  # enter the full path to the tomcat webapps directory
  JkAutoAlias /opt/tomtact/webapps

The following example shows how to serve a dynamic context by Tomcat and static using Apache. The webapps directory has to be accessible by apache.

  # enter the full path to the tomcat webapps directory
  JkAutoAlias /opt/tomtact/webapps

  # Mount 'servlets-examples' directory. It's physical location
  # is assumed to be in the /opt/tomtact/webapps/servlets-examples
  # ajp13w is a worker defined in the workers.properties
  JkMount /servlets-examples/* ajp13w

  # Unmount desired static content from servlets-examples webapp.
  # This content will be served by the httpd directly.
  JkUnMount /servlets-examples/*.gif ajp13w
  JkUnMount /servlets-examples/*.jpg ajp13w

Note that you can have a single JkAutoAlias directive per virtual host inside your httpd.conf

JkWorkerProperty is a new directive available from JK 1.2.7 version. It is a convenient method for setting directives that are usually set inside workers.propeties file. The parameter for that directive is raw line from workers.properties file.

  # Just like workers.properties but exact line is prefixed
  # with JkWorkerProperty

  # Minimal jk configuration
  JkWorkerProperty worker.list=ajp13w
  JkWorkerProperty worker.ajp13w.type=ajp13
  JkWorkerProperty worker.ajp13w.host=localhost
  JkWorkerProperty worker.ajp13w.port=8009   

JkMountFile is a new directive available from JK 1.2.9 version. It is used for dynamic updates of mount points at runtime. When the mount file is changed, JK will reload it's content.

  # Load mount points

  JkMountFile conf/uriworkermap.properties

If the mount point uri starts with an exclamation mark '!' it defines an exclusion in the same way JkUnMount does. If the mount point uri starts with minus sign '-' the mount point will only be disabled. A disabled mount can be reenabled by deleting the minus sign and waiting for the JkMountFile to reload. An exclusion can be disabled by prefixing it with a minus sign.

  # Sample uriworkermap.properties file

  /servlets-examples/*=ajp13w
  # Do not map .jpeg files
  !/servlets-examples/*.jpeg=ajp13w
  # Make jsp examples initially disabled  
  -/jsp-examples/*=ajp13w

At run time you can change the content of this file. For example removing minus signs will enable the previously disabled uri mappings. You can add any number of new entries at runtime that reflects the newly deployed applications. Apache will reload the file and update the mount points within 60 second interval.

There is no way to delete entries by dynamic reloading, but you can disable or exclude mappings.

Using SetHandler and Environment Variables

Alternatively to the mod_jk specific directives, you can also use SetHandler and environment variables to control, which requests are being forwarded via which worker. This gives you more flexibility, but the results might be more difficult to understand. If you mix both ways of defining the forwards, in general to mod_jk directives will win.

SetHandler jakarta-servlet forces requests to be handled by mod_jk. If you neither specify any workers via JkMount and the related directives, not via the environment variable described below, the first worker in the list of all worker will be chosen. You can use SetHandler for example in Location blocks or with Apache 2.2 and later also in RewriteRule.

In order to control the worker using SetEnvIf or RewriteRule for more complex rules, you can set the environment variable JK_WORKER_NAME to the name of your chosen target worker. This enables you to decide on the chosen worker in a more flexible way, including dependencies on cookie values. This feature has been added in version 1.2.19 of mod_jk. Furthermore you might append rule extensions to the worker name. The extensions are separated from the worker name by a semicolon ";" using the same syntax as in the uriworkermap.properties file. Supporting rule extensions in the worker name has been added in version 1.2.33.

In order to use another variable than JK_WORKER_NAME, you can set the name of this variable via the JkWorkerIndicator directive.

You can also define exclusions from mod_jk forwards by setting the environment variable no-jk.

  # Automatically map all encoded urls
  <Location *;jsessionid=>
    SetHandler jakarta-servlet
    SetEnv JK_WORKER_NAME my_worker
  </Location>

  # Map all subdirs to workers via naming rule
  # and exclude static content.
  <Location /apps/>
    SetHandler jakarta-servlet
    SetEnvIf REQUEST_URI ^/apps/([^/]*)/ JK_WORKER_NAME=$1
    SetEnvIf REQUEST_URI ^/apps/([^/]*)/static no-jk
  </Location>
Advanced Environment Variables

Environment variables allow to overwrite the default behaviour of mod_jk depending on request properties like e.g. the request URI, header values or cookie. This can be done using the SetEnvIf or RewriteRule directives.

The environment variable JK_ROUTE can be set to explicitely choose a member of a load balancer worker. The value must be equal to the route attribute of the member, or if that attribute is not used, equal to the member name. Note that this is only needed if session IDs and routes are encoded in a non standard way in the request. Stickyness using the Java Servlet compliant way of encoding the IDs is supported by default. This is available since version 1.2.33.

The environment variable JK_REPLY_TIMEOUT can be set to dynamically define a reply timeout. The value must be given in milliseconds. This is available since version 1.2.27.

The environment variable JK_STICKY_IGNORE can be set to disable session stickyness for individual requests. If the variable is set to an empty string or a nonzero number, session stickyness will be disabled. Setting it to 0 will reset to the behaviour defined by the worker configuration. This is available since version 1.2.33.

This feature can be useful to optimize load balancing when using cookie based session stickyness. In this case, as long as she keeps her browser open, any request by a user who started a session will be send to the same Tomcat instance, even if he left the part of the application which uses the session. You can for instance set this environment variable when a user requests a login form to ensure, that this initial session request is balanced non-sticky.

The environment variable JK_STATELESS can be used to improve load balancing for the session based balancing methods Session and Next. In this case normally any request which does not come with a session id counts as a new session. This can be problematic, if for instance static content is retrieved without a session id. If you set the environment variable JK_STATELESS for a request, then the request will not count as a new session, even if it does not come with a session id. This is available since version 1.2.33.

The environment variable JK_IGNORE_CL can be set to force ignoring the request Content-Length header (if it exists). mod_jk will then stream the request body until the web server indicates that the full body was read. No Content-Length header will be send to the backend. This is available since version 1.2.41.

This feature can be used to make mod_jk compatible with filters which change the size of the request body. One such filter is mod_deflate when used to inflate the body of a request with gzip encoded body. In this case mod_jk will by default forward a truncated body, because it gets the wrong body size from the web server. Telling mod_jk to ignore the Content-Length header will result in streaming all request body data it can read from the web server to the backend.

You should only set the JK_IGNORE_CL environment variables for requests that actually need it. Unfortunately there's no way for mod_jk to detect the need automatically.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/reference/printer/status.html0000644000000000000020000006513612555256555023127 0ustar rootbinThe Apache Tomcat Connectors - Reference Guide - Status Worker Reference
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Reference Guide

Status Worker Reference

Introduction

Tomcat Connectors has a special type of worker, the so-called status worker. The status worker does not forward requests to Tomcat instances. Instead it allows to retrieve status and configuration information at runtime, and furthermore to change many configuration items dynamically. This can be done via a simple embedded web interface.

The status worker is especially powerful, when used together with load balancing workers.

This document does not explain the HTML user interface of the status worker. Until now it is very simple, so just go ahead and use it. This doc instead tries to explain the less obvious features of the status worker. We also will give a complete coverage of the various request parameters and their meaning, so that you can include the status worker in your automation scripts.

The documentation of the status worker starts with jk 1.2.20

Usage Patterns

Actions

The status worker knows about the following actions:

  • list: lists the configurations and runtime information of all configured workers. The output will be grouped by global information first (version data), then load balancer information, after that AJP worker information and finally the legend. For load balancers, there will be a summary part, and after that details for each member worker. For all workers, we also include the URL mappings (forward definitions).
  • show: the same as list, but only shows data for one chosen worker
  • edit: produces a form to edit configuration data for a chosen worker. There is a special subtype of "edit", that makes it easy to change one attribute for all members of a load balancer, e.g. their activation state.
  • update: commit changes made in an edit form. Caution: the changes will not be persisted to the configuration files. As soon as your restart your web server, all changes made through the status worker will be lost! On the other hand, the changes done by the status worker will be applied during runtime without a restart of the web server.
  • reset: reset all runtime statistics for a worker.
  • recover: Mark a member of a load balancer, that is in error state, for immediate recovery.
  • version: only show version information of the web server and the JK software
  • dump: list the original workers configuration. Caution: the dump will only contain the configuration that was used during startup. Any changes applied later by the dynamic management interface of the status worker itself will not be contained in this dump. The dump action has been added in version 1.2.27.

Output Format

For most actions you can choose between 4 output formats.

  • HTML: Used interactively with a browser
  • XML: Mostly useful for automation, when your scripting environment is XML friendly. This format has rich structure information, but does not work line based, so you would really like to use it together with XML tools.
  • Properties: This format is a line based format, that conforms to the rules of Java property files. Most structure information is contained in the hierarchical key. For information, that is of configuration nature, the format should produce lines very similar to the ones you can use in workers.properties. It will not produce a complete configuration file!
  • Text: A simple textual output format.
The "edit" action does only make sense for the HTML output type.

User Interface Features

In the HTML view, there is an automatic refresh feature, implemented via the meta refresh option of HTML. Once you start the automatic refresh, the UI will will respect it for all actions except edit, update and maintain. Even if you navigate through one of those, the automatic refresh will start again as soon as you come back to one of the other actions.

Many parts of the HTML page can be minimised, if they are not interesting for you. There are a couple of "Hide" links, which will collapse parts of the information. The feature exists for the following blocks of information:

  • Legend: Do not show the legend for the information presented in "list" and "show" actions
  • URI mappings: Do not show the URI mapping for the workers
  • Load Balancing Workers: Do not show workers of type "lb"
  • AJP Workers: Do not show workers of type ajp
  • Balancer Members: Do not show detailed information concerning each member of load balancers
  • Load Balancer Configuration: Do not show configuration data for load balancers
  • Load Balancer Summary: Do not show status summary for load balancers
  • AJP Configuration: Do not show configuration data for ajp workers load balancer members
The last three minimisation features have been added in version 1.2.27.

Special Considerations concerning URL Maps and Virtual Hosts

Note: The following restriction has been removed starting with version 1.2.26.

The Apache module mod_jk makes use of the internal Apache httpd infrastructure concerning virtual hosts. The downside of this is, that the status worker can only show URL maps, for the virtual host it is defined in. It is not able to reach the configuration objects for other virtual hosts. Of course you can define a status worker in any virtual host you are using. All information presented apart from the URL maps will be the same, independent of the virtual host the status worker has been called in.

Logging

The status worker will log changes made to the configuration with log level "info" to the usual JK log file. Invalid requests will be logged with log level "warn". If you want to report some broken behaviour, log file content of level "debug" or even "trace" will be useful.

Configuration

Basic Configuration

The basic configuration of a status worker is very similar to that of a usual ajp worker. You need to specify a name for the worker, and the URLs you want to map to it. The first part of the configuration happens in the workers.properties file. We define a worker named mystatus of type status:

worker.list=mystatus
worker.mystatus.type=status
Then we define a URL, which should be mapped to this worker, i.e. the URL we use to reach the functionality of the status worker. You can use any method mod_jk supports for the web server of your choice. Possibilities are maps inside uriworkermap.properties, an additional mount attribute in workers.properties, or in Apache JkMount. Here's an example for a uriworkermap.properties line:
/private/admin/mystatus=mystatus
The URI pattern is case sensitive.

As you will learn in the following sections, the status worker is very powerful. You should use the usual authentication and authorisation methods of your web server to secure this URL.

You can also define multiple instances of the status worker, by using different names and URL mappings. For instance you might want to configure them individually and then allow special groups of people to use them

Output Customisation

There are a couple of attributes for the workers.properties entries, which allow to customise various aspects of the output of the status worker.

The attribute css can be set to the URL of a stylesheet:

worker.mystatus.css=/private/admin/static/mystatus.css
When writing HTML output, the status worker then includes the line
<link rel="stylesheet" type="text/css" href="/private/admin/static/mystatus.css" />
There is no sample stylesheet included with the mod_jk release, and by default the attribute css is empty, so no stylesheet reference will be included in the pages. The HTML code of the status worker output pages does not include any class attributes. If you like to contribute a stylesheet or improvements to the HTML layout, please contact us on the tomcat developers list.

The properties output format can be customised via the attribute prefix. The names of all properties the status worker does output, will begin with this prefix. The default is "worker".

Several attributes influence the format when writing XML output. The attribute ns allows to set a namespace prefix, that will be used for every status worker+element. The default is "jk:". Setting it to "-" disables the namespace prefix.

With the attribute xmlns you can map the prefix to a namespace URL. The default value is xmlns:jk="http://tomcat.apache.org". Setting it to "-" disables the output of the URL.

Finally you can specify an XML document type via the attribute doctype. The specified string will be inserted at the beginning of the document, directly after the xml header. The default is empty.

Securing Access

We urge you to use the builtin access control features of your web server to control access to the status worker URLs you have chosen. Nevertheless two configuration attributes of status workers are helpful. The attribute "read_only" disables all features of the status worker, that can be used to change configurations or runtime status of the other workers. A read_only status worker will not allow access to the edit, update, reset or recover actions. The default value is false, ie. read/write. To enable read_only you need to set it to true.

You could configure two status workers, one has read_only and will be made available to a larger admin group, the other one will be used fully featured, but only by fewer people:

worker.list=jk-watch
worker.jk-watch.type=status
worker.jk-watch.read_only=true
worker.jk-watch.mount=/user/status/jk
worker.list=jk-manage
worker.jk-manage.type=status
worker.jk-manage.mount=/admin/status/jk
Starting with version 1.2.21, a read/write status worker can also be switched temporarily into read-only mode by the user via a link in the HTML GUI. The user can always switch it back to read/write. Only a status worker configured as read-only via the "read_only" attribute is completely safe from applying any changes.

The other attribute you can use is user. By default this list is empty, which means no limit on the users. You can set "user" to a comma separated list of user names. If your web server is configured such that it sends the user names with the request, the status worker will check, if the name attached with the request is contained in it's "user" list.

The user list can be split over multiple occurrences of the "user" attribute.

By default, the user names are matched case sensitively. Starting with version 1.2.21 you can set the attribute user_case_insensitive to true. Then the comparison will be made case insensitive.

Service Availability Rating

For load balancing workers the status worker shows some interesting overview information. It categorises the members of the load balancer into the classes "good", "bad" and degraded". This feature can be combined with external escalation procedures. Depending on your global system design and your operating practises your preferred categorisation might vary.

The categorisation is based on the activation state of the workers (active, disabled or stopped), which is a pure configuration state, and the runtime state (OK or ERR with possible substates idle, busy, recovering, probing, and forced recovery) which only depends on the runtime situation.

The runtime substates have the following meaning:

  • OK (idle): This worker didn't receive any request since the last balancer maintenance. By default balancer maintenance runs every 60 seconds. The worker should be OK, but since we didn't have to use it for some time, we can't be sure. This state has been called N/A before version 1.2.24.
  • OK (busy): All connections for this worker are in use for requests.
  • ERROR (recovering): The worker was in error state for some time and is now marked for recovery. The next request suitable for this worker will use it.
  • ERROR (probing): After setting the worker to recovering, we received a request suitable for this worker. This request is now using the worker.
  • ERROR (forced recovery): The worker is in error, but we don't have an alternative worker, so we keep using it.

By default the status worker groups into "good" all members, that have activation "active" and runtime state not equal to "error" with empty substate. The "bad" group consists of the members, that have either activation "stopped", or are in runtime state "error" with empty substate.

Workers that fit neither of the two groups, are considered to be "degraded".

You can define other rules for the grouping into good, bad and degraded. The two attributes "good" and "bad" can be populated by a comma-separated list ob single characters or dot-separated pairs. Each character stands for the first character of one of the possible states "active", "disabled", "stopped", "ok", "idle", "busy", "recovering" and "error". The additional states "probing" and "forced recovery" are always rated equivalent to "recovering". Comma-separated entries will be combined with logical "or", if you combine a configuration and a runtime state with a dot. the are combined with logical "and". So the default value for "good" is "a.o,a.i,a.b,a.r", for "bad" it is "e,s".

The status worker first tries to match against the "bad" definitions, if this doesn't succeed it tries to match against "good", and finally it chooses "degraded", if no "bad" or "good" match can be found.

Request Parameters

This section should help you building automation scripts based on the jk status management interface. This interface is stable in the sense, that we only expect to add further parameters in the future. Existing parameters from previous versions will keep their original semantics. We also expect the output formats XML, Properties and Text to be kept stable. So please use those, if you want to parse status worker output in your automation scripts.

Actions

The action is determined by the parameter cmd. It can have the values "list", "show", "edit", "update", "reset", "recover", "version" and "dump". If you omit the cmd parameter, the default "list" will be used. All actions except for "list", "refresh", "version" and "dump" need additional parameters.

The action "dump" has been added in version 1.2.27.

Output Format

The format is determined by the parameter mime. It can have the values "html", "xml", "txt" and "prop". If you omit the mime parameter, the default "html" will be used. The action "edit" (the edit form) does only make sense for "mime=html".

Worker Selection

Actions that operate on a single worker need one or two additional parameters to select this worker. The parameter w contains the name of the worker from the worker list. If an action operates on a member (sub worker) of a load balancer, the parameter w contains the name of the load balancer worker, and the additional parameter sw contains the name of the sub worker.

Automatic Refresh

During automatic refresh, the parameter re contain the refresh interval in seconds. If you omit this parameter, automatic refresh will be off.

Hide Options

The parameter opt contains a bit mask of activated options. The default is 0, so by default no options are activated. The following options exist:

  • 0x0001: hide members of lb workers
  • 0x0002: hide URL maps
  • 0x0004: hide the legend
  • 0x0008: hide load balancer workers
  • 0x0010: hide ajp workers
  • 0x0020: only allow read_only actions for a read/write status worker.
  • 0x0040: hide load balancer configuration
  • 0x0080: hide load balancer status summary
  • 0x0100: hide configuration for ajp and load balancer member workers
Values 0x0040-0x0100 have been added in version 1.2.27.

Data Parameters for the standard Update Action

You can use the edit action with a final click to the update button, to change settings of workers. But you can also make direct calls to the update action. The following request parameters contain the configuration information, you want to change. First the list for load balancer workers:

  • vlr: retries (number)
  • vlt: recover_time (seconds)
  • vlee: error_escalation_time (seconds)
  • vlx: max_reply_timeouts (number)
  • vls: sticky_session (0/f/n/off=off, 1/t/y/on=on; case insensitive)
  • vlf: sticky_session_force (0/f/n/off=off, 1/t/y/on=on; case insensitive)
  • vlm: method (0/r="Requests", 1/t="Traffic", 2/b="Busyness", 3/s="Sessions", 4/s="Next"; case insensitive, only first character is used)
  • vll: lock (0/o="Optimistic", 1/p="Pessimistic"; case insensitive, only first character is used)
And now the list of parameters you can use to change settings for load balancer members:
  • vwa: activation flag (0/a="active", 1/d="disabled", 2/s="stopped"; case insensitive, only first character is used)
  • vwf: load balancing factor (integer weight)
  • vwn: route for use with sticky sessions (string)
  • vwr: redirect to define simple failover rules (string)
  • vwc: domain to tell JK about your replication design (string)
  • vwd: distance to express preferences (integer)
Finally the list of parameters you can use to change settings for ajp workers and ajp load balancer members:
  • vahst: host (string)
  • vaprt: port (number)
  • vacpt: connection_pool_timeout (number)
  • vact: connect_timeout (number)
  • vapt: prepost_timeout (number)
  • vart: reply_timeout (number)
  • var: retries (number)
  • varo: recovery_options (number)
  • vabl: busy_limit (number)
  • vamps: max_packet_size (number)
Note that changing the host name or port will only take effect for new connections. Already established connections to the old address will still be used. Nevertheless this feature is interesting, because you can provision load balancer members with port "0", which will automatically be stopped during startup. Later when you know the final names and ports, you can set them and they will be automatically activated.

The leading character "v" has been added to the parameters in version 1.2.27. Changing settings for ajp workers has also been introduced in version 1.2.27.

For the details of all parameters, we refer to the workers.properties Reference.

Aspect Editing for Load Balancer Members

You can use the edit action to edit all settings for a load balancer or for a member of a load balancer respectively on one page. If you want to edit one configuration aspect for all members of a load balancer simultaneously, this will be triggered by the parameter att. The value of the parameter indicates, which aspect you want to edit. The list is the same as in the previous section, except for "vahst" and "vaprt": "vwa", "vwf", "vwn", "vwr", "vwc", "vwd", "vacpt", "vact", "vapt", "vart", "var", "varo", "vabl" and "vamps". But here you need to put the name into the parameter att, instead of using it as a request parameter name.

The values of the common aspect for all the load balancer members will be given in parameters named "val0", "val1", ....


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/reference/printer/uriworkermap.html0000644000000000000020000005426512555256555024334 0ustar rootbinThe Apache Tomcat Connectors - Reference Guide - uriworkermap.properties configuration
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Reference Guide

uriworkermap.properties configuration

Introduction

The forwarding of requests from the web server to tomcat gets configured by defining mapping rules. Such a rule maps requests to workers. The request part of the map is described by a URI pattern, the worker by it's worker name.

The so-called uriworkermap file is a mechanism of defining rules, which works for all web servers. There exist also other web server specific configuration options for defining rules, which will be mostly discussed on the reference pages for configuring tomcat connectors for the individual web servers.

The name of the file is usually uriworkermap.properties, although this is configurable in the web server. Please consult the web server specific documentation pages on how to enable the uriworkermap file.

The main features supported by the uriworkermap file are

  • Support for comments in the rule file.
  • Exact and wildchar matches, shortcuts to map a directory and all including content.
  • Exclusion rules, disabling of rules and rule priorities.
  • Rule extensions, modifying worker behaviour per rule.
  • Virtual host integration: uri mapping rules can be expressed per virtual host. The details are web server specific though.
  • Dynamic reloading: The file gets checked periodically for changes. New versions are automatically reloaded without web server restarts.
  • Integration with the status worker.
The following sections describe these aspects in more detail.

Syntax

Line format

The file has a line based format. There are no continuation characters, so each rule needs to be defined on a single line. Each rule is a pair consisting of a URI pattern and a worker name, combined by an equals sign '=':

  /myapp=myworker
The URI pattern is case sensitive.

Comments, white space

All text after and including the character '#' gets ignored and can be used for comments. Leading and trailing white space gets trimmed around the URI pattern and also around the worker name. The following definitions are all equivalent:

  # This is a white space example
  /myapp=myworker
     /myapp=myworker
  /myapp  =  myworker

URI patterns

Inside the URI pattern three special characters can be used, '*', '?' and '|'. The character '*' is a wildchar that matches any number of arbitrary characters in the URI, '?' matches exactly one character. Each URI pattern has to start with the character '/', or with '*' or with '?', optionally prefixed by any combination of the modifiers '!' and '-' (see next section).

  # Mapping the URI /myapp1 and everything under /myapp1/:
  /myapp1=myworker-a
  /myapp1/*=myworker-a
  # Mapping all URI which end with a common suffix:
  *.jsp=myworker
  *.do=myworker
Since the first case of mapping a certain location and everything inside it is very common, the character '|' gives a handy shortcut:
  # Mapping the URI /myapp1 and everything under /myapp1/:
  /myapp1|/*=myworker-a
The pattern 'X|Y' is exactly equivalent to the two maps 'X' and 'XY'.

Exclusion, Disabling and Priorities

Exclusions and rule disabling

Exclusion rules allows to define exclusions from URI rules, which would forward requests to tomcat. If the exclusion rule matches, the request will not be forwarded. This is usually used to serve static content by the web server. A rule is an exclusion rule, if it is suffixed with '!':

  # Mapping the URI /myapp and everything under /myapp/:
  /myapp|/*=myworker
  # Exclude the subdirectory static:
  !/myapp/static|/*=myworker
  # Exclude some suffixes:
  !*.html=myworker
An exclusion rule overrides a normal mapping rule only, if the worker names in the normal rule and in the exclusion rule are the same. Starting with version 1.2.26 of JK you can apply an exclusion rule to any worker, by using the star character '*' as the worker name in the exclusion rule. More complex patterns in exclusion worker names are not allowed.
  # Mapping the webapps /myapp1 and /myapp2:
  /myapp1|/*=myworker1
  /myapp2|/*=myworker2
  # Exclude the all subdirectories static for all workers:
  !/*/static|/*=*
  # Exclude some suffixes for all workers:
  !*.html=*

Rule disabling comes into play, if your web server merges rules from various sources, and you want to disable any rule defined previously. Since the uriworkermap file gets reloaded dynamically, you can use this to temporarily disable request forwarding: A rule gets disabled, if it is suffixed with '-':

  # We are not in maintenance.
  # The maintenance rule got defined somewhere else.
  -/*=maintenance
Exclusion rules can get disabled as well, then the rule starts with '-!'.

Mapping priorities

The most restrictive URI pattern is applied first. More precisely the URI patterns are sorted by the number of '/' characters in the pattern (highest number first), and rules with equal numbers are sorted by their string length (longest first).

If both distinctions still do not suffice, then the defining source of the rule is considered. Rules defined in uriworkermap.properties come first, before rules defined by JkMount (Apache) and inside workers.properties using the mount attribute.

All disabled rules are ignored. Exclusion rules are applied after all normal rules have been applied.

There is no defined behaviour, for the following configuration conflict: using literally the same URI pattern in the same defining source but with different worker targets.

Rule extensions

Rule extensions were added in version 1.2.27 and are not available in earlier versions.

Syntax

Rule extensions are additional attributes, that can be attached to any rule. They are added at the end of the rule, each extension separated by a semicolon:

  # This is an extension example,
  # setting a reply_timeout of 1 minute
  # only for this mapping.
  /myapp=myworker;reply_timeout=60000
  #
  # This is an example using multiple extensions
  /myapp=myloadbalancer;reply_timeout=60000;stopped=member1
Attributes set via rule extensions always overwrite conflicting configurations in the worker definition file.

Extension reply_timeout

The extension reply_timeout sets a reply timeout for a single mapping rule.

  # Setting a reply_timeout of 1 minute
  # only for this mapping.
  /myapp=myworker;reply_timeout=60000
It overrides any reply_timeout defined for the worker. The extension allows to set a reasonable default reply timeout to the worker, and a more relaxed reply timeout to URLs, which are known to start time intensive tasks. For a general description of reply timeouts see the timeouts documentation.

Extension sticky_ignore

The extension sticky_ignore will disable session stickyness for a single mapping rule.

  # Disable session stickyness
  # only for this mapping.
  /myapp/loginform.jsp=myworker;sticky_ignore=1
This extension can be useful to optimize load balancing when using cookie based session stickyness. In this case, as long as she keeps her browser open, any request by a user who started a session will be send to the same Tomcat instance, even if he left the part of the application which uses the session. You can for instance set this environment variable when a user requests a login form to ensure, that this initial session request is balanced non-sticky.

This extension is available since version 1.2.33.

Extension stateless

The extension stateless is only useful when using session based load balancing. In this case normally any request which does not come with a session id counts as a new session. If you mark a mapping rule with the stateless extension, then the requests matching the mapping rule will not count as a new session, even if they do not come with a session id.

  # Don't let static content trash our session balancing
  /myapp/static/*=myworker;stateless=1
This extension is available since version 1.2.33.

Extensions active/disabled/stopped

The extensions active, disabled, and stopped can be used in a load balancer mapping rule to set selected members of the load balancer into a special activation state.

  # Stop forwarding only for member1 of loadbalancer
  /myapp=myloadbalancer;stopped=member1
Multiple members must be separated by commas or white space:
  # Stop forwarding for member01 and member02 of loadbalancer
  # Disable forwarding for member21 and member22 of loadbalancer
  /myapp=myloadbalancer;stopped=member01,member02;disabled=member21,member22
For the precise meaning of the activation states see the description of activation.

Extension fail_on_status

The extension fail_on_status can be used in any rule:

  # Send 503 instead of 404 and 500,
  # and if we get a 503 also set the worker to error
  /myapp=myworker;fail_on_status=-404,-500,503
Multiple status codes must be separated by commas. For the precise meaning of the attribute see the description of fail_on_status.

Extension use_server_errors

The extension use_server_errors allows to let the web server send an error page, instead of the backend (e.g. Tomcat) error page. This is useful, if one wants to send customized error pages, but those are not part of all web applications. They can then be put onto the web server.

The value of use_server_errors is a positive number. Any request send to the backend, that returns with an http status code bigger or equal to use_server_errors, will be answered to the client with the error page of the web server for this status code.

  # Use web server error page for all errors
  /myapp=myworker;use_server_errors=400
  # Use web server error page only for technical errors
  /myotherapp=myworker;use_server_errors=500

Extensions controlling load balancer stickyness

The extensions

  • session_cookie
  • session_path
  • set_session_cookie
  • session_cookie_path
allow to define the load balancer worker attributes of the same name per mount. See their descriptions in the worker.properties configuration reference.

Virtual host integration

IIS

When using IIS you can restrict individual rules to special virtual hosts by prefixing the URI pattern with the virtual host information. The rules is that the url must be prefixed with the host name.

  # Use www.foo.org as virtual host
  /www.foo.org/myapp/*=myworker
  # Use www.bar.org as virtual host
  /www.bar.org/myapp/*=myworker
  # Normal mapping
  /mysecondapp/*=myworker

Note that /mysecondapp/* will be mapped to all virtual hosts present. In case one needs to prevent the mappings to some particular virtual host then the exclusion rule must be used

  # Make sure the myapp is accessible by all virtual hosts
  /myapp/*=myworker
  # Disable mapping myapp for www.foo.org virtual host
  !/www.foo.org/myapp/*=myworker

Apache httpd

For Apache you can define individual uriworkermap files per virtual host. The directive JkMountFile can be used in the main server and in each virtual host. If a virtual host does not use JkMountfile, but JkMountCopy is set to 'On', then it inherits the JkMountFile from the main server. If you want all vhost to inherit mounts from the main server, you can set JkMountCopy to 'All' in the main server.

Dynamic reloading

When a request is being processed, tomcat connectors check the file modification time of the uriworkermap file. To keep the performance penalty low, this happens only, if the last check happened at least n seconds ago.

For Apache you can configure the interval "n" using the directive JkMountFileReload, for IIS you would use the attribute worker_mount_reload. The default value is 60 seconds. A value of "0" turns off the reloading.

If the file changed, it gets reloaded completely. If there exist rules coming from other sources than the uriworkermap file (e.g. the workers.properties mount attribute or JkMount with Apache httpd), the new uriworkermap file gets dynamically merged with these ones exactly like when you do a web server restart.

Until version 1.2.19 reloading behaved slightly differently: it continuously added the full contents of the uriworkermap file to the rule mapping. The merging rules were, that duplicated got eliminated and old rules could be disabled, by defining the rule as disabled in the new file. Rules never got deleted.

Status worker integration

The configuration view of the status worker also shows the various mapping rules. After each worker's configuration, the rules are listed, that forward to this worker. The list contains four columns:

  • the name of the virtual server
  • the URI pattern, prefixed with '-' for a disabled pattern and '!' for an exclusion pattern
  • the type of the rule: Exact or Wildchar
  • and the source of the rule definition: 'worker definition' for the workers.properties file (mount attribute), 'JkMount' for Apache httpd JkMount and it's relatives and finally 'uriworkermap' for the uriworkermap file.

Note: The following restriction has been removed starting with version 1.2.26.
For Apache httpd, there is an important subtlety: the request going to the status worker gets executed in the context of some server (main or virtual). The status worker will only show the mapping rules, that are defined for this server (main or virtual).
Until version 1.2.25 the list contained three columns:

  • the type of the rule: Exact or Wildchar, eventually prefixed with Disabled or Unmount (for exclusion rules)
  • the URI pattern
  • and the source of the rule definition: 'worker definition' for the workers.properties file (mount attribute), 'JkMount' for Apache httpd JkMount and it's relatives and finally 'uriworkermap' for the uriworkermap file.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/reference/printer/iis.html0000644000000000000020000004476112555256555022371 0ustar rootbinThe Apache Tomcat Connectors - Reference Guide - Configuring IIS
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Reference Guide

Configuring IIS

Requirements

The Tomcat redirector requires three entities:

  • isapi_redirect.dll - The IIS server plugin, either obtain a pre-built DLL or build it yourself (see the build section).
  • workers.properties - A file that describes the host(s) and port(s) used by the workers (Tomcat processes). A sample workers.properties can be found under the conf directory.
  • uriworkermap.properties - A file that maps URL-Path patterns to workers. A sample uriworkermap.properties can be found under the conf directory as well.

The installation includes the following parts:

  • Configuring the ISAPI redirector with a default /examples context and checking that you can serve servlets with IIS.
  • Adding more contexts to the configuration.

Note that in a 64 Bit environment - at least for IIS 7 - the used IIS Application Pool should have "Enable 32-bit Applications" set to "False". Otherwise the redirector will not be called and returns an http code 404. If you think, the 32bit version of isapi_redirect.dll would do the job instead, you will get an http code 500, because the library is not loadable into a 64 Bit IIS.

Registry settings

ISAPI redirector reads configuration from the registry, create a new registry key named :

"HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0"

Attributes described below as a "string value representing a boolean" can be set either using the numbers 0 (false) and 1 (true) as values, or off (false) and on (true) or any other string starting with the letters f (false), n (false), t (true) or y (true). The values are taken case insensitive. In this documentation we will stick to false and true.

Key NameDescription
extension_uri

A string value pointing to the ISAPI extension /jakarta/isapi_redirect.dll

log_file

A value pointing to location where log file will be created. (for example c:\tomcat\logs\isapi.log)
If one of the log rotation settings (log_rotationtime or log_filesize) are specified then the actual log file name is based on this setting. If the log file name includes any '%' characters, then it is treated as a format string for strftime(3), e.g. c:\tomcat\logs\isapi-%Y-%m-%d-%H_%M_%S.log. Otherwise, the suffix .nnnnnnnnnn is automatically added and is the time in seconds. A full list of format string substitutions can be found in the Apache rotatelogs documentation

log_level

A string value for log level (can be debug, info, warn, error or trace).

This directive was added in version 1.2.31

log_rotationtime

The time between log file rotations in seconds. Setting this to 0 (the default) disables log rotation based on time.

This directive was added in version 1.2.31

log_filesize

The maximum log file size in megabytes, after which the log file will be rotated. Setting this to 0 (the default) disables log rotation based on file size.
The value can have an optional M suffix, i.e. both 5 and 5M will rotate the log file when it grows to 5MB.
If log_rotationtime is specified, then this setting is ignored.

worker_file

A string value which is the full path to workers.properties file (for example c:\tomcat\conf\workers.properties)

worker_mount_file

A string value which is the full path to uriworkermap.properties file (for example c:\tomcat\conf\uriworkermap.properties)

rewrite_rule_file

A string value which is the full path to rewrite.properties file (for example c:\tomcat\conf\rewrite.properties)

shm_size

A DWORD value size of the shared memory. Set this value to be the number of all defined workers * 400. (Set this value only if you have more then 64 workers)

This directive has been added in version 1.2.20

Starting with version 1.2.27 the size of the shared memory is determined automatically, even for large numbers of workers. This attribute is not needed any longer.

worker_mount_reload

A DWORD value specifying the time in seconds upon which the worker_mount_file will be reloaded.

This directive has been added in version 1.2.20

strip_session

A string value representing a boolean. If it is set to true, URL session suffixes of the form ";jsessionid=..." get stripped of URLs, if the are served locally by the web server.

The default value is false.

This directive has been added in version 1.2.21

auth_complete

A DWORD value representing "0" or "1". This is needed because of minor incompatibilities with IIS 5.1.

By default its value is 1, which means we use the SF_NOTIFY_AUTH_COMPLETE event. If you set this to 0, then we use SF_NOTIFY_PREPROC_HEADERS. This might be needed for IIS 5.1 when handling requests using the PUT HTTP method.

This directive has been added in version 1.2.21

uri_select

A string value which influences, how URIs are decoded and re-encoded between IIS and Tomcat. You should leave this at it's default value, unless you have a very good reason to change it.

If the value is "parsed", the forwarded URI will be decoded and explicit path components like ".." will already be resolved. This is less spec compliant and is not safe if you are using prefix forwarding rules.

If the value is "unparsed", the forwarded URI will be the original request URI. It's spec compliant and also the safest option. Rewriting the URI and then forwarding the rewritten URI will not work.

If the value is "escaped", the forwarded URI will be the re-encoded form of the URI used by "parsed". Explicit path components like ".." will already be resolved. This will not work in combination with URL encoded session IDs.

If the value is "proxy", the forwarded URI will be a partially re-encoded form of the URI used by "parsed". Explicit path components like ".." will already be resolved. and problematic are re-encoded.

The default value since version 1.2.24 is "proxy". Before it was "parsed".

reject_unsafe

A string value representing a boolean. If it is set to true, URLs still containing percent signs '%' or backslashes '\' after decoding will be rejected.

Most web apps do not use such URLs. By enabling reject_unsafe you can block several well known URL encoding attacks.

The default value is false.

This directive has been added in version 1.2.24

collapse_slashes

One of the string values "all", "none" or "unmount". It controls whether multiple adjacent slashes in request URLs are collapsed before looking for a mount or unmount match.

Value "all" will result in collapsing before mount and unmount checks, value "none" will result in never collapsing, value "unmount" will check mount rules without collapsing but unmount with collapsing.

Before version 1.2.41 collapsing was never done. Starting with version 1.2.41 collapsing before looking for unmount matches is the default to prevent easy bypassing of unmount rules.

This directive has been added in version 1.2.41

watchdog_interval

A DWORD value representing the watchdog thread interval in seconds. The workers are maintained periodically by a background thread running periodically every watchdog_interval seconds. Worker maintenance checks for idle connections, corrects load status and is able to detect backend health status.

The maintenance only happens, if since the last maintenance at least worker.maintain seconds have passed. So setting the watchdog_interval much smaller than worker.maintain is not useful.

The default value is 0 seconds, meaning the watchdog thread will not be created, and the maintenance is done in combination with normal requests instead.

This directive has been added in version 1.2.27

error_page

A string value representing the error page url redirection when backend returns non-200 response. This directive can be used to customise the error messages returned from backend server.

The url must point to a valid server url and can contain format string number (%d) that can be used to separate the pages by error number. The redirect url in that case is formatted by replacing %d from error_page to returned error number.

This directive has been added in version 1.2.27

enable_chunked_encoding

A string value representing a boolean. If it is set to true, chunked encoding is supported by the server.

The default value is false.

This directive has been added in version 1.2.27. Until version 1.2.30 it was considered experimental and only available when a special build containing chunking support was used. Starting with 1.2.30 it is no longer considered experimental.

Using a properties file for configuration

The ISAPI redirector can read it's configuration from a properties file instead of the registry. This has the advantage that you can use multiple ISAPI redirectors with independent configurations on the same server. The redirector will check for the properties file during initialisation, and use it in preference to the registry if present.

Create a properties file in the same directory as the ISAPI redirector called isapi_redirect.properties i.e. with the same name as the ISAPI redirector DLL but with a .properties extension. A sample isapi_redirect.properties can be found under the conf directory.

The property names and values in the properties file are the same as for the registry settings described above. For example:

# Configuration file for the Tomcat ISAPI Redirector

# The path to the ISAPI Redirector Extension, relative to the website
# This must be in a virtual directory with execute privileges
extension_uri=/jakarta/isapi_redirect.dll

# Full path to the log file for the ISAPI Redirector
log_file=c:\tomcat\logs\isapi_redirect.log

# Log level (debug, info, warn, error or trace)
log_level=info

# Full path to the workers.properties file
worker_file=c:\tomcat\conf\workers.properties

# Full path to the uriworkermap.properties file
worker_mount_file=c:\tomcat\conf\uriworkermap.properties

Notes:

  • Back-slashes - '\' - are not escape characters.
  • Comment lines begin with '#'.

Starting with version 1.2.27 two environment variables are automatically added to the environment that can be used inside .properties files.

  • JKISAPI_PATH - Full path to the ISAPI Redirector.
  • JKISAPI_NAME - Name of the ISAPI Redirector dll without extension

# Use the logs in the installation path of ISAPI Redirector
log_file=$(JKISAPI_PATH)\$(JKISAPI_NAME).log

Log file rotation

The ISAPI redirector with version 1.2.31 can perform log rotation, with configuration and behaviour similar to the rotatelogs program provided with Apache HTTP Server.

To configure log rotation, configure a log_file, and one of the log_rotationtime or log_filesize options. If both are specified, the log_rotationtime will take precedence, and log_filesize will be ignored.
For example, to configure daily rotation of the log file:

# Configuration file for the Tomcat ISAPI Redirector
...

# Full path to the log file for the ISAPI Redirector
log_file=c:\tomcat\logs\isapi_redirect.%Y-%m-%d.log

# Log level (debug, info, warn, error or trace)
log_level=info

# Rotate the log file every day
log_rotationtime=86400

...

Or to configure rotation of the log file when it reaches 5MB in size:

# Configuration file for the Tomcat ISAPI Redirector
...

# Full path to the log file for the ISAPI Redirector
log_file=c:\tomcat\logs\isapi_redirect.%Y-%m-%d-%H.log

# Log level (debug, info, warn, error or trace)
log_level=info

# Rotate the log file at 5 MB
log_filesize=5M

...

The log will be rotated whenever the configured limit is reached, but only if the log file name would change. If you configure a log file name with strftime(3) format codes in it, then ensure it specifies the same granularity as the rotation time configured, e.g. %Y-%m-%d if rotating daily (log_rotationtime=86400).
See the rotatelogs documentation for more examples.

Using a simple rewrite rules

The ISAPI redirector with version 1.2.16 can do a simple URL rewriting. Although not as powerful as Apache Httpd's mod_rewrite, it allows a simple exchange of request URIs

The rule is in the form original-url-prefix=forward-url-prefix. For example:

# Simple rewrite rules, making /jsp-examples
# and /servlets-examples available under shorter URLs
/jsp/=/jsp-examples/
/servlets/=/servlets-examples/

You can also use regular expressions, if you prefix the rule with a tilde ~:

# Complex rewrite rule, adding "-examples"
# to the first path component of all requests
~/([^/]*)=/$1-examples

Note that uriworkermap.properties must use the URLs before rewriting.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/index.html0000644000000000000020000002767712555256556017303 0ustar rootbinThe Apache Tomcat Connectors / mod_jk - ISAPI redirector - NSAPI redirector - Documentation Index
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors / mod_jk - ISAPI redirector - NSAPI redirector

Documentation Index

Printer Friendly Version
print-friendly
version
Introduction

This is the top-level entry point of the documentation bundle for the Apache Tomcat Connectors

Select one of the links from the navigation menu (to the left) to drill down to the more detailed documentation that is available. Each available manual is described in more detail below.

Headlines
  • JK-1.2.41 released

    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.41 Stable. This release contains a security fix and bug fixes for issues found in previous releases.

    Download the JK 1.2.41 release.

  • Download previous releases from the archives.

Reference Guide

  • workers.properties

    A Tomcat worker is a Tomcat instance that is waiting to execute servlets on behalf of some web server. For example, we can have a web server such as Apache forwarding servlet requests to a Tomcat process (the worker) running behind it.

    This page contains detailed description of all workers.properties directives.

  • uriworkermap.properties

    The forwarding of requests from the web server to tomcat gets configured by defining mapping rules. The so-called uriworkermap file is a mechanism of defining those rules.

  • Status Worker

    The status worker is a builtin management worker. It displays state information and can also be used to dynamically reconfigure JK.

  • Apache

    This page contains detailed description of all directives related to Apache web server.

  • IIS

    This page contains detailed description of all IIS directives.

Common HowTo

  • Quick Start

    This page describes the configuration files used by JK on the Web Server side for the 'impatients'.

  • All about workers

    This page contains an overview about the various aspects of defining and using workers.

  • Timeouts

    This page describes the possible timeout settings you can use.

  • Load Balancing

    This page contains an introduction on load balancing with JK.

  • Reverse Proxy

    This page contains an introduction to reverse proxies, how JK handles this situation and how you can influence the JK proxying behaviour.

Webserver HowTo

These pages contain detailed descriptions of how to build and install JK for the various web servers.

AJP Protocol Reference

  • AJPv13

    This page describes the Apache JServ Protocol version 1.3 (hereafter ajp13).

  • AJPv13 Extension Proposal

    This page describes an extension proposal for ajp13.

Miscellaneous documentation


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/common_howto/0000755000000000000020000000000012555256555017772 5ustar rootbintomcat-connectors-1.2.41-src/docs/common_howto/workers.html0000644000000000000020000005072312555256555022363 0ustar rootbinThe Apache Tomcat Connectors - Common HowTo - Workers HowTo
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Common HowTo

Workers HowTo

Printer Friendly Version
print-friendly
version
Introduction

A Tomcat worker is a Tomcat instance that is waiting to execute servlets on behalf of some web server. For example, we can have a web server such as Apache forwarding servlet requests to a Tomcat process (the worker) running behind it.

The scenario described above is a very simple one; in fact one can configure multiple Tomcat workers to serve servlets on behalf of a certain web server. The reasons for such configuration can be:

  • We want different contexts to be served by different Tomcat workers to provide a development environment where all the developers share the same web server but own a Tomcat worker of their own.
  • We want different virtual hosts served by different Tomcat processes to provide a clear separation between sites belonging to different companies.
  • We want to provide load balancing, meaning run multiple Tomcat workers each on a machine of its own and distribute the requests between them.

There are probably more reasons for having multiple workers but I guess that this list is enough... Tomcat workers are defined in a properties file dubbed workers.properties and this tutorial explains how to work with it.

This document was originally part of Tomcat: A Minimalistic User's Guide written by Gal Shachor, but has been split off for organisational reasons.

Defining Workers

Defining workers to the Tomcat web server plugin can be done using a properties file (a sample file named workers.properties is available in the conf/ directory).

the file contains entries of the following form:

worker.list=<a comma separated list of worker names>

  # the list of workers
  worker.list= worker1, worker2

When starting up, the web server plugin will instantiate the workers whose name appears in the worker.list property, these are also the workers to whom you can map requests. The directive can be used multiple times.

Workers Type

Each named worker should also have a few entries to provide additional information on his behalf. This information includes the worker's type and other related worker information. Currently the following worker types that exists are (JK 1.2.5):

TypeDescription
ajp12This worker knows how to forward requests to out-of-process Tomcat workers using the ajpv12 protocol.
ajp13This worker knows how to forward requests to out-of-process Tomcat workers using the ajpv13 protocol.
lbThis is a load-balancing worker; it knows how to provide round-robin based sticky load balancing with a certain level of fault-tolerance.
statusThis is a status worker for managing load balancers.

Defining workers of a certain type should be done with the following property format:

worker.worker name.type=<worker type> Where worker name is the name assigned to the worker and the worker type is one of the four types defined in the table (a worker name may only contain any space the characters [a-zA-Z0-9\-_]).

  # Defines a worker named "local" that uses the ajpv12 protocol to forward requests to a Tomcat process.
  worker.local.type=ajp12
  # Defines a worker named "remote" that uses the ajpv13 protocol to forward requests to a Tomcat process.
  worker.remote.type=ajp13
  # Defines a worker named "loadbalancer" that loadbalances several Tomcat processes transparently.
  worker.loadbalancer.type=lb
Setting Worker Properties

After defining the workers you can also specify properties for them. Properties can be specified in the following manner:

worker.<worker name>.<property>=<property value>

Each worker has a set of properties that you can set as specified in the following subsections:
ajp12 Worker properties

The ajp12 has been deprecated with Tomcat 3.3.x and you should use instead ajp13 which is the only ajp protocol known by all Tomcat 4 and above.

The ajp12 typed workers forward requests to out-of-process Tomcat workers using the ajpv12 protocol over TCP/IP sockets.

the ajp12 worker properties are :

host property sets the host where the Tomcat worker is listening for ajp12 requests.

port property sets the port where the Tomcat worker is listening for ajp12 requests

lbfactor property is used when working with a load balancer worker, this is the load-balancing factor for the worker. We'll see more on this in the lb worker section.

  # worker "worker1" will talk to Tomcat listening on machine www.x.com at port 8007 using 2 lb factor
  worker.worker1.host=www.x.com
  worker.worker1.port=8007
  worker.worker1.lbfactor=2

Notes: In the ajpv12 protocol, connections are created, used and then closed at each request. The default port for ajp12 is 8007

ajp13 Worker properties

The ajp13 typed workers forward requests to out-of-process Tomcat workers using the ajpv13 protocol over TCP/IP sockets. The main difference between ajpv12 and ajpv13 are that:

  • ajpv13 is a more binary protocol and it tries to compress some of the request data by coding frequently used strings as small integers.
  • ajpv13 reuses open sockets and leaves them open for future requests (remember when you've got a Firewall between your web server and Tomcat).
  • ajpv13 has special treatment for SSL information so that the container can implement SSL related methods such as isSecure().

You should note that Ajp13 is now the only out-process protocol supported by Tomcat 4 and above.

  # worker "worker2" will talk to Tomcat listening on machine www2.x.com at port 8009 using 3 lb factor
  worker.worker2.host=www2.x.com
  worker.worker2.port=8009
  worker.worker2.lbfactor=3
  # worker "worker2" uses connections, which will stay no more than 10mn in the connection pool
  worker.worker2.connection_pool_timeout=600
  # worker "worker2" ask operating system to send KEEP-ALIVE signal on the connection
  worker.worker2.socket_keepalive=1
  # mount can be used as an alternative to the JkMount directive
  worker.worker2.mount=/contexta /contexta/* /contextb /contextb/*

Notes: In the ajpv13 protocol, the default port is 8009

lb Worker properties

The load-balancing worker does not really communicate with Tomcat workers. Instead it is responsible for the management of several "real" workers. This management includes:

  • Instantiating the workers in the web server.
  • Using the worker's load-balancing factor, perform weighed-round-robin load balancing where high lbfactor means stronger machine (that is going to handle more requests)
  • Keeping requests belonging to the same session executing on the same Tomcat worker.
  • Identifying failed Tomcat workers, suspending requests to them and instead falling-back on other workers managed by the lb worker.

The overall result is that workers managed by the same lb worker are load-balanced (based on their lbfactor and current user session) and also fall-backed so a single Tomcat process death will not "kill" the entire site. The following table specifies some properties that the lb worker can accept:

  • balance_workers is a comma separated list of workers that the load balancer need to manage. As long as these workers should only be used via the load balancer worker, there is no need to also put them into the worker.list property. This directive can be used multiple times for the same load balancer.
  • sticky_session specifies whether requests with SESSION ID's should be routed back to the same Tomcat worker. Set sticky_session to false when Tomcat is using a Session Manager which can persist session data across multiple instances of Tomcat. By default sticky_session is set to true.

  # The worker balance1 while use "real" workers worker1 and worker2
  worker.balance1.balance_workers=worker1, worker2
Status Worker properties

The status worker does not communicate with Tomcat. Instead it is responsible for the load balancer management.

  # Add the status worker to the worker list
  worker.list=jkstatus
  # Define a 'jkstatus' worker using status
  worker.jkstatus.type=status

Next thing is to mount the requests to the jkstatus worker. For Apache web servers use the:

  # Add the jkstatus mount point
  JkMount /jkmanager/* jkstatus 

To obtain a higher level of security use the:

  # Enable the JK manager access from localhost only
 <Location /jkmanager/>
    JkMount jkstatus
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
 </Location>
Property file macros

You can define "macros" in the property files. These macros let you define properties and later on use them while constructing other properties.

  # property example, like a network base address
  mynet=194.226.31
  # Using the above macro to simplify the address definitions
  # for a farm of workers.
  worker.node1.host=$(mynet).11
  worker.node2.host=$(mynet).12
  worker.node3.host=$(mynet).13
Hierarchical property configuration

Workers can reference configurations of other workers. If worker "x" references worker "y", then it inherits all configuration parameters from "y", except for the ones that have explicitly been set for "x".

  # worker toe defines some default settings
  worker.toe.type=ajp13
  worker.toe.socket_keepalive=true
  worker.toe.connect_timeout=10000
  worker.toe.recovery_options=7
  # workers tic and tac inherit those values
  worker.tic.reference=worker.toe
  worker.tac.reference=worker.toe

Please note, that the reference contains the full prefix to the referenced configuration attributes, not only the name of the referenced worker.

References can be nested with a maximum depth of 20. Be careful to avoid loops!

Attributes which are allowed multiple times for a single worker can not be merged from a worker and a reference. An attribute is only inherited from a reference, if it is not already set for the referring worker.

References are especially useful, when configuring load balancers. Try to understand the following two stage references:

  # We only use one load balancer
  worker.list=lb
  # Let's define some defaults
  worker.basic.port=8009
  worker.basic.type=ajp13
  worker.basic.socket_keepalive=true
  worker.basic.connect_timeout=10000
  worker.basic.recovery_options=7
  # And we use them in two groups
  worker.lb1.domain=dom1
  worker.lb1.distance=0
  worker.lb1.reference=worker.basic
  worker.lb2.domain=dom2
  worker.lb2.distance=1
  worker.lb2.reference=worker.basic
  # Now we configure the load balancer
  worker.lb.type=lb
  worker.lb.method=B
  worker.lb.balanced_workers=w11,w12,w21,w22
  worker.w11.host=myhost11
  worker.w11.reference=worker.lb1
  worker.w12.host=myhost12
  worker.w12.reference=worker.lb1
  worker.w21.host=myhost21
  worker.w21.reference=worker.lb2
  worker.w22.host=myhost22
  worker.w22.reference=worker.lb2
A sample worker.properties

Since coping with worker.properties on your own is not an easy thing to do, a sample worker.properties file is bundled along JK.

You could also find here a sample workers.properties defining :

  • An ajp12 worker that used the host localhost and the port 8007
  • An ajp13 worker that used the host localhost and the port 8008
  • An lb worker that load balance the ajp12 and ajp13 workers
  # Define 3 workers, 2 real workers using ajp12, ajp13, the last one being a loadbalancing worker 
  worker.list=worker1, worker2, worker3
  # Set properties for worker1 (ajp12)
  worker.worker1.type=ajp12
  worker.worker1.host=localhost
  worker.worker1.port=8007
  worker.worker1.lbfactor=1
  # Set properties for worker2 (ajp13)
  worker.worker2.type=ajp13
  worker.worker2.host=localhost
  worker.worker2.port=8009
  worker.worker2.lbfactor=1
  worker.worker2.connection_pool_timeout=600
  worker.worker2.socket_keepalive=1
  worker.worker2.socket_timeout=60
  # Set properties for worker3 (lb) which use worker1 and worker2
  worker.worker3.balance_workers=worker1,worker2

Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/common_howto/loadbalancers.html0000644000000000000020000003454212555256555023462 0ustar rootbinThe Apache Tomcat Connectors - Common HowTo - LoadBalancer HowTo
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Common HowTo

LoadBalancer HowTo

Printer Friendly Version
print-friendly
version
Introduction

A load balancer is a worker that does not directly communicate with Tomcat. Instead it is responsible for the management of several "real" workers, called members or sub workers of the load balancer.

This management includes:

  • Instantiating the workers in the web server.
  • Using the worker's load-balancing factor, perform weighted load balancing (distributing load according to defined strengths of the targets).
  • Keeping requests belonging to the same session executing on the same Tomcat (session stickyness).
  • Identifying failed Tomcat workers, suspending requests to them and instead falling-back on other workers managed by the load balancer.
  • Providing status and load metrics for the load balancer itself and all members via the status worker interface.
  • Allowing to dynamically reconfigure load-balancing via the status worker interface.

Workers managed by the same load balancer worker are load-balanced (based on their configured balancing factors and current request or session load) and also secured against failure by providing failover to other members of the same load balancer. So a single Tomcat process death will not "kill" the entire site.

Some of the features provided by a load balancer are even interesting, when only working with a single member worker (where load balancing is not possible).

Basic Load Balancer Properties

A worker is configured as a load balancer by setting its worker type to lb.

The following table specifies some properties used to configure a load balancer worker:

  • balance_workers is a comma separated list of names of the member workers of the load balancer. These workers are typically of type ajp13. The member workers do not need to appear in the worker.list property themselves, adding the load balancer to it suffices.
  • sticky_session specifies whether requests with SESSION ID's should be routed back to the same Tomcat instance that created the session. You can set sticky_session to false when Tomcat is using a session manager which can share session data across multiple instances of Tomcat - or if your application is stateless. By default sticky_session is set to true.
  • lbfactor can be added to each member worker to configure individual strengths for the members. A higher lbfactor will lead to more requests being balanced to that worker. The factors must be given by integers and the load will be distributed proportional to the factors given. Higher factors lead to more requests.
  # The load balancer worker balance1 will distribute
  # load to the members worker1 and worker2
  worker.balance1.type=lb
  worker.balance1.balance_workers=worker1, worker2
  worker.worker1.type=ajp13
  worker.worker1.host=myhost1
  worker.worker1.port=8009
  worker.worker2.type=ajp13
  worker.worker1.host=myhost2
  worker.worker1.port=8009

Session stickyness is not implemented using a tracking table for sessions. Instead each Tomcat instance gets an individual name and adds its name at the end of the session id. When the load balancer sees a session id, it finds the name of the Tomcat instance and sends the request via the correct member worker. For this to work you must set the name of the Tomcat instances as the value of the jvmRoute attribute in the Engine element of each Tomcat's server.xml. The name of the Tomcat needs to be equal to the name of the corresponding load balancer member. In the above example, Tomcat on host "myhost1" needs jvmRoute="worker1", Tomcat on host "myhost2" needs jvmRoute="worker2".

For a complete reference of all load balancer configuration attributes, please consult the worker reference.

Advanced Load Balancer Worker Properties

The load balancer supports complex topologies and failover configurations. Using the member attribute distance you can group members. The load balancer will always send a request to a member of lowest distance. Only when all of those are broken, it will balance to the members of the next higher configured distance. This allows to define priorities between Tomcat instances in different data center locations.

When working with shared sessions, either by using session replication or a persisting session manager (e.g. via a database), one often splits up the Tomcat farm into replication groups. In case of failure of a member, the load balancer needs to know, which other members share the session. This is configured using the domain attribute. All workers with the same domain are assumed to share the sessions.

For maintenance purposes you can tell the load balancer to not allow any new sessions on some members, or even not use them at all. This is controlled by the member attribute activation. The value Active allows normal use of a member, disabled will not create new sessions on it, but still allow sticky requests, and stopped will no longer send any requests to the member. Switching the activation from "active" to "disabled" some time before maintenance will drain the sessions on the worker and minimize disruption. Depending on the usage pattern of the application, draining will take from minutes to hours. Switching the worker to stopped immediately before maintenance will reduce logging of false errors by mod_jk.

Finally you can also configure hot spare workers by using activation set to disabled in combination with the attribute redirect added to the other workers:

  # The advanced router LB worker
  worker.list=router
  worker.router.type=lb
  worker.router.balance_workers=worker1,worker2

  # Define the first member worker
  worker.worker1.type=ajp13
  worker.worker1.host=myhost1
  worker.worker1.port=8009
  # Define preferred failover node for worker1
  worker.worker1.redirect=worker2

  # Define the second member worker
  worker.worker2.type=ajp13
  worker.worker2.host=myhost2
  worker.worker2.port=8009
  # Disable worker2 for all requests except failover
  worker.worker2.activation=disabled

The redirect flag on worker1 tells the load balancer to redirect the requests to worker2 in case that worker1 has a problem. In all other cases worker2 will not receive any requests, thus acting like a hot standby.

A final note about setting activation to disabled: The session id coming with a request is send either as part of the request URL (;jsessionid=...) or via a cookie. When using bookmarks or browsers that are running since a long time, it is possible to send a request carrying an old and invalid session id pointing at a disabled member. Since the load balancer does not have a list of valid sessions, it will forward the request to the disabled member. Thus draining takes longer than expected. To handle such cases, you can add a Servlet filter to your web application, which checks the request attribute JK_LB_ACTIVATION. This attribute contains one of the strings "ACT", "DIS" or "STP". If you detect "DIS" and the session for the request is no longer active, delete the session cookie and redirect using a self-referential URL. The redirected request will then no longer carry session information and thus the load balancer will not send it to the disabled worker. The request attribute JK_LB_ACTIVATION has been added in version 1.2.32.

Status Worker properties

The status worker does not communicate with Tomcat. Instead it is responsible for the worker management. It is especially useful when combined with load balancer workers.

  # Add the status worker to the worker list
  worker.list=jkstatus
  # Define a 'jkstatus' worker using status
  worker.jkstatus.type=status

Next thing is to mount the requests to the jkstatus worker. For Apache web servers use the:

  # Add the jkstatus mount point
  JkMount /jkmanager/* jkstatus 

To obtain a higher level of security use the:

  # Enable the JK manager access from localhost only
 <Location /jkmanager/>
    JkMount jkstatus
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
 </Location>

Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/common_howto/proxy.html0000644000000000000020000005716612555256555022060 0ustar rootbinThe Apache Tomcat Connectors - Common HowTo - Reverse Proxy HowTo
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Common HowTo

Reverse Proxy HowTo

Printer Friendly Version
print-friendly
version
Introduction

The Apache module mod_jk and its ISAPI and NSAPI variants connect a web server to a backend (typically Tomcat) using the AJP protocol. The web server receives an HTTP(S) request and the module forwards the request to the backend. This function is usually called a gateway or a proxy, in the context of HTTP it is called a reverse proxy.

Typical Problems

A reverse proxy is not totally transparent to the application on the backend. For instance the host name and port the original client (e.g. browser) needs to talk to belong to the web server and not to the backend, so the reverse proxy talks to a different host name and port. When the application on the backend returns content including self-referential URLs using its own backend address and port, the client will usually not be able to use these URLs.

Another example is the client IP address, which for the web server is the source IP of the incoming connection, whereas for the backend the connection always comes from the web server. This can be a problem, when the client IP is used by the backend application e.g. for security reasons.

AJP as a Solution

Most of these problems are automatically handled by the AJP protocol and the AJP connectors of the backend. The AJP protocol transports this communication metadata and the backend connector presents this metadata whenever the application asks for it using Servlet API methods.

The following list contains the communication metadata handled by AJP and the ServletRequest/HttpServletRequest API calls which can be used to retrieve them:

  • local name: getLocalName(). This is also equal to getServerName(), unless a Host header is contained in the request. In this case the server name is taken from that header.
  • local IP address: getLocalAddr(). The local IP address was initially not supported. It is available when using mod_jk 1.2.41 with Apache or IIS (not for the NSAPI plugin) together with Tomcat version at least 6.0.42, 7.0.55 or 8.0.11. For older versions, getLocalAddr() will incorrectly return the same result as getLocalName(). As a workaround you can forward the local IP address by setting JkEnvVar SERVER_ADDR and then either using request.getAttribute("SERVER_ADDR") instead of getLocalAddr() or wrapping the request using a filter and overriding getLocalAddr() with request.getAttribute("SERVER_ADDR").
  • local port: getLocalPort(). This is also equal to getServerPort(), unless a Host header is contained in the request. In this case the server port is taken from that header if it contains an explicit port, or is equal to the default port of the scheme used.
  • client address: getRemoteAddr()
  • client port: getRemotePort(). The remote port was initially not supported. It is available when using mod_jk 1.2.32 with Apache or IIS (not for the NSAPI plugin) together with Tomcat version at least 5.5.28, 6.0.20 or 7.0.0. For older versions, getRemotePort() will incorrectly return 0 or -1. As a workaround you can forward the remote port by setting JkEnvVar REMOTE_PORT and then either using request.getAttribute("REMOTE_PORT") instead of getRemotePort() or wrapping the request using a filter and overriding getRemotePort() with request.getAttribute("REMOTE_PORT").
  • client host: getRemoteHost()
  • authentication type: getAuthType()
  • remote user: getRemoteUser(), if tomcatAuthentication="false"
  • protocol: getProtocol()
  • HTTP method: getMethod()
  • URI: getRequestURI()
  • HTTPS used: isSecure(), getScheme()
  • query string: getQueryString()
The following additional SSL-related data will be made available by Apache and forwarded by mod_jk only if you set SSLOptions +StdEnvVars. For the certificate information you also need to set SSLOptions +ExportCertData.
  • SSL cipher: getAttribute(javax.servlet.request.cipher_suite)
  • SSL key size: getAttribute(javax.servlet.request.key_size). Can be disabled using JkOptions -ForwardKeySize.
  • SSL client certificate: getAttribute(javax.servlet.request.X509Certificate). If you want the whole certificate chain, then you need to also set JkOptions ForwardSSLCertChain. It is likely, that in this case you also need to adjust the maximal AJP packet size using the worker attribute max_packet_size.
  • SSL session ID: getAttribute(javax.servlet.request.ssl_session). This is for Tomcat, it has not yet been standardized.

Fine Tuning

In some situations this is not enough though. Assume there is another less clever reverse proxy in front of your web server, for instance an HTTP load balancer or similar device which also serves as an SSL accelerator.

Then you are sure that all your clients use HTTPS, but your web server doesn't know about that. All it can see is requests coming from the accelerator using plain HTTP.

Another example would be a simple reverse proxy in front of your web server, so that the client IP address that your web server sees is always the IP address of this reverse proxy, and not of the original client. Often such reverse proxies generate an additional HTTP header, like X-Forwareded-for which contains the original client IP address (or a list of IP addresses, if there are more cascading reverse proxies in front). It would be nice, if we could use the content of such a header as the client IP address to pass to the backend.

So we might need to manipulate some of the data that AJP sends to the backend. When using mod_jk inside Apache httpd you can use several httpd environment variables to let mod_jk know, which data it should forward. These environment variables can be set by the httpd directives SetEnv or SetEnvIf, but also in a very flexible way using mod_rewrite (since httpd 2.x it can not only test against environment variables, but also set them).

The following list contains all environment variables mod_jk checks, before sending data to the backend:

  • JK_LOCAL_NAME: the local name
  • JK_LOCAL_PORT: the local port
  • JK_REMOTE_HOST: the client host
  • JK_REMOTE_ADDR: the client address
  • JK_AUTH_TYPE: the authentication type
  • JK_REMOTE_USER: the remote user
  • HTTPS: On (case-insensitive) to indicate, that HTTPS is used
  • SSL_CIPHER: the SSL cipher
  • SSL_CIPHER_USEKEYSIZE: the SSL key size
  • SSL_CLIENT_CERT: the SSL client certificate
  • SSL_CLIENT_CERT_CHAIN_: prefix of variable names, containing the client cerificate chain
  • SSL_SESSION_ID: the SSL session ID

Remember: in general you don't need to set them. The module retrieves the data automatically from the web server. Only in case you want to change this data, you can overwrite it by using these variables.

Some of these variables might also be used by other web server modules. All variables whose name does not begin with "JK" are set directly by Apache httpd. If you want to change the data, but do not want to negatively influence the behaviour of other modules, you can change the names of all variables mod_jk uses to private ones. For the details see the Apache reference page.

All variables, that are not SSL-related have only been introduced in version 1.2.27.

In addition there are two special shortcuts to influence the client IP address that is forwarded. Using JkOptions ForwardLocalAddress you can forward the local IP address of the web server as the client IP address. This can be useful, e.g. when using the Tomcat remote address valve for allowing connections only from registered Apache web servers. Using JkOptions ForwardPhysicalAddress you always forward the physical peer IP address as the client address. By default mod_jk uses the logical address as provided by the web server. For example the module mod_remoteip sets the logical IP address to the client IP forwarded by proxies in the X-Forwarded-For header.

Tomcat AJP Connector Settings

As an alternative to using the environment variables described in the previous section (which do only exist when using Apache httpd), you can also configure Tomcat to overwrite some of the communications data forwarded by mod_jk. The AJP connector in Tomcat's server.xml allows to set the following properties:

  • proxyName: server name as returned by getServerName()
  • proxyPort: server port as returned by getServerPort()
  • scheme: protocol scheme as returned by getScheme()
  • secure: set to "true", if you wish isSecure() to return "true".
Remember: in general you don't need to set those. AJP automatically handles all cases where the web server running mod_jk knows the right data.

URL Handling

URL Rewriting

Sometimes one want to change path components of the URLs under which an application is available. Especially if a web application is deployed as some context, say /myapp, marketing prefers short URLs, so want the application to be directly available under http://www.mycompany.com/. Although you can deploy the application as the so-called ROOT context, which will be directly available at "/", admins often prefer not to use the ROOT context, e.g. because only one application can be the root context (per host).

The procedure to change the URLs in the reverse proxy is tedious, because often an application produces self-referential URLs, which then include the path components which you tried to hide to the outside world. Nevertheless, if you absolutely need to do it, here are the steps.

Case A: You need to make the application available at a simple URL, but it is OK, if users proceed using the more complex URLs, as long as they don't have to type them in. That's the easy case, and if this suffices to you, you're lucky. Use a simply RedirectMatch for Apache httpd:

RedirectMatch ^/$ http://www.mycompany.com/myapp/

Your application will then be available under http://www.mycompany.com/, and each visitor will be immediately redirected to the real URL http://www.mycompany.com/myapp/

Case B: You need to hide path components for all requests going to the application. Here's the recipe for the case, where you want to hide the first path component /myapp. More complex manipulations are left as an exercise to the reader. First the solution for the case of Apache httpd:

1. Use mod_rewrite to add /myapp to all requests before forwarding to the backend:

# Don't forget the PT flag! (pass through)
RewriteRule ^/(.*) http://www.mycompany.com/myapp/$1 [PT]

2. Use mod_headers to rewrite any HTTP redirects your application might return. Such redirects typically contain the path components you want to hide, because by the HTTP standard, redirects always need to include the full URL, and your application is not aware of the fact, that your clients talk to it via some shortened URL. An HTTP redirect is done with a special response header named Location. We rewrite the Location headers of our responses:

# Keep protocol, server and port if present,
# but insert our webapp name before the rest of the URL
Header edit Location ^([^/]*//[^/]*)?/(.*)$ $1/myapp/$2 

3. Use mod_headers again, to rewrite the paths contained in any cookies, your application might set. Such cookie paths again might contain the path components you want to hide. A cookie is set with the HTTP response header named Set-Cookie. We rewrite the Set-Cookie headers of our responses:

# Fix the cookie path
Header edit Set-Cookie "^(.*; Path=/)(.*)" $1/myapp/$2 

3. Some applications might contain hard coded absolute links. In this case check, whether you find a configuration item for your web framework to configure the base URL. If not, your only chance is to parse all response content bodies and do search and replace. This is fragile and very resource intensive. If you really need to do this, you can use mod_proxy_html, mod_substitute or mod_sed for this task.

If you are using Microsoft IIS as a web server, the ISAPI plugin provides a way of doing the first step with a builtin feature. You define a mapping file for simple prefix changes like this:

# Add a context prefix to all requests ...
/=/myapp/
# ... or change some prefix ...
/oldapp/=/myapp/

and then put the name of the file in the rewrite_rule_file entry of the registry or your isapi_redirect.properties file. In your uriworkermap.properties file, you still need to map the URLs as they are before rewriting!

More complex rewrites can be done using the same file, but with regular expressions. A leading tilde sign '~', indicates, that you are using a regular expression:

# Use a regular expression rewrite
~/oldapps([0-9]*)/=/newapps$1/

There is no support for Steps 2 (rewriting redirect responses) or 3 (rewriting cookie paths).

URL Encoding

Some types of problems are triggered by the use of encoded URLs (see percent encoding). For the same location there exist a lot of different URLs which are equivalent. The reverse proxy needs to inspect the URL in order to apply its own authentication rules and to decide, to which backend it should send the request (or whether it should handle it itself). Therefore the request URL first is normalized: percent encoded characters are decoded, /./ is replaced by /, /XXX/../ is replaced by / and similar manipulations of the URL are done. After that, the web server might apply rewrite rules to further change the URL in less obvious ways. Finally there is no more way to put the resulting URL in an encoding, which is "similar" to the one which was used for the original URL.

For historical reasons, there have been several alternatives, how mod_jk and the ISAPI plugin encoded the resulting URL before sending it to the backend. They could be chosen via JkOptions (Apache httpd) or uri_select (ISAPI). None of those historical encodings are recommended, because they have either negative functionality implications or pose a security risk. The default encoding since version 1.2.24 is ForwardURIProxy (Apache httpd) or proxy (ISAPI) and it is strongly recommended to keep the default and remove all old explicit settings.

Request Attributes

You can also add more attributes to any request you are forwarding when using Apache httpd. For this use the JkEnvVar directive (for details see the Apache reference page). Such request attributes can be retrieved on the Tomcat side via request.getAttribute(attributeName). Note that their names will not be listed in request.getAttributeNames()!


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/common_howto/printer/0000755000000000000020000000000012555256555021455 5ustar rootbintomcat-connectors-1.2.41-src/docs/common_howto/printer/workers.html0000644000000000000020000004246112555256555024046 0ustar rootbinThe Apache Tomcat Connectors - Common HowTo - Workers HowTo
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Common HowTo

Workers HowTo

Introduction

A Tomcat worker is a Tomcat instance that is waiting to execute servlets on behalf of some web server. For example, we can have a web server such as Apache forwarding servlet requests to a Tomcat process (the worker) running behind it.

The scenario described above is a very simple one; in fact one can configure multiple Tomcat workers to serve servlets on behalf of a certain web server. The reasons for such configuration can be:

  • We want different contexts to be served by different Tomcat workers to provide a development environment where all the developers share the same web server but own a Tomcat worker of their own.
  • We want different virtual hosts served by different Tomcat processes to provide a clear separation between sites belonging to different companies.
  • We want to provide load balancing, meaning run multiple Tomcat workers each on a machine of its own and distribute the requests between them.

There are probably more reasons for having multiple workers but I guess that this list is enough... Tomcat workers are defined in a properties file dubbed workers.properties and this tutorial explains how to work with it.

This document was originally part of Tomcat: A Minimalistic User's Guide written by Gal Shachor, but has been split off for organisational reasons.

Defining Workers

Defining workers to the Tomcat web server plugin can be done using a properties file (a sample file named workers.properties is available in the conf/ directory).

the file contains entries of the following form:

worker.list=<a comma separated list of worker names>

  # the list of workers
  worker.list= worker1, worker2

When starting up, the web server plugin will instantiate the workers whose name appears in the worker.list property, these are also the workers to whom you can map requests. The directive can be used multiple times.

Workers Type

Each named worker should also have a few entries to provide additional information on his behalf. This information includes the worker's type and other related worker information. Currently the following worker types that exists are (JK 1.2.5):

TypeDescription
ajp12This worker knows how to forward requests to out-of-process Tomcat workers using the ajpv12 protocol.
ajp13This worker knows how to forward requests to out-of-process Tomcat workers using the ajpv13 protocol.
lbThis is a load-balancing worker; it knows how to provide round-robin based sticky load balancing with a certain level of fault-tolerance.
statusThis is a status worker for managing load balancers.

Defining workers of a certain type should be done with the following property format:

worker.worker name.type=<worker type> Where worker name is the name assigned to the worker and the worker type is one of the four types defined in the table (a worker name may only contain any space the characters [a-zA-Z0-9\-_]).

  # Defines a worker named "local" that uses the ajpv12 protocol to forward requests to a Tomcat process.
  worker.local.type=ajp12
  # Defines a worker named "remote" that uses the ajpv13 protocol to forward requests to a Tomcat process.
  worker.remote.type=ajp13
  # Defines a worker named "loadbalancer" that loadbalances several Tomcat processes transparently.
  worker.loadbalancer.type=lb
Setting Worker Properties

After defining the workers you can also specify properties for them. Properties can be specified in the following manner:

worker.<worker name>.<property>=<property value>

Each worker has a set of properties that you can set as specified in the following subsections:
ajp12 Worker properties

The ajp12 has been deprecated with Tomcat 3.3.x and you should use instead ajp13 which is the only ajp protocol known by all Tomcat 4 and above.

The ajp12 typed workers forward requests to out-of-process Tomcat workers using the ajpv12 protocol over TCP/IP sockets.

the ajp12 worker properties are :

host property sets the host where the Tomcat worker is listening for ajp12 requests.

port property sets the port where the Tomcat worker is listening for ajp12 requests

lbfactor property is used when working with a load balancer worker, this is the load-balancing factor for the worker. We'll see more on this in the lb worker section.

  # worker "worker1" will talk to Tomcat listening on machine www.x.com at port 8007 using 2 lb factor
  worker.worker1.host=www.x.com
  worker.worker1.port=8007
  worker.worker1.lbfactor=2

Notes: In the ajpv12 protocol, connections are created, used and then closed at each request. The default port for ajp12 is 8007

ajp13 Worker properties

The ajp13 typed workers forward requests to out-of-process Tomcat workers using the ajpv13 protocol over TCP/IP sockets. The main difference between ajpv12 and ajpv13 are that:

  • ajpv13 is a more binary protocol and it tries to compress some of the request data by coding frequently used strings as small integers.
  • ajpv13 reuses open sockets and leaves them open for future requests (remember when you've got a Firewall between your web server and Tomcat).
  • ajpv13 has special treatment for SSL information so that the container can implement SSL related methods such as isSecure().

You should note that Ajp13 is now the only out-process protocol supported by Tomcat 4 and above.

  # worker "worker2" will talk to Tomcat listening on machine www2.x.com at port 8009 using 3 lb factor
  worker.worker2.host=www2.x.com
  worker.worker2.port=8009
  worker.worker2.lbfactor=3
  # worker "worker2" uses connections, which will stay no more than 10mn in the connection pool
  worker.worker2.connection_pool_timeout=600
  # worker "worker2" ask operating system to send KEEP-ALIVE signal on the connection
  worker.worker2.socket_keepalive=1
  # mount can be used as an alternative to the JkMount directive
  worker.worker2.mount=/contexta /contexta/* /contextb /contextb/*

Notes: In the ajpv13 protocol, the default port is 8009

lb Worker properties

The load-balancing worker does not really communicate with Tomcat workers. Instead it is responsible for the management of several "real" workers. This management includes:

  • Instantiating the workers in the web server.
  • Using the worker's load-balancing factor, perform weighed-round-robin load balancing where high lbfactor means stronger machine (that is going to handle more requests)
  • Keeping requests belonging to the same session executing on the same Tomcat worker.
  • Identifying failed Tomcat workers, suspending requests to them and instead falling-back on other workers managed by the lb worker.

The overall result is that workers managed by the same lb worker are load-balanced (based on their lbfactor and current user session) and also fall-backed so a single Tomcat process death will not "kill" the entire site. The following table specifies some properties that the lb worker can accept:

  • balance_workers is a comma separated list of workers that the load balancer need to manage. As long as these workers should only be used via the load balancer worker, there is no need to also put them into the worker.list property. This directive can be used multiple times for the same load balancer.
  • sticky_session specifies whether requests with SESSION ID's should be routed back to the same Tomcat worker. Set sticky_session to false when Tomcat is using a Session Manager which can persist session data across multiple instances of Tomcat. By default sticky_session is set to true.

  # The worker balance1 while use "real" workers worker1 and worker2
  worker.balance1.balance_workers=worker1, worker2
Status Worker properties

The status worker does not communicate with Tomcat. Instead it is responsible for the load balancer management.

  # Add the status worker to the worker list
  worker.list=jkstatus
  # Define a 'jkstatus' worker using status
  worker.jkstatus.type=status

Next thing is to mount the requests to the jkstatus worker. For Apache web servers use the:

  # Add the jkstatus mount point
  JkMount /jkmanager/* jkstatus 

To obtain a higher level of security use the:

  # Enable the JK manager access from localhost only
 <Location /jkmanager/>
    JkMount jkstatus
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
 </Location>
Property file macros

You can define "macros" in the property files. These macros let you define properties and later on use them while constructing other properties.

  # property example, like a network base address
  mynet=194.226.31
  # Using the above macro to simplify the address definitions
  # for a farm of workers.
  worker.node1.host=$(mynet).11
  worker.node2.host=$(mynet).12
  worker.node3.host=$(mynet).13
Hierarchical property configuration

Workers can reference configurations of other workers. If worker "x" references worker "y", then it inherits all configuration parameters from "y", except for the ones that have explicitly been set for "x".

  # worker toe defines some default settings
  worker.toe.type=ajp13
  worker.toe.socket_keepalive=true
  worker.toe.connect_timeout=10000
  worker.toe.recovery_options=7
  # workers tic and tac inherit those values
  worker.tic.reference=worker.toe
  worker.tac.reference=worker.toe

Please note, that the reference contains the full prefix to the referenced configuration attributes, not only the name of the referenced worker.

References can be nested with a maximum depth of 20. Be careful to avoid loops!

Attributes which are allowed multiple times for a single worker can not be merged from a worker and a reference. An attribute is only inherited from a reference, if it is not already set for the referring worker.

References are especially useful, when configuring load balancers. Try to understand the following two stage references:

  # We only use one load balancer
  worker.list=lb
  # Let's define some defaults
  worker.basic.port=8009
  worker.basic.type=ajp13
  worker.basic.socket_keepalive=true
  worker.basic.connect_timeout=10000
  worker.basic.recovery_options=7
  # And we use them in two groups
  worker.lb1.domain=dom1
  worker.lb1.distance=0
  worker.lb1.reference=worker.basic
  worker.lb2.domain=dom2
  worker.lb2.distance=1
  worker.lb2.reference=worker.basic
  # Now we configure the load balancer
  worker.lb.type=lb
  worker.lb.method=B
  worker.lb.balanced_workers=w11,w12,w21,w22
  worker.w11.host=myhost11
  worker.w11.reference=worker.lb1
  worker.w12.host=myhost12
  worker.w12.reference=worker.lb1
  worker.w21.host=myhost21
  worker.w21.reference=worker.lb2
  worker.w22.host=myhost22
  worker.w22.reference=worker.lb2
A sample worker.properties

Since coping with worker.properties on your own is not an easy thing to do, a sample worker.properties file is bundled along JK.

You could also find here a sample workers.properties defining :

  • An ajp12 worker that used the host localhost and the port 8007
  • An ajp13 worker that used the host localhost and the port 8008
  • An lb worker that load balance the ajp12 and ajp13 workers
  # Define 3 workers, 2 real workers using ajp12, ajp13, the last one being a loadbalancing worker 
  worker.list=worker1, worker2, worker3
  # Set properties for worker1 (ajp12)
  worker.worker1.type=ajp12
  worker.worker1.host=localhost
  worker.worker1.port=8007
  worker.worker1.lbfactor=1
  # Set properties for worker2 (ajp13)
  worker.worker2.type=ajp13
  worker.worker2.host=localhost
  worker.worker2.port=8009
  worker.worker2.lbfactor=1
  worker.worker2.connection_pool_timeout=600
  worker.worker2.socket_keepalive=1
  worker.worker2.socket_timeout=60
  # Set properties for worker3 (lb) which use worker1 and worker2
  worker.worker3.balance_workers=worker1,worker2

Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/common_howto/printer/loadbalancers.html0000644000000000000020000002627212555256555025146 0ustar rootbinThe Apache Tomcat Connectors - Common HowTo - LoadBalancer HowTo
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Common HowTo

LoadBalancer HowTo

Introduction

A load balancer is a worker that does not directly communicate with Tomcat. Instead it is responsible for the management of several "real" workers, called members or sub workers of the load balancer.

This management includes:

  • Instantiating the workers in the web server.
  • Using the worker's load-balancing factor, perform weighted load balancing (distributing load according to defined strengths of the targets).
  • Keeping requests belonging to the same session executing on the same Tomcat (session stickyness).
  • Identifying failed Tomcat workers, suspending requests to them and instead falling-back on other workers managed by the load balancer.
  • Providing status and load metrics for the load balancer itself and all members via the status worker interface.
  • Allowing to dynamically reconfigure load-balancing via the status worker interface.

Workers managed by the same load balancer worker are load-balanced (based on their configured balancing factors and current request or session load) and also secured against failure by providing failover to other members of the same load balancer. So a single Tomcat process death will not "kill" the entire site.

Some of the features provided by a load balancer are even interesting, when only working with a single member worker (where load balancing is not possible).

Basic Load Balancer Properties

A worker is configured as a load balancer by setting its worker type to lb.

The following table specifies some properties used to configure a load balancer worker:

  • balance_workers is a comma separated list of names of the member workers of the load balancer. These workers are typically of type ajp13. The member workers do not need to appear in the worker.list property themselves, adding the load balancer to it suffices.
  • sticky_session specifies whether requests with SESSION ID's should be routed back to the same Tomcat instance that created the session. You can set sticky_session to false when Tomcat is using a session manager which can share session data across multiple instances of Tomcat - or if your application is stateless. By default sticky_session is set to true.
  • lbfactor can be added to each member worker to configure individual strengths for the members. A higher lbfactor will lead to more requests being balanced to that worker. The factors must be given by integers and the load will be distributed proportional to the factors given. Higher factors lead to more requests.
  # The load balancer worker balance1 will distribute
  # load to the members worker1 and worker2
  worker.balance1.type=lb
  worker.balance1.balance_workers=worker1, worker2
  worker.worker1.type=ajp13
  worker.worker1.host=myhost1
  worker.worker1.port=8009
  worker.worker2.type=ajp13
  worker.worker1.host=myhost2
  worker.worker1.port=8009

Session stickyness is not implemented using a tracking table for sessions. Instead each Tomcat instance gets an individual name and adds its name at the end of the session id. When the load balancer sees a session id, it finds the name of the Tomcat instance and sends the request via the correct member worker. For this to work you must set the name of the Tomcat instances as the value of the jvmRoute attribute in the Engine element of each Tomcat's server.xml. The name of the Tomcat needs to be equal to the name of the corresponding load balancer member. In the above example, Tomcat on host "myhost1" needs jvmRoute="worker1", Tomcat on host "myhost2" needs jvmRoute="worker2".

For a complete reference of all load balancer configuration attributes, please consult the worker reference.

Advanced Load Balancer Worker Properties

The load balancer supports complex topologies and failover configurations. Using the member attribute distance you can group members. The load balancer will always send a request to a member of lowest distance. Only when all of those are broken, it will balance to the members of the next higher configured distance. This allows to define priorities between Tomcat instances in different data center locations.

When working with shared sessions, either by using session replication or a persisting session manager (e.g. via a database), one often splits up the Tomcat farm into replication groups. In case of failure of a member, the load balancer needs to know, which other members share the session. This is configured using the domain attribute. All workers with the same domain are assumed to share the sessions.

For maintenance purposes you can tell the load balancer to not allow any new sessions on some members, or even not use them at all. This is controlled by the member attribute activation. The value Active allows normal use of a member, disabled will not create new sessions on it, but still allow sticky requests, and stopped will no longer send any requests to the member. Switching the activation from "active" to "disabled" some time before maintenance will drain the sessions on the worker and minimize disruption. Depending on the usage pattern of the application, draining will take from minutes to hours. Switching the worker to stopped immediately before maintenance will reduce logging of false errors by mod_jk.

Finally you can also configure hot spare workers by using activation set to disabled in combination with the attribute redirect added to the other workers:

  # The advanced router LB worker
  worker.list=router
  worker.router.type=lb
  worker.router.balance_workers=worker1,worker2

  # Define the first member worker
  worker.worker1.type=ajp13
  worker.worker1.host=myhost1
  worker.worker1.port=8009
  # Define preferred failover node for worker1
  worker.worker1.redirect=worker2

  # Define the second member worker
  worker.worker2.type=ajp13
  worker.worker2.host=myhost2
  worker.worker2.port=8009
  # Disable worker2 for all requests except failover
  worker.worker2.activation=disabled

The redirect flag on worker1 tells the load balancer to redirect the requests to worker2 in case that worker1 has a problem. In all other cases worker2 will not receive any requests, thus acting like a hot standby.

A final note about setting activation to disabled: The session id coming with a request is send either as part of the request URL (;jsessionid=...) or via a cookie. When using bookmarks or browsers that are running since a long time, it is possible to send a request carrying an old and invalid session id pointing at a disabled member. Since the load balancer does not have a list of valid sessions, it will forward the request to the disabled member. Thus draining takes longer than expected. To handle such cases, you can add a Servlet filter to your web application, which checks the request attribute JK_LB_ACTIVATION. This attribute contains one of the strings "ACT", "DIS" or "STP". If you detect "DIS" and the session for the request is no longer active, delete the session cookie and redirect using a self-referential URL. The redirected request will then no longer carry session information and thus the load balancer will not send it to the disabled worker. The request attribute JK_LB_ACTIVATION has been added in version 1.2.32.

Status Worker properties

The status worker does not communicate with Tomcat. Instead it is responsible for the worker management. It is especially useful when combined with load balancer workers.

  # Add the status worker to the worker list
  worker.list=jkstatus
  # Define a 'jkstatus' worker using status
  worker.jkstatus.type=status

Next thing is to mount the requests to the jkstatus worker. For Apache web servers use the:

  # Add the jkstatus mount point
  JkMount /jkmanager/* jkstatus 

To obtain a higher level of security use the:

  # Enable the JK manager access from localhost only
 <Location /jkmanager/>
    JkMount jkstatus
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
 </Location>

Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/common_howto/printer/proxy.html0000644000000000000020000005073412555256555023535 0ustar rootbinThe Apache Tomcat Connectors - Common HowTo - Reverse Proxy HowTo
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Common HowTo

Reverse Proxy HowTo

Introduction

The Apache module mod_jk and its ISAPI and NSAPI variants connect a web server to a backend (typically Tomcat) using the AJP protocol. The web server receives an HTTP(S) request and the module forwards the request to the backend. This function is usually called a gateway or a proxy, in the context of HTTP it is called a reverse proxy.

Typical Problems

A reverse proxy is not totally transparent to the application on the backend. For instance the host name and port the original client (e.g. browser) needs to talk to belong to the web server and not to the backend, so the reverse proxy talks to a different host name and port. When the application on the backend returns content including self-referential URLs using its own backend address and port, the client will usually not be able to use these URLs.

Another example is the client IP address, which for the web server is the source IP of the incoming connection, whereas for the backend the connection always comes from the web server. This can be a problem, when the client IP is used by the backend application e.g. for security reasons.

AJP as a Solution

Most of these problems are automatically handled by the AJP protocol and the AJP connectors of the backend. The AJP protocol transports this communication metadata and the backend connector presents this metadata whenever the application asks for it using Servlet API methods.

The following list contains the communication metadata handled by AJP and the ServletRequest/HttpServletRequest API calls which can be used to retrieve them:

  • local name: getLocalName(). This is also equal to getServerName(), unless a Host header is contained in the request. In this case the server name is taken from that header.
  • local IP address: getLocalAddr(). The local IP address was initially not supported. It is available when using mod_jk 1.2.41 with Apache or IIS (not for the NSAPI plugin) together with Tomcat version at least 6.0.42, 7.0.55 or 8.0.11. For older versions, getLocalAddr() will incorrectly return the same result as getLocalName(). As a workaround you can forward the local IP address by setting JkEnvVar SERVER_ADDR and then either using request.getAttribute("SERVER_ADDR") instead of getLocalAddr() or wrapping the request using a filter and overriding getLocalAddr() with request.getAttribute("SERVER_ADDR").
  • local port: getLocalPort(). This is also equal to getServerPort(), unless a Host header is contained in the request. In this case the server port is taken from that header if it contains an explicit port, or is equal to the default port of the scheme used.
  • client address: getRemoteAddr()
  • client port: getRemotePort(). The remote port was initially not supported. It is available when using mod_jk 1.2.32 with Apache or IIS (not for the NSAPI plugin) together with Tomcat version at least 5.5.28, 6.0.20 or 7.0.0. For older versions, getRemotePort() will incorrectly return 0 or -1. As a workaround you can forward the remote port by setting JkEnvVar REMOTE_PORT and then either using request.getAttribute("REMOTE_PORT") instead of getRemotePort() or wrapping the request using a filter and overriding getRemotePort() with request.getAttribute("REMOTE_PORT").
  • client host: getRemoteHost()
  • authentication type: getAuthType()
  • remote user: getRemoteUser(), if tomcatAuthentication="false"
  • protocol: getProtocol()
  • HTTP method: getMethod()
  • URI: getRequestURI()
  • HTTPS used: isSecure(), getScheme()
  • query string: getQueryString()
The following additional SSL-related data will be made available by Apache and forwarded by mod_jk only if you set SSLOptions +StdEnvVars. For the certificate information you also need to set SSLOptions +ExportCertData.
  • SSL cipher: getAttribute(javax.servlet.request.cipher_suite)
  • SSL key size: getAttribute(javax.servlet.request.key_size). Can be disabled using JkOptions -ForwardKeySize.
  • SSL client certificate: getAttribute(javax.servlet.request.X509Certificate). If you want the whole certificate chain, then you need to also set JkOptions ForwardSSLCertChain. It is likely, that in this case you also need to adjust the maximal AJP packet size using the worker attribute max_packet_size.
  • SSL session ID: getAttribute(javax.servlet.request.ssl_session). This is for Tomcat, it has not yet been standardized.

Fine Tuning

In some situations this is not enough though. Assume there is another less clever reverse proxy in front of your web server, for instance an HTTP load balancer or similar device which also serves as an SSL accelerator.

Then you are sure that all your clients use HTTPS, but your web server doesn't know about that. All it can see is requests coming from the accelerator using plain HTTP.

Another example would be a simple reverse proxy in front of your web server, so that the client IP address that your web server sees is always the IP address of this reverse proxy, and not of the original client. Often such reverse proxies generate an additional HTTP header, like X-Forwareded-for which contains the original client IP address (or a list of IP addresses, if there are more cascading reverse proxies in front). It would be nice, if we could use the content of such a header as the client IP address to pass to the backend.

So we might need to manipulate some of the data that AJP sends to the backend. When using mod_jk inside Apache httpd you can use several httpd environment variables to let mod_jk know, which data it should forward. These environment variables can be set by the httpd directives SetEnv or SetEnvIf, but also in a very flexible way using mod_rewrite (since httpd 2.x it can not only test against environment variables, but also set them).

The following list contains all environment variables mod_jk checks, before sending data to the backend:

  • JK_LOCAL_NAME: the local name
  • JK_LOCAL_PORT: the local port
  • JK_REMOTE_HOST: the client host
  • JK_REMOTE_ADDR: the client address
  • JK_AUTH_TYPE: the authentication type
  • JK_REMOTE_USER: the remote user
  • HTTPS: On (case-insensitive) to indicate, that HTTPS is used
  • SSL_CIPHER: the SSL cipher
  • SSL_CIPHER_USEKEYSIZE: the SSL key size
  • SSL_CLIENT_CERT: the SSL client certificate
  • SSL_CLIENT_CERT_CHAIN_: prefix of variable names, containing the client cerificate chain
  • SSL_SESSION_ID: the SSL session ID

Remember: in general you don't need to set them. The module retrieves the data automatically from the web server. Only in case you want to change this data, you can overwrite it by using these variables.

Some of these variables might also be used by other web server modules. All variables whose name does not begin with "JK" are set directly by Apache httpd. If you want to change the data, but do not want to negatively influence the behaviour of other modules, you can change the names of all variables mod_jk uses to private ones. For the details see the Apache reference page.

All variables, that are not SSL-related have only been introduced in version 1.2.27.

In addition there are two special shortcuts to influence the client IP address that is forwarded. Using JkOptions ForwardLocalAddress you can forward the local IP address of the web server as the client IP address. This can be useful, e.g. when using the Tomcat remote address valve for allowing connections only from registered Apache web servers. Using JkOptions ForwardPhysicalAddress you always forward the physical peer IP address as the client address. By default mod_jk uses the logical address as provided by the web server. For example the module mod_remoteip sets the logical IP address to the client IP forwarded by proxies in the X-Forwarded-For header.

Tomcat AJP Connector Settings

As an alternative to using the environment variables described in the previous section (which do only exist when using Apache httpd), you can also configure Tomcat to overwrite some of the communications data forwarded by mod_jk. The AJP connector in Tomcat's server.xml allows to set the following properties:

  • proxyName: server name as returned by getServerName()
  • proxyPort: server port as returned by getServerPort()
  • scheme: protocol scheme as returned by getScheme()
  • secure: set to "true", if you wish isSecure() to return "true".
Remember: in general you don't need to set those. AJP automatically handles all cases where the web server running mod_jk knows the right data.

URL Handling

URL Rewriting

Sometimes one want to change path components of the URLs under which an application is available. Especially if a web application is deployed as some context, say /myapp, marketing prefers short URLs, so want the application to be directly available under http://www.mycompany.com/. Although you can deploy the application as the so-called ROOT context, which will be directly available at "/", admins often prefer not to use the ROOT context, e.g. because only one application can be the root context (per host).

The procedure to change the URLs in the reverse proxy is tedious, because often an application produces self-referential URLs, which then include the path components which you tried to hide to the outside world. Nevertheless, if you absolutely need to do it, here are the steps.

Case A: You need to make the application available at a simple URL, but it is OK, if users proceed using the more complex URLs, as long as they don't have to type them in. That's the easy case, and if this suffices to you, you're lucky. Use a simply RedirectMatch for Apache httpd:

RedirectMatch ^/$ http://www.mycompany.com/myapp/

Your application will then be available under http://www.mycompany.com/, and each visitor will be immediately redirected to the real URL http://www.mycompany.com/myapp/

Case B: You need to hide path components for all requests going to the application. Here's the recipe for the case, where you want to hide the first path component /myapp. More complex manipulations are left as an exercise to the reader. First the solution for the case of Apache httpd:

1. Use mod_rewrite to add /myapp to all requests before forwarding to the backend:

# Don't forget the PT flag! (pass through)
RewriteRule ^/(.*) http://www.mycompany.com/myapp/$1 [PT]

2. Use mod_headers to rewrite any HTTP redirects your application might return. Such redirects typically contain the path components you want to hide, because by the HTTP standard, redirects always need to include the full URL, and your application is not aware of the fact, that your clients talk to it via some shortened URL. An HTTP redirect is done with a special response header named Location. We rewrite the Location headers of our responses:

# Keep protocol, server and port if present,
# but insert our webapp name before the rest of the URL
Header edit Location ^([^/]*//[^/]*)?/(.*)$ $1/myapp/$2 

3. Use mod_headers again, to rewrite the paths contained in any cookies, your application might set. Such cookie paths again might contain the path components you want to hide. A cookie is set with the HTTP response header named Set-Cookie. We rewrite the Set-Cookie headers of our responses:

# Fix the cookie path
Header edit Set-Cookie "^(.*; Path=/)(.*)" $1/myapp/$2 

3. Some applications might contain hard coded absolute links. In this case check, whether you find a configuration item for your web framework to configure the base URL. If not, your only chance is to parse all response content bodies and do search and replace. This is fragile and very resource intensive. If you really need to do this, you can use mod_proxy_html, mod_substitute or mod_sed for this task.

If you are using Microsoft IIS as a web server, the ISAPI plugin provides a way of doing the first step with a builtin feature. You define a mapping file for simple prefix changes like this:

# Add a context prefix to all requests ...
/=/myapp/
# ... or change some prefix ...
/oldapp/=/myapp/

and then put the name of the file in the rewrite_rule_file entry of the registry or your isapi_redirect.properties file. In your uriworkermap.properties file, you still need to map the URLs as they are before rewriting!

More complex rewrites can be done using the same file, but with regular expressions. A leading tilde sign '~', indicates, that you are using a regular expression:

# Use a regular expression rewrite
~/oldapps([0-9]*)/=/newapps$1/

There is no support for Steps 2 (rewriting redirect responses) or 3 (rewriting cookie paths).

URL Encoding

Some types of problems are triggered by the use of encoded URLs (see percent encoding). For the same location there exist a lot of different URLs which are equivalent. The reverse proxy needs to inspect the URL in order to apply its own authentication rules and to decide, to which backend it should send the request (or whether it should handle it itself). Therefore the request URL first is normalized: percent encoded characters are decoded, /./ is replaced by /, /XXX/../ is replaced by / and similar manipulations of the URL are done. After that, the web server might apply rewrite rules to further change the URL in less obvious ways. Finally there is no more way to put the resulting URL in an encoding, which is "similar" to the one which was used for the original URL.

For historical reasons, there have been several alternatives, how mod_jk and the ISAPI plugin encoded the resulting URL before sending it to the backend. They could be chosen via JkOptions (Apache httpd) or uri_select (ISAPI). None of those historical encodings are recommended, because they have either negative functionality implications or pose a security risk. The default encoding since version 1.2.24 is ForwardURIProxy (Apache httpd) or proxy (ISAPI) and it is strongly recommended to keep the default and remove all old explicit settings.

Request Attributes

You can also add more attributes to any request you are forwarding when using Apache httpd. For this use the JkEnvVar directive (for details see the Apache reference page). Such request attributes can be retrieved on the Tomcat side via request.getAttribute(attributeName). Note that their names will not be listed in request.getAttributeNames()!


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/common_howto/printer/quick.html0000644000000000000020000001627612555256555023473 0ustar rootbinThe Apache Tomcat Connectors - Common HowTo - Quick Start HowTo
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Common HowTo

Quick Start HowTo

Introduction

This document describes the configuration files used by JK on the Web Server side for the 'impatient':

  • workers.properties is a mandatory file used by the webserver and which is the same for all JK implementations (Apache/IIS/NES).
  • web server add-ons to be set on the webserver side.

We'll give here minimum servers configuration and an example workers.properties to be able to install and check quickly your configuration.

Minimum workers.properties

Here is a minimum workers.properties, using just ajp13 to connect your Apache webserver to the Tomcat engine, complete documentation is available in Workers HowTo.


  # Define 1 real worker using ajp13
  worker.list=worker1
  # Set properties for worker1 (ajp13)
  worker.worker1.type=ajp13
  worker.worker1.host=localhost
  worker.worker1.port=8009

Minimum Apache web server configuration

Here is a minimum information about Apache configuration, a more complete separate HowTo for Apache is available.

You should first have mod_jk.so (unix) or mod_jk.dll (Windows) installed in your Apache module directory (see your Apache documentation to locate it).

Usual locations for modules directory on Unix:

  • /usr/lib/apache/
  • /usr/lib/apache2/
  • /usr/local/apache/libexec/

Usual locations for modules directory on Windows :

  • C:\Program Files\Apache Group\Apache\modules\
  • C:\Program Files\Apache Group\Apache2\modules\

You'll find a link to prebuilt binaries here

Here is the minimum which should be set in httpd.conf directly or included from another file:

Usual locations for configuration directory on Unix:

  • /etc/httpd/conf/
  • /etc/httpd2/conf/
  • /usr/local/apache/conf/

Usual locations for configuration directory on Windows :

  • C:\Program Files\Apache Group\Apache\conf\
  • C:\Program Files\Apache Group\Apache2\conf\


  # Load mod_jk module
  # Update this path to match your modules location
  LoadModule    jk_module  libexec/mod_jk.so
  # Declare the module for <IfModule directive> (remove this line on Apache 2.x)
  AddModule     mod_jk.c
  # Where to find workers.properties
  # Update this path to match your conf directory location (put workers.properties next to httpd.conf)
  JkWorkersFile /etc/httpd/conf/workers.properties
  # Where to put jk shared memory
  # Update this path to match your local state directory or logs directory
  JkShmFile     /var/log/httpd/mod_jk.shm
  # Where to put jk logs
  # Update this path to match your logs directory location (put mod_jk.log next to access_log)
  JkLogFile     /var/log/httpd/mod_jk.log
  # Set the jk log level [debug/error/info]
  JkLogLevel    info
  # Select the timestamp log format
  JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
  # Send everything for context /examples to worker named worker1 (ajp13)
  JkMount  /examples/* worker1

Minimum IIS web server configuration

A separate HowTo for the IIS web server is available.

This paragraph has not been written yet, but you can contribute to it.

Minimum NES/iPlanet/Sun web server configuration

A separate HowTo for the Netscape/iPlanet/Sun web server is available.

This paragraph has not been written yet, but you can contribute to it.

Test your configuration

(Re)start the web server and browse to the http://localhost/examples/


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/common_howto/printer/timeouts.html0000644000000000000020000005373412555256555024230 0ustar rootbinThe Apache Tomcat Connectors - Common HowTo - Timeouts HowTo
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Common HowTo

Timeouts HowTo

Introduction

Setting communication timeouts is very important to improve the communication process. They help to detect problems and stabilise a distributed system. JK can use several different timeout types, which can be individually configured. For historical reasons, all of them are disabled by default. This HowTo explains their use and gives hints how to find appropriate values.

All timeouts can be configured in the workers.properties file. For a complete reference of all worker configuration items, please consult the worker reference. This page assumes, that you are using at least version 1.2.16 of JK. Dependencies on newer versions will be mentioned where necessary.

Do not set timeouts to extreme values. Very small timeouts will likely be counterproductive.

Long Garbage Collection pauses on the backend do not make a good fit with some timeouts. Try to optimise your Java memory and GC settings.

JK Timeout Attributes

CPing/CPong

CPing/CPong is our notion for using small test packets to check the status of backend connections. JK can use such test packets directly after establishing a new backend connection (connect mode) and also directly before each request gets send to a backend (prepost mode). Starting with version 1.2.27 it can also be used when a connection was idle for a long time (interval mode). The maximum waiting time (timeout) for a CPong answer to a CPing and the idle time in interval mode can be configured.

The test packets will be answered by the backend very fast with a minimal amount of needed processing resources. A positive answer tells us, that the backend can be reached and is actively processing requests. It does not detect, if some context is deployed and working. The benefit of CPing/CPong is a fast detection of a communication problem with the backend. The downside is a slightly increased latency.

The worker attribute ping_mode can be set to a combination of characters to determine, in which situations test packets are used:

  • C: connect mode, timeout ping_timeout overwritten by connect_timeout
  • P: prepost mode, timeout ping_timeout overwritten by prepost_timeout
  • I: interval mode, timeout ping_timeout, idle time connection_ping_interval
  • A: all modes

Multiple values must be concatenated without any separator characters. We recommend using all CPing tests. If your application is very latency sensitive, then you should only use the combination of connect and interval mode.

Activating the CPing probing via ping_mode has been added in version 1.2.27. For older versions only the connect and prepost modes exist and must be activated by explicitely setting connect_timeout and prepost_timeout.

The worker attribute ping_timeout sets the default wait timeout in milliseconds for CPong for all modes. By default the value is "10000" milliseconds. The value only gets used, if you activate CPing/Cpong probes via ping_mode. The default value should be fine, except if you experience very long Java garbage collection pauses. Depending on your network latency and stability, good custom values often are between 5000 and 15000 milliseconds. You can overwrite the timeout used for connect and prepost mode with connect_timeout and prepost_timeout. Remember: don't use extremely small values.

The worker attribute connect_timeout sets the wait timeout in milliseconds for CPong during connection establishment. You can use it if you want to overwrite the general timeout set with ping_timeout. To use connect mode CPing, you need to enable it via ping_mode. Since JK usually uses persistent connections, opening new connections is a rare event. We therefore recommend activating connect mode. Depending on your network latency and stability, good values often are between 5000 and 15000 milliseconds. Remember: don't use extremely small values.

The worker attribute prepost_timeout sets the wait timeout in milliseconds for CPong before request forwarding. You can use it if you want to overwrite the general timeout set with ping_timeout. To use prepost mode CPing, you need to enable it via ping_mode. Activating this type of CPing/CPong adds a small latency to each request. Usually this is small enough and the benefit of CPing/CPong is more important. So in general we also recommend using prepost_timeout. Depending on your network latency and stability, good values often are between 5000 and 10000 milliseconds. Remember: don't use extremely small values.

Until version 1.2.27 ping_mode and ping_timeout did not exist and to enable connect or prepost mode CPing you had to set connect_timeout respectively prepost_timeout to some reasonable positive value.

Low-Level TCP Timeouts

Some platforms allow to set timeouts for all operations on TCP sockets. This is available for Linux and Windows, other platforms do not support this, e.g. Solaris. If your platform supports TCP send and receive timeouts, you can set them using the worker attribute socket_timeout. You can not set the two timeouts to different values.

JK will accept this attribute even if your platform does not support socket timeouts. In this case setting the attribute will have no effect. By default the value is "0" and the timeout is disabled. You can set the attribute to some seconds value (not: milliseconds). JK will then set the send and the receive timeouts of the backend connections to this value. The timeout is low-level, it is used for each read and write operation on the socket individually.

Using this attribute will make JK react faster to some types of network problems. Unfortunately socket timeouts have negative side effects, because for most platforms, there is no good way to recover from such a timeout, once it fired. For JK there is no way to decide, if this timeout fired because of real network problems, or only because it didn't receive an answer packet from a backend in time. So remember: don't use extremely small values.

For the general case of connection establishment you can use socket_connect_timeout. It takes a millisecond value and works on most platforms, even if socket_timeout is not supported. We recommend using socket_connect_timeout because in some network failure situations failure detection during connection establishment can take several minutes due to TCP retransmits. Depending on the quality of your network a timeout somewhere between 1000 and 5000 milliseconds should be fine. Note that socket_timeout is in seconds, and socket_connect_timeout in milliseconds.

Connection Pools and Idle Timeouts

JK handles backend connections in a connection pool per web server process. The connections are used in a persistent mode. After a request completed successfully we keep the connection open and wait for the next request to forward. The connection pool is able to grow according to the number of threads that want to forward requests in parallel.

Most applications have a varying load depending on the hour of the day or the day of the month. Other reasons for a growing connection pool would be temporary slowness of backends, leading to an increasing congestion of the frontends like web servers. Many backends use a dedicated thread for each incoming connection they handle. So usually one wants the connection pool to shrink, if the load diminishes.

JK allows connections in the pool to get closed after some idle time. This maximum idle time can be configured with the attribute connection_pool_timeout which is given in units of seconds. The default value is "0", which disables closing idle connections.

We generally recommend values around 10 minutes, so setting connection_pool_timeout to 600 (seconds). If you use this attribute, please also set the attribute keepAliveTimeout (if it is set explicitly) or connectionTimeout in the AJP Connector element of your Tomcat server.xml configuration file to an analogous value. Caution: keepAliveTimeout and connectionTimeout must be given in milliseconds. So if you set JK connection_pool_timeout to 600, you should set Tomcat keepAliveTimeout or connectionTimeout to 600000.

JK connections do not get closed immediately after the timeout passed. Instead there is an automatic internal maintenance task running every 60 seconds, that checks the idle status of all connections. The 60 seconds interval can be adjusted with the global attribute worker.maintain. We do not recommend to change this value, because it has a lot of side effects. Until version 1.2.26, the maintenance task only runs, if requests get processed. So if your web server has processes that do not receive any requests for a long time, there is no way to close the idle connections in its pool. Starting with version 1.2.27 you can configure an independent watchdog thread when using Apache 2.x with threaded APR or IIS.

The maximum connection pool size can be configured with the attribute connection_pool_size. We generally do not recommend to use this attribute in combination with Apache httpd. For Apache httpd we automatically detect the number of threads per process and set the maximum pool size to this value. For IIS we use a default value of 250 (before version 1.2.20: 10), for the Sun Web Server the default is "1". We strongly recommend adjusting this value for IIS and the Sun Web Server to the number of requests one web server process should be able to send to a backend in parallel. You should measure how many connections you need during peak hours without performance problems, and then add some percentage depending on your growth rate etc. Finally you should check, whether your web server processes are able to use at least as many threads, as you configured as the pool size.

The JK attribute connection_pool_minsize defines, how many idle connections remain when the pool gets shrunken. By default this is half of the maximum pool size.

Firewall Connection Dropping

One particular problem with idle connections comes from firewalls, that are often deployed between the web server layer and the backend. Depending on their configuration, they will silently drop connections from their status table if they are idle for to long.

From the point of view of JK and of the web server, the other side simply doesn't answer any traffic. Since TCP is a reliable protocol it detects the missing TCP ACKs and tries to resend the packets for a relatively long time, typically several minutes. Therefore you should always use connection_pool_timeout and connection_pool_minsize on the JK side and keepAliveTimeout or connectionTimeout on the Tomcat side to prevent idle connection drop.

Furthermore using the boolean attribute socket_keepalive you can set a standard socket option, that automatically sends TCP keepalive packets after some idle time on each connection. By default this is set to false. If you suspect idle connection drops by firewalls you should set this to true.

Unfortunately the default intervals and algorithms for these packets are platform specific. You might need to inspect TCP tuning options for your platform on how to control TCP keepalive. Often the default intervals are much longer than the firewall timeouts for idle connections. Nevertheless we recommend talking to your firewall administration and your platform administration in order to make them agree on good configuration values for the firewall and the platform TCP tuning.

In case none of our recommendations help and you are definitively having problems with idle connection drops, you can disable the use of persistent connections when using JK together with Apache httpd. For this you set "JkOptions +DisableReuse" in your Apache httpd configuration. The amount of performance impact this will have depends on the details of your network and your firewall.

Reply Timeout

JK can also use a timeout on request replies. This timeout does not measure the full processing time of the response. Instead it controls, how much time between consecutive response packets is allowed.

In most cases, this is what one actually wants. Consider for example long running downloads. You would not be able to set an effective global reply timeout, because downloads could last for many minutes. Most applications though have limited processing time before starting to return the response. For those applications you could set an explicit reply timeout. Applications that do not harmonise with reply timeouts are batch type applications, data warehouse and reporting applications which are expected to observe long processing times.

If JK aborts waiting for a response, because a reply timeout fired, there is no way to stop processing on the backend. Although you free processing resources in your web server, the request will continue to run on the backend - without any way to send back a result once the reply timeout fired.

JK uses the worker attribute reply_timeout to set reply timeouts. The default value is "0" (timeout disabled) and you can set it to any millisecond value.

In combination with Apache httpd, you can also set a more flexible reply_timeout using an httpd environment variable. If you set the variable JK_REPLY_TIMEOUT to some integer value, this value will be used instead of the value in the worker configuration. This way you can set reply timeouts more flexible with mod_setenvif and mod_rewrite depending on URI, query string etc. If the environment variable JK_REPLY_TIMEOUT is not set, or is set to a negative value, the default reply timeout of the worker will be used. If JK_REPLY_TIMEOUT contains the value "0", then the reply timeout will be disabled for the request.

In combination with a load balancing worker, JK will disable a member worker of the load balancer if a reply timeout fires. The worker will then no longer be used until it gets recovered during the next automatic maintenance task. Starting with JK 1.2.24 you can improve this behaviour using max_reply_timeouts. This attribute will allow occasional long running requests without disabling the worker. Only if those requests happen to often, the worker gets disabled by the load balancer.

Load Balancer Error Detection

Local and Global Error States

A load balancer worker does not only have the ability to balance load. It also handles stickyness and failover of requests in case of errors. When a load balancer detects an error on one of its members, it needs to decide, whether the error is serious, or only a temporary error or maybe only related to the actual request that was processed. Temporary errors are called local errors, serious errors will be called global errors.

If the load balancer decides that a backend should be put into the global error state, then the web server will not send any more requests there. If no session replication is used, this means that all user sessions located on the respective backend are no longer available. The users will be send to another backend and will have to login again. So the global error state is not transparent to the users. The application is still available, but users might loose some work.

In some cases the decision between local error and global error is easy. For instance if there is an error sending back the response to the client (browser), then it is very unlikely that the backend is broken. So this situation is a typical example of a local error.

Some situations are harder to decide though. If the load balancer can't establish a new connection to a backend, it could be because of a temporary overload situation (so no more free threads in the backend), or because the backend isn't alive any more. Depending on the details, the right state could either be local error or global error.

Error Escalation Time

Until version 1.2.26 most errors were interpreted as global errors. Starting with version 1.2.27 many errors which were previously interpreted as global were switched to being local whenever the backend is still busy. Busy means, that other concurrent requests are send to the same backend (successful or not).

In many cases there is no perfect way of making the decision between local and global error. The load balancer simply doesn't have enough information. In version 1.2.28 you can now tune, how fast the load balancer switches from local error to global error. If a member of a load balancer stays in local error state for too long, the load balancer will escalate it into global error state.

The time tolerated in local error state is controlled by the load balancer attribute error_escalation_time (in seconds). The default value is half of recover_time, so unless you changed recover_time the default is 30 seconds.

Using a smaller value for error_escalation_time will make the load balancer react faster to serious errors, but also carries the risk of more often loosing sessions in not so serious situations. You can lower error_escalation_time down to 0 seconds, which means all local errors which are potentially serious are escalated to global errors immediately.

Note that without good basic error detection the whole escalation procedure is useless. So you should definitely use socket_connect_timeout and activate CPing/CPong with ping_mode and ping_timeout before thinking about also tuning error_escalation_time.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/common_howto/quick.html0000644000000000000020000002453012555256555022000 0ustar rootbinThe Apache Tomcat Connectors - Common HowTo - Quick Start HowTo
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Common HowTo

Quick Start HowTo

Printer Friendly Version
print-friendly
version
Introduction

This document describes the configuration files used by JK on the Web Server side for the 'impatient':

  • workers.properties is a mandatory file used by the webserver and which is the same for all JK implementations (Apache/IIS/NES).
  • web server add-ons to be set on the webserver side.

We'll give here minimum servers configuration and an example workers.properties to be able to install and check quickly your configuration.

Minimum workers.properties

Here is a minimum workers.properties, using just ajp13 to connect your Apache webserver to the Tomcat engine, complete documentation is available in Workers HowTo.


  # Define 1 real worker using ajp13
  worker.list=worker1
  # Set properties for worker1 (ajp13)
  worker.worker1.type=ajp13
  worker.worker1.host=localhost
  worker.worker1.port=8009

Minimum Apache web server configuration

Here is a minimum information about Apache configuration, a more complete separate HowTo for Apache is available.

You should first have mod_jk.so (unix) or mod_jk.dll (Windows) installed in your Apache module directory (see your Apache documentation to locate it).

Usual locations for modules directory on Unix:

  • /usr/lib/apache/
  • /usr/lib/apache2/
  • /usr/local/apache/libexec/

Usual locations for modules directory on Windows :

  • C:\Program Files\Apache Group\Apache\modules\
  • C:\Program Files\Apache Group\Apache2\modules\

You'll find a link to prebuilt binaries here

Here is the minimum which should be set in httpd.conf directly or included from another file:

Usual locations for configuration directory on Unix:

  • /etc/httpd/conf/
  • /etc/httpd2/conf/
  • /usr/local/apache/conf/

Usual locations for configuration directory on Windows :

  • C:\Program Files\Apache Group\Apache\conf\
  • C:\Program Files\Apache Group\Apache2\conf\


  # Load mod_jk module
  # Update this path to match your modules location
  LoadModule    jk_module  libexec/mod_jk.so
  # Declare the module for <IfModule directive> (remove this line on Apache 2.x)
  AddModule     mod_jk.c
  # Where to find workers.properties
  # Update this path to match your conf directory location (put workers.properties next to httpd.conf)
  JkWorkersFile /etc/httpd/conf/workers.properties
  # Where to put jk shared memory
  # Update this path to match your local state directory or logs directory
  JkShmFile     /var/log/httpd/mod_jk.shm
  # Where to put jk logs
  # Update this path to match your logs directory location (put mod_jk.log next to access_log)
  JkLogFile     /var/log/httpd/mod_jk.log
  # Set the jk log level [debug/error/info]
  JkLogLevel    info
  # Select the timestamp log format
  JkLogStampFormat "[%a %b %d %H:%M:%S %Y] "
  # Send everything for context /examples to worker named worker1 (ajp13)
  JkMount  /examples/* worker1

Minimum IIS web server configuration

A separate HowTo for the IIS web server is available.

This paragraph has not been written yet, but you can contribute to it.

Minimum NES/iPlanet/Sun web server configuration

A separate HowTo for the Netscape/iPlanet/Sun web server is available.

This paragraph has not been written yet, but you can contribute to it.

Test your configuration

(Re)start the web server and browse to the http://localhost/examples/


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/common_howto/timeouts.html0000644000000000000020000006217412555256555022543 0ustar rootbinThe Apache Tomcat Connectors - Common HowTo - Timeouts HowTo
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Common HowTo

Timeouts HowTo

Printer Friendly Version
print-friendly
version
Introduction

Setting communication timeouts is very important to improve the communication process. They help to detect problems and stabilise a distributed system. JK can use several different timeout types, which can be individually configured. For historical reasons, all of them are disabled by default. This HowTo explains their use and gives hints how to find appropriate values.

All timeouts can be configured in the workers.properties file. For a complete reference of all worker configuration items, please consult the worker reference. This page assumes, that you are using at least version 1.2.16 of JK. Dependencies on newer versions will be mentioned where necessary.

Do not set timeouts to extreme values. Very small timeouts will likely be counterproductive.

Long Garbage Collection pauses on the backend do not make a good fit with some timeouts. Try to optimise your Java memory and GC settings.

JK Timeout Attributes

CPing/CPong

CPing/CPong is our notion for using small test packets to check the status of backend connections. JK can use such test packets directly after establishing a new backend connection (connect mode) and also directly before each request gets send to a backend (prepost mode). Starting with version 1.2.27 it can also be used when a connection was idle for a long time (interval mode). The maximum waiting time (timeout) for a CPong answer to a CPing and the idle time in interval mode can be configured.

The test packets will be answered by the backend very fast with a minimal amount of needed processing resources. A positive answer tells us, that the backend can be reached and is actively processing requests. It does not detect, if some context is deployed and working. The benefit of CPing/CPong is a fast detection of a communication problem with the backend. The downside is a slightly increased latency.

The worker attribute ping_mode can be set to a combination of characters to determine, in which situations test packets are used:

  • C: connect mode, timeout ping_timeout overwritten by connect_timeout
  • P: prepost mode, timeout ping_timeout overwritten by prepost_timeout
  • I: interval mode, timeout ping_timeout, idle time connection_ping_interval
  • A: all modes

Multiple values must be concatenated without any separator characters. We recommend using all CPing tests. If your application is very latency sensitive, then you should only use the combination of connect and interval mode.

Activating the CPing probing via ping_mode has been added in version 1.2.27. For older versions only the connect and prepost modes exist and must be activated by explicitely setting connect_timeout and prepost_timeout.

The worker attribute ping_timeout sets the default wait timeout in milliseconds for CPong for all modes. By default the value is "10000" milliseconds. The value only gets used, if you activate CPing/Cpong probes via ping_mode. The default value should be fine, except if you experience very long Java garbage collection pauses. Depending on your network latency and stability, good custom values often are between 5000 and 15000 milliseconds. You can overwrite the timeout used for connect and prepost mode with connect_timeout and prepost_timeout. Remember: don't use extremely small values.

The worker attribute connect_timeout sets the wait timeout in milliseconds for CPong during connection establishment. You can use it if you want to overwrite the general timeout set with ping_timeout. To use connect mode CPing, you need to enable it via ping_mode. Since JK usually uses persistent connections, opening new connections is a rare event. We therefore recommend activating connect mode. Depending on your network latency and stability, good values often are between 5000 and 15000 milliseconds. Remember: don't use extremely small values.

The worker attribute prepost_timeout sets the wait timeout in milliseconds for CPong before request forwarding. You can use it if you want to overwrite the general timeout set with ping_timeout. To use prepost mode CPing, you need to enable it via ping_mode. Activating this type of CPing/CPong adds a small latency to each request. Usually this is small enough and the benefit of CPing/CPong is more important. So in general we also recommend using prepost_timeout. Depending on your network latency and stability, good values often are between 5000 and 10000 milliseconds. Remember: don't use extremely small values.

Until version 1.2.27 ping_mode and ping_timeout did not exist and to enable connect or prepost mode CPing you had to set connect_timeout respectively prepost_timeout to some reasonable positive value.

Low-Level TCP Timeouts

Some platforms allow to set timeouts for all operations on TCP sockets. This is available for Linux and Windows, other platforms do not support this, e.g. Solaris. If your platform supports TCP send and receive timeouts, you can set them using the worker attribute socket_timeout. You can not set the two timeouts to different values.

JK will accept this attribute even if your platform does not support socket timeouts. In this case setting the attribute will have no effect. By default the value is "0" and the timeout is disabled. You can set the attribute to some seconds value (not: milliseconds). JK will then set the send and the receive timeouts of the backend connections to this value. The timeout is low-level, it is used for each read and write operation on the socket individually.

Using this attribute will make JK react faster to some types of network problems. Unfortunately socket timeouts have negative side effects, because for most platforms, there is no good way to recover from such a timeout, once it fired. For JK there is no way to decide, if this timeout fired because of real network problems, or only because it didn't receive an answer packet from a backend in time. So remember: don't use extremely small values.

For the general case of connection establishment you can use socket_connect_timeout. It takes a millisecond value and works on most platforms, even if socket_timeout is not supported. We recommend using socket_connect_timeout because in some network failure situations failure detection during connection establishment can take several minutes due to TCP retransmits. Depending on the quality of your network a timeout somewhere between 1000 and 5000 milliseconds should be fine. Note that socket_timeout is in seconds, and socket_connect_timeout in milliseconds.

Connection Pools and Idle Timeouts

JK handles backend connections in a connection pool per web server process. The connections are used in a persistent mode. After a request completed successfully we keep the connection open and wait for the next request to forward. The connection pool is able to grow according to the number of threads that want to forward requests in parallel.

Most applications have a varying load depending on the hour of the day or the day of the month. Other reasons for a growing connection pool would be temporary slowness of backends, leading to an increasing congestion of the frontends like web servers. Many backends use a dedicated thread for each incoming connection they handle. So usually one wants the connection pool to shrink, if the load diminishes.

JK allows connections in the pool to get closed after some idle time. This maximum idle time can be configured with the attribute connection_pool_timeout which is given in units of seconds. The default value is "0", which disables closing idle connections.

We generally recommend values around 10 minutes, so setting connection_pool_timeout to 600 (seconds). If you use this attribute, please also set the attribute keepAliveTimeout (if it is set explicitly) or connectionTimeout in the AJP Connector element of your Tomcat server.xml configuration file to an analogous value. Caution: keepAliveTimeout and connectionTimeout must be given in milliseconds. So if you set JK connection_pool_timeout to 600, you should set Tomcat keepAliveTimeout or connectionTimeout to 600000.

JK connections do not get closed immediately after the timeout passed. Instead there is an automatic internal maintenance task running every 60 seconds, that checks the idle status of all connections. The 60 seconds interval can be adjusted with the global attribute worker.maintain. We do not recommend to change this value, because it has a lot of side effects. Until version 1.2.26, the maintenance task only runs, if requests get processed. So if your web server has processes that do not receive any requests for a long time, there is no way to close the idle connections in its pool. Starting with version 1.2.27 you can configure an independent watchdog thread when using Apache 2.x with threaded APR or IIS.

The maximum connection pool size can be configured with the attribute connection_pool_size. We generally do not recommend to use this attribute in combination with Apache httpd. For Apache httpd we automatically detect the number of threads per process and set the maximum pool size to this value. For IIS we use a default value of 250 (before version 1.2.20: 10), for the Sun Web Server the default is "1". We strongly recommend adjusting this value for IIS and the Sun Web Server to the number of requests one web server process should be able to send to a backend in parallel. You should measure how many connections you need during peak hours without performance problems, and then add some percentage depending on your growth rate etc. Finally you should check, whether your web server processes are able to use at least as many threads, as you configured as the pool size.

The JK attribute connection_pool_minsize defines, how many idle connections remain when the pool gets shrunken. By default this is half of the maximum pool size.

Firewall Connection Dropping

One particular problem with idle connections comes from firewalls, that are often deployed between the web server layer and the backend. Depending on their configuration, they will silently drop connections from their status table if they are idle for to long.

From the point of view of JK and of the web server, the other side simply doesn't answer any traffic. Since TCP is a reliable protocol it detects the missing TCP ACKs and tries to resend the packets for a relatively long time, typically several minutes. Therefore you should always use connection_pool_timeout and connection_pool_minsize on the JK side and keepAliveTimeout or connectionTimeout on the Tomcat side to prevent idle connection drop.

Furthermore using the boolean attribute socket_keepalive you can set a standard socket option, that automatically sends TCP keepalive packets after some idle time on each connection. By default this is set to false. If you suspect idle connection drops by firewalls you should set this to true.

Unfortunately the default intervals and algorithms for these packets are platform specific. You might need to inspect TCP tuning options for your platform on how to control TCP keepalive. Often the default intervals are much longer than the firewall timeouts for idle connections. Nevertheless we recommend talking to your firewall administration and your platform administration in order to make them agree on good configuration values for the firewall and the platform TCP tuning.

In case none of our recommendations help and you are definitively having problems with idle connection drops, you can disable the use of persistent connections when using JK together with Apache httpd. For this you set "JkOptions +DisableReuse" in your Apache httpd configuration. The amount of performance impact this will have depends on the details of your network and your firewall.

Reply Timeout

JK can also use a timeout on request replies. This timeout does not measure the full processing time of the response. Instead it controls, how much time between consecutive response packets is allowed.

In most cases, this is what one actually wants. Consider for example long running downloads. You would not be able to set an effective global reply timeout, because downloads could last for many minutes. Most applications though have limited processing time before starting to return the response. For those applications you could set an explicit reply timeout. Applications that do not harmonise with reply timeouts are batch type applications, data warehouse and reporting applications which are expected to observe long processing times.

If JK aborts waiting for a response, because a reply timeout fired, there is no way to stop processing on the backend. Although you free processing resources in your web server, the request will continue to run on the backend - without any way to send back a result once the reply timeout fired.

JK uses the worker attribute reply_timeout to set reply timeouts. The default value is "0" (timeout disabled) and you can set it to any millisecond value.

In combination with Apache httpd, you can also set a more flexible reply_timeout using an httpd environment variable. If you set the variable JK_REPLY_TIMEOUT to some integer value, this value will be used instead of the value in the worker configuration. This way you can set reply timeouts more flexible with mod_setenvif and mod_rewrite depending on URI, query string etc. If the environment variable JK_REPLY_TIMEOUT is not set, or is set to a negative value, the default reply timeout of the worker will be used. If JK_REPLY_TIMEOUT contains the value "0", then the reply timeout will be disabled for the request.

In combination with a load balancing worker, JK will disable a member worker of the load balancer if a reply timeout fires. The worker will then no longer be used until it gets recovered during the next automatic maintenance task. Starting with JK 1.2.24 you can improve this behaviour using max_reply_timeouts. This attribute will allow occasional long running requests without disabling the worker. Only if those requests happen to often, the worker gets disabled by the load balancer.

Load Balancer Error Detection

Local and Global Error States

A load balancer worker does not only have the ability to balance load. It also handles stickyness and failover of requests in case of errors. When a load balancer detects an error on one of its members, it needs to decide, whether the error is serious, or only a temporary error or maybe only related to the actual request that was processed. Temporary errors are called local errors, serious errors will be called global errors.

If the load balancer decides that a backend should be put into the global error state, then the web server will not send any more requests there. If no session replication is used, this means that all user sessions located on the respective backend are no longer available. The users will be send to another backend and will have to login again. So the global error state is not transparent to the users. The application is still available, but users might loose some work.

In some cases the decision between local error and global error is easy. For instance if there is an error sending back the response to the client (browser), then it is very unlikely that the backend is broken. So this situation is a typical example of a local error.

Some situations are harder to decide though. If the load balancer can't establish a new connection to a backend, it could be because of a temporary overload situation (so no more free threads in the backend), or because the backend isn't alive any more. Depending on the details, the right state could either be local error or global error.

Error Escalation Time

Until version 1.2.26 most errors were interpreted as global errors. Starting with version 1.2.27 many errors which were previously interpreted as global were switched to being local whenever the backend is still busy. Busy means, that other concurrent requests are send to the same backend (successful or not).

In many cases there is no perfect way of making the decision between local and global error. The load balancer simply doesn't have enough information. In version 1.2.28 you can now tune, how fast the load balancer switches from local error to global error. If a member of a load balancer stays in local error state for too long, the load balancer will escalate it into global error state.

The time tolerated in local error state is controlled by the load balancer attribute error_escalation_time (in seconds). The default value is half of recover_time, so unless you changed recover_time the default is 30 seconds.

Using a smaller value for error_escalation_time will make the load balancer react faster to serious errors, but also carries the risk of more often loosing sessions in not so serious situations. You can lower error_escalation_time down to 0 seconds, which means all local errors which are potentially serious are escalated to global errors immediately.

Note that without good basic error detection the whole escalation procedure is useless. So you should definitely use socket_connect_timeout and activate CPing/CPong with ping_mode and ping_timeout before thinking about also tuning error_escalation_time.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/images/0000755000000000000020000000000012555256553016525 5ustar rootbintomcat-connectors-1.2.41-src/docs/images/printer.gif0000644000000000000020000000066612555256553020707 0ustar rootbinGIF89a ÄÿÿÿÿÿÞßÞÖ×ÖÎÏÎÎ1ÆÇƵ¶µ¥¦¥œžœ”–”„†„sqscžcacÿ0œÀÀÀ!ù, ÿ $ŽdI.¨©®ê2¦l\º3-³4Õw[ê"C$Ò›‰€$a‘”HØ$HåRÒ”äv#i±:0<Ú×Ë8@±¢ê©/‹áA G†¬ä~rt^ yD"nxz €r…(Š‹# ‰ yo“‡B~ š‹4TAp‡¸ª««‹ˆ¯ ”±””ˆ¹o¼« qÁǸˆoɪšjDÁ’“T‰^Îkp¼ÌŒ í” ÎåçÙC# ë íàûòòÐK6„'ÑŠù/ß< †¨2ØhÂbþ)8oˆ½û—Àa5ï3™Pi1‘Æ’Cò½a¹â c ‘猦Œ!à¼ì è³ÈyrÊ+:EÂK)6]É4F;tomcat-connectors-1.2.41-src/docs/images/void.gif0000644000000000000020000000005312555256553020153 0ustar rootbinGIF89a€ÿÿÿÿÿÿ!ù ,L;tomcat-connectors-1.2.41-src/docs/images/docs.gif0000644000000000000020000000040512555256553020143 0ustar rootbinGIF89a„ÿÿÿþþþ000ðððààà///111ÀÀÀÏÏÏßßß¿¿¿ÐÐÐýÿþ/10ÎÎÎÞàßÀÀ¾þÿÿ€€€NNN___ááá°°°OOOáßàÿÿý002,Š Ždi–A0ªç(¼p ŸÂ`ß¡Åi ‡àA$&> bX4"Mµ`‘ iƒâ˜è>IŒÁÑìv_’€P6Ó.6ñáF@ࢵњ Bî& Uf}vx…rˆ4lŽxy–˜(Ž ¡-23­³³£³!;tomcat-connectors-1.2.41-src/docs/images/design.gif0000644000000000000020000000114012555256553020461 0ustar rootbinGIF89aÆÿÿÿþþþþÿÿ???>>>??=@@@=?>>@?*EVe¹èO¿ÿB±ø?®ö2£é-Ÿæ“Ù‹Ñ ƒÄz²%sšJbòÿÿÿÿý*FT1¢èIaooopno@>?¯¯¯ïïïðîïðððÏÏÏ¿¿¿°°°   «¡ŸÿþÿÍÒÎÂή¿¯®¾±©Â¬‘¥”®®®ÏÑлÀº¡¯¢“­’~ nod|dSkS#}&¾ÐIJϹ¤Í«›Ð¦“Π¿ˆÐ‘u܃¼Á»¡®¤•®™~ ‡m’sk‰q*w/ÁϯÀ°±¿°°¾¯¬Á®ÐÐв®­ÐÎÏÏÏÑ,Å€‚‚ƒƒ†Šƒ…‹Ž’••Ž Š¢¤§©«®Š¼½¾ŽÅÆ !ÂÄ"#$%%&&̃''ÃÅ()*++*,-ØŠ./012345667ç†Ã(89:;<=>>?ê 2 H!Cˆ‘gD  nPA‚$‰’%æ!¢äŒI4M¬]æÄÉ“'"R¦d"Â!¥˜,ɬ4)Ò¤›’lâ;tomcat-connectors-1.2.41-src/docs/images/tomcat.gif0000644000000000000020000000402212555256553020501 0ustar rootbinGIF89a’\ÄÿÿÿÒ¦)ýÝu" GB4pl^¨”W‹r+’’‘ÓÓÓóóô³´´Ð´bñÑp¸”.!ù,’\ÿ Ždižhª®bQ(l,›LÁ”P®C@>ú³ pxRŽq ¨!Q¼_´7eZ¯%ÃñHH`e í–%ñν¯úJØn_k”¢í(qæ4:Οbc7}" umƒx?"QU„4 uGŠq[^&UŽ‘¤&†–˜_š[ Z'¡‹¥¶Z®[wX†–¹¸¶ÃD•– _ ʺËÄÕ`mǩПV tu“ÍÖç( GÒÈÐd# õö÷ Í¿–ìä˜CGpÄv@3`´‡“@1`¯‚èR¤¨ ¢ÇcÄU^5¥~tT¹Çxw̵ܜç©ÙÖŠYwQ€ Hçí{¦nÍ›3L8nÿþõñ2?À«äänÁ+:Pðy–Õ¿¹²¹ìˆ‡ÏëîOI5§½Î[ŠpŽWáâÇ/³*÷@ý¿)otî²ülÎe˜à-{a ñ:U0/€tÞ$—ˆYÇ/êàa2åY΃”_¯àóë! ƒ¿ÀDà¸ð@f=@y@JÅ׫èL8‘à €Sª ªª…ëgX´çÍÆP:$Pdá>Ú‰¯`D¤áN cBž%1@€PU‡E)úCH¼" ð'ÿ"îm0c¿¶‰¶ð b,„Ô8·^Ñq°sÙ¯À¶¿8’ñ "ŇF.$fR9Œ£þ8 $P!dü ç2€ÜI}YÙ%á?.J2~`[Ðþæ— ¹ßCœ'?IÈa(¿ Àñ é5ñaƒ•ÛËðÊ‚ è´ÔL†I̘Ü—òãZå FJ“¸ˆº,‘%rä˜`™s“àÅ€ð…]“8rôl6¬#ÛL¢*<Ci~ä(¤™fK0D<†rÍ´†)óè2Á0Àï[d<è‘“•¸¤ž!” ¸Œ‚@_þok£$û<²AôÌ£Pþ9J*gè‚×ÿ’t,·¦*ÛLô!=ü­P…+ 4›ß<`VéÑý4t…ɧA¦£)—2Œ&CM™ŽpÖÁb<Í!|:CJÂѡ˘٠Ypš1|ÁV]+P KóTMâxª@êˆþ³¬:G†á3ÜQt5>+Zcœëê þ鎆ÆmË`jÙZÄÅéÊc(aŒjE»!S¸ÛhøÂz°¨ÆÕ¯JªjNrÔKÕ€ë ŠV'æÑê x}H¯€›oå¥åš*$~C¢2§«’.‹„Ìâk³‹¹HeØ 4‡¢‘HV%m‰ÏH8ÐanU]QÚ[+”³g4ŠNç Ø{IP¶D°Õ=¶[Ù!ØÊ´¶ @!»é¦Ã(…S­"gkZNÎ?ØXËÆ”­ ˜B§{É5»£¹?CÈòŽÐÜûÊ@¸GI«ÿ&ÑË_@“ÀŽ‚÷Äw9Éeò¯}#¼† ‡o„:ÝMw9¬×Q®+ ™Š»4b—ˆ±Œgì?µ¹x½ÂÉIœc”!;tomcat-connectors-1.2.41-src/docs/images/code.gif0000644000000000000020000000061212555256553020125 0ustar rootbinGIF89a¥ÿÿÿþþþ000ðððààà///111ÀÀÀVVãssä]]êÏÏÏßßß¿¿¿––Î..ô¢¢ÚŠŠßEEï••êJJôýÿþ/10ÎÎÎddñ||í¸¸ÔÇÇã22øÆÇãÀÀ¾þÿÿ€€ÔKKõ@@退€NNN___ÈÈäûkkÛø««Å°°°OOO°®ç––Ìÿÿý002‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”,¯@€pH,‹ÀPy žÐ(ô(X¯‚–P8‡0"‘P, Üp< 7Zm¬†#’³dBHSgxg ~E eh tE† “T—q›o”D–g† ¦F }’ °§B† !g"»±u#$%&' ()*+½N,+-.ÛÓÔH//#+°ÝÞM00RSêððàðA;tomcat-connectors-1.2.41-src/docs/images/add.gif0000644000000000000020000000201512555256553017742 0ustar rootbinGIF89açÿÿÿÿþÿþþþÿÿýþÿÿ# ê£aì¥c 4Àn ì£_ÿ¡Iÿ­Uï´r ÿüï5؉Pñ†8ùCÞ˜\Cö¡Qý¡Jÿ­Sý±Yÿ½fôÄ„ ÿüñ1ݘ]ï“@ÿ@ÿžCý¢Iý±[ÿ½dóà æÓµ ÿþô$ ä˜Mÿž>ÿŸAóà õÓ–ûЋðÒ  é£^õ¤Ué²yI+ 8."0000026/%A/ ïЙùщõÑ•î±n÷²díÀ‡>,˜¢×°û ÐÿµØëïЗúÑ‚õÒñÀ~ûÁwìÄ‘ */B—³Û“Âðµ×ò àÇ©5/#äÒ®,-I€†Úžÿ«Êùÿ÷ÿJKšR)£:‰1!zohÅxwì†õ7«»Ô ÿúÿEP*»OÜdÿk2ýwNòhÔ2ÿüÿ FR%³e*ärCß)ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ò ÀÀƒppÀ€ƒ&dˆ‰ p(£@†0p„(XÀ ÀÈ@ˆP ,\ÀAÃ<|yD#H”0ñàŠ*V°háâà 1d˜øÙaÆ5lÜÀQu :vðèáã B†)’0‚‘#H’(Y¤‰“'P¢HIøa •*V®`É¢e —.Dz òL1c–)c¦ãCgФQ³†M7oàÄ‘3¡EsèÔ±sO={øôé30âÀ~þ $hEQ ,°›7ÆçУG§(@@;tomcat-connectors-1.2.41-src/docs/images/jakarta-logo.gif0000644000000000000020000002061012555256553021566 0ustar rootbinGIF89aù0ç:5:[Q,‡{Dß:³«N¿JñÉ[£%·.•#Ñ;Td-ð×\‡*÷T@™5Mðá]~ &æSI÷|J†2Em¡/èàbîîî¶V:NÈ‘v_ "v8:\I’ˆI®¦bK>–T=çÎbÐEöòŠ[]_¶ivŠ•N &‘hk<5¸±[ÚÙÙ:Jf.Y¸xP.--c*]î3t2¡–YbF2}FöööÝBvh7˜Œf= Sö£Q¢,F¶®jÈĈÜ,Tˤ„îæj¢‚IZxY;>¥´ºfed¥:o{ƒÁ=Y6ÊEîÒfúúúL#4Rm>>>c&`Ú$Ako“pQ§šeÝ9Xv6S{oFááà/ IÎvЇGC7$2 DlùhF 08¤*["4” *ʦ¦ÒÒв²°h6M¯o^’~^¼)Qž%DŽ-Oª Rö›WÌixì<Ž":è5R4g‡ a–¤¬TTUºº†•S„ÚÊj––•€[_MXIJJöHAn0ééè¡D3µÄÈþþþi"^®¢jƒ?qË´˜vP‚`lpìxJÎʘb 2‰œ¦‚*Q¥H” \Ö>*0’&R°W~ 2Í(Vö1¹›‘õ4>´®n.UuDvljh¼SQ5W{(9ï»ZK)PrSoèiMvvvò>àÍ˦¦¥³AKN 6’fV¶Œxòòòî~Ftt¯gb0"5h7ie,<‡HgÎ~††|N| f~>F”T[$%a:dÄ»¼¶¶Š·|y€€º¤”ÐÌÆ†1p a` N{c_ô$>u¢`…††n[Arrr¬®¯?TiDvhú‹KïµTX"b AP&&&μ}ù3žžê)Ju*UY8e¾J„$`!þ+Thanks to Brian.Ewins@i-documentsystems.com,ù0þ H° Áå4\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç CŠôè…ÍÈ“(Sª\ɲ¥Ë—0c†œá¥¢—‰^¤xL¦ÏŸ@ƒ J´¨LCePô”¨¤'"ikñ1Ó‹…TOª‹ÆuiVƒÇ¸FS÷µ,A b£a5›Ò‹KâElR.Qº=kí¨¡¾VjîyÑH >¶«(^¼8QÑ@–cìÊècº¥dر¡ŠÝ0¨ÂRÃM/³@Žê¬˜O4“'_ˆPS¤¡7S›%3ŸÊ _¨P²&ŠgJö&²U @Œ5ê©Ñ©1@øð½X‹xàìïRþù]ˆeÑšQ†þŽ'Åõ£YŽBò2{ÑÀCz™í>¤ýôl€oêHÁÐ]å ¢Ä#*çÉP³CsÈàa!¡pÓ 7ÜÒŠWÝI!☉hàc‘é¤CA/Äó‚ÉöÝgDý—|ßÕ6|¤­4fvdß}˜‘’!£D“$wÙØ]<½a&@1º´F<“ìÍ#{4ˆ@ùÔ…PœC—\’F…Ôa u0AŒ,E胈_ýHÐcU "^ (Zý8[]5Ò‡’!é4Š#¡ñÈR4Šzd_ÝtSŽ ¢UÙÝž•v·Š¢Í ñÁÇ$“ðÑ¥4þ‰¬áÌpØp@þ@Å `áWàQidÃ+ô|‚9àüUVztÙ(Ï`¶D":”À‹®@D÷™gÐ,äêfˆ4ÝÄ#A³\éJ7ÒăêAƒn:k¬ëä ®¸¢£A%M9鬑³ýÛn<ïÆ;¯@’T.¹éÐ"º®¤ó°@W<‹ð!Z1»"_Ǥó.Ç0É}Uˆ(P9³×±ÄëŽÀ«Hóo"R[².'ðÀ3dÃݤS›Ì0rÉw²¶˜€‚rR ‡ (LÂe"­XbIöÌf=ÈQf—ÜÑ\dƒGuܸÉÌþ†Ü0ã‰\FQ ¨ã%B"iêp­†`öóAñˆ¦Íl§3›"óG‘g"† 9²@ÿy1¹hBœÜáÇyDÒÌ+ Žttƒ…=bƒÒ·­ì²—¿þÍÉ 'š2¬¤ŠÆ1†”MÅ®ŒFÄ40½¨  M€£0‡q a½èE)̦¿P$cš`ÄÎAÒ Àá—hÎ%žêàáá  °9}N>Á“ÖQÁD„æ[«ë¤AB¨ lÑp cÔè9HÙe6a¡<ņ2àRÏz”@PXñP4^¡htäÔ1DR€ÐÜ ƒ :ÊUó;KXB Õ ™½Ð ‰[¡C˜ˆ­!ш=ƒÅ\áDÌø®‹õ”ÞQ¹Vž‚Õ¨Õ[—žÅÿØ¡y X¨>Ì@€ˆ#¨„~Œ£É…ðh ]° µi8þ€l ÿ銂ôÕž€V0C$G8Žeã¦'™¤Nu) ¨ Å膟ŠFp‡…Å ˆY²·jc4PãD¸åá²}³Ù ¹9̬â`j5È«EXÊR4ÊYÈ,ë :uwÝ+ˆ ÁUjŽS}\áƒ)wˆNÌ– íÍé@¤†™ƒ6±ë…°hÞ+Ù¸ìdNÂ,½VAáÙ`ÒpÅhWÌyà"m6z! ~¤müØ#Û@R”é PduaÕ 6¸‡*È LÄB N I³ÓžbkÖkóþ$¼zK»P­Øl¼âWˆN4Égþ‰\Å@.æ\92LÚ¤ÌU0¥h`Ÿifw\lãß*a‚Ðõ ^°%‘öŠÄ¬å¨ñ² R-ÌU±cai8ÑLšÍq»Qâ~Î`óà@8ð jø`ãÀB°Œ`°Öΰ%ô7‡9|@¶P8@ Sƒ¼ÂWG&‡² ì­oàÈ ¹„:TÊ•LÍvÈv1™½‘sÂQCBEü&¢Îr†¯ìB=öœ•H¨,HUKØßËÀ¹à¢Ç]ÂA,¾ìbAÄÍíz¢»|T'¿£'ê³Ä¥Äâ>`Às`ޏ8.2ŠGFô‚µg›ÕþΠ Røªw@išLq7V¼ãw«A x¢­ˆ²YôM$D=ÍMœ\¼<šn¤ÌÞ_¹Ó{îÙð!IPWÒX"‚ØÚ½ ®8úžë+BòZi6BD<ªNh:TF#Ë: t6F1ƒpÅÆžˆUˆæZ¶ ³¦eWgD=êd±O¼•ŽvQ»¢{pÅ#š°Y!,!ÚÐs禱TØàÀP ãf‚Ö§G™p‡ÇaþcyuÀ‰A~€2…À!îñŠW8¡jhµ‹²åF#UïMÏôTgDlÃüæ½;N#þÈóS|®—AT,úÀþéBæ×{ëÁ·˜Eã 2–»wóÏà3ƒ‚ðŸv¾/ÉØÝÒ osÃW÷Œ%¨à¡(Ѓ0†0 y ’·û0«¦j‡ã ßpZÉ Ô`ÇÁ0Âc{t¡²Çv ` ¬€,¹p—PÕ‘d2 ‹° ÆÐ 9W€DQ`%TÛ–26Õ7 5cî±tæ–Tô^ôï—DÁ‡kQg|FN91Vnݶ9™v…mwv˜Z/|æ—svt×]à'%æsæTôAñÇ÷8µab¸/° ¬òªòÐ;a Xà4þ˜ gep óðýPq7߉H@ ãPò #W¹ÀQp)… +À.øð`d5` $  ` að D,è S¿¹w ê`ƒååéc=&4‡¢mzD¨Ô{]5Ø#à^!Ðs^\ˆ€3F¯BjÝ wûõ„Ô„Œa…mïÆiuwT,Ä„mµn@$Tß&0"ˆåIGxäØfO£CŒ\VpàHý€Gö` Ê€GzÀD6PþGVmÀ )Ui`Ë€@vp´Çµx¾ PÖ ɇD¸Aa(VõsœSºÁY ¥0ò”¢‘M%&n¦¢3U0XjíV)X©•àÁu=‚Œí—ÄÑ :µQ†£ÔOU 1óÅYfw|Åt—l·BÑ@Oâ$ýQ–U@Eéq|Ó— ‡˜³Q}y†la+ñ ®¢(Ð%5¡Ð ³b ŒÐ Í@ òÓ yB €¬Vqщ_à§SP½ gÀ6õ€»Æ‚„¦àe6ð“ÜÃvd°ŠN€7}sáþP‹°‚¶·»Ð£Dñƒq|81F÷Ñ÷˜À‡Xî–pú§…Í':°•ßjDtwëÒž³¡o㑘씳 yúö}kf ŠFÀG˜Vè÷8ÞètCsE®3Ú<IFÕ ^`JP  2 **npùp¤Prà –àY Ô€ ûР ó  8Z—X >ÀHP ‚¼– ¯Åbr&à |tæ`Ôaœxp9`.Xrà ¬@p‚÷ ddPúÐ#‘>œyau1FlÀBP9`w ãUh@Ó *{„þ[¨]gVÏà)qÉÔ‹ú¸B|jo>5¡@CO a,T•qTzY³@D=R`3 Ij…¹‡ù;‚™Œñ†!épfð ÁdÅ g( #Ÿ ˜˜õV¡¢“ð&: 4’xpÓ L¤0sÀ,€£µ€ y0>Ó00Ѐã hkfã ÁP Éà’²»6+À ‚¹àceò 6ŠGÆÈ'$çЮü°}ó ²'YžP‘ s,±]³ M)·±F±_ª¨Á87a ûªDS2éÇ8š~ñ° R2³3;†2c·þ}šmvš±ç¦IëI&;²l±k€²{Ô5P@à?cpõ  ¢àš4P Õ Š0¥@$e°Óµ¬6 ÕÀq¤…S6s`cÀZÙ H—@š [p¶’&p#ï   õ@RàrPx÷ Sd@@c°¸á=¸Žû¸Qi˜A±;X2Ä!­PD[™`!p$Œ­VµÔµH€ ²é£˜¡€X‹É ø ŒÀQTP µÐ ü0¤˜ b« ›pº¢+ p¾`lÙÂÒ Ì@W@èþP‹¹` –ðÈ Y@×° /ð@)Ѹ•{¾èk93ÀYs‰¾("ÇàÇ0´/ˆ¥50xÐŒà Îð´ÕàP[ ¢À ˜ˆœ¥pj>0 X°Zz —84p²ÅfS‘,Ðk|t=¦+¦  éʉ'•Rc w³!Ÿð›½ÀQm mÚ°G–ÄP¾¥ê¾8Üpêù|9¼Ï"¶`qPgðÕqG†ÿàš ¨ÀÀ:ú‘˜àºêƒ ¨€ ºicÕ r  e…à :†Œ°Z–Pº°¶erâ‚[@qsôq¹{hà¹edL@]þa¾=<ÈŸ¢žBP„ŒÄ@¬ !pP¯à‚z@ þðPÅ:*ÅÿÀ‚ ó`ÀÐh¬‹µ¬… ²[ /Ö›æ  úc¨ð´0°½l“ p RÞ0 “8ã` và[¹Àº’Räpnà5øÃ5DC¹‰Í_1 2 ÍÒ씇€ôpÕA p¢œ`µ`6k|‘¢°»º[  µþ;Õ€ ó0 ‰DÚàf¯6 IZVð<4ð€ò  (i\à»p› ¼ ‰` p2!¼Œp¸@ Ö` ûÐjð¦Ú4%ŠÈ×<Ò$]Òq dþ÷ Í.ç‚™°ÕàÀõÐkü­–ÀÍpÎP‹ ® ®Ù ,4 €¡ŒDÀp hÓ Õ@GÁy¬¢c+Üì?6ГXq>` Äö›¬ÕcÀ Ÿ ,3• ÷ð5À Ö Äpíp Q '€°&×z½×E0„pôÀ àDÀ ,P™`çÉsà ¸v»6êZzÀæ0ö€É\[ ó`óУ›æ-J} Zûóy² ·;rJk T’à¡°¯€ œ¹°7|ó[°Ñ[¾ $À?ð×p ] CC Ò|þ=ÝÔmÒ†° ´Pù  „à ÷ðàù[a2£õ0Áv~ÀÙö& Π] 0 Ó,@Êpˆû VÌJjf@Xà»fi@ !9‰æðcS‰ã0i°H¦Pzô$LVJÙ7p•!Ý'QŽz[²*è8T/¾ê`$ Ñ˜#aÍî‹âîÛ8)@ Y¸Œ°d‘Ü cPà68ÍqcP¤ÀÞ*έ®•ß6 ,PåëlŠ  Ø fðß÷!¥`X; ¯6;6H‰¸°Èvd‚ÀÍk&‡pÊR‹þá âP7•`ë`= A`k@žQù¥t~Vœ Ú€°U€\ñõ›.–sÍŽî¾lÐé(a ìP±P~Ps°Õq þ`—p9@@ ¯9@lO¾´T>~°´šcö XP Õ  Ðßµ0@1@· ÔG]ÚÞ2¹0¥Ø0  (Õ Љ7F ¹`Ø¿)€â è°FÀ 7à < ³ê{é3é$1•*ð#Ñ 6Ÿ.Íú~¾BÀÌ*q  à @ô@ v !LÞ '5Š&ð@ð‚ðJ ›þü°cçM ÿ€kŠÐksÀÓÕº`£¸€ Iêf ðŒ bp o±ª¼£ Øž 90Ê0xDwpÂÕ±Gp À• ë°)ÐQÀ •Ðîëpk)ép Rãs¡šÉÁôhÙ :@3Àð<÷ á x9y¿:À2tBK ÅДo4Å0U€t-‘á«À€"¯aÝ€}bö‘£ ø«@¹^ ³ A(ú‰¿ø¿UŠ*¦:öR“…`á'so(âìÆ°Ïð9RPe ® õG„4‹À@„€@þps3ÄÕ¬Íñ&Õ±·Í1³^z& š +¡À¶9 ´ª¹å,ð¸ ?\Ð< xôÓ ›0€ V@¨€ Ñ~  y™)S@Aî ²'8xœÇ£„„8… „¸ Tª´H /‰<~R$È*Bø¬I€È5BF¥‹'¤BÒ¥3R!Ý^Sd7³Fz¬òâh¢Aé–z”’ŽO´‘(Ò½XƒbÆÈnT¡4Rš´c/\¹s”€hB=êàfGR^¾8VÅÓ‘«Ø¬y1*ÀÈtf\4X䨲gÝ‚¤-Þšr«D–äó¢°º‘êf¼þЯ̾!©œ/ÀJ‘F¹Œw¹ àrr¦[RZ÷î£^NÑqC‚$FjÔȆî½pðàyÇ„«ÏñdsžÊ¥KÎ3‘¦@& @isà@=Ršø±ç£Y³qh,9K–‡Ã~0šYP™<¾á€š/QfTæÙgLn1˜2 °Â2„pgàÁ#@ ‹v@ñ."‡\ám)8óH°.‹«*ŽÚÉ(¤, I CÒ‘i$R$)ˆÔ­›Qø2¤¨¡–Œ†Ýfè&-j)tk²È9R©ÒÑæ#)ÊÀò(*EbÌéÅQþ ¤!uLDy‚ENóÒ#ž9Š:¹ò(>Òü²Ñ¥|\C˜7®ùá‡Åœ36G¥–^zQ†zQ*¹šº€fÛ1ìâˆ.Ä a‘­ú_ƒ?ª‚Q¨ºþ£ŠºÅE—…5‰½¸ ¿ÎÒ`(ž¶:ê¬%؈§'+?þ7é… 6Î")ˆ†6ŸÚàh¨ÿÈ{ðŘ䥂ODó4€hŒ¢€÷ãþ&(‚Y~$ñ¢Œ—ˆý΂K9†8@CFp@ ôVƒy!àÐÛª:Ñ ¸ÕàÈ0Ž& 7~8q¨Ž©:Nàä¸Äs®°‰ñ4à§ëE3`xîРzÀÎC,tËɰÁvEŽÿØÃ8¨ˆ½@t„DÁ#BÀ) á€ÜÀƒ†Bð»âÕo$ òpd>C}éHíKD󔉩 AÊÑP<6ƒÜ© Ò«B=²“™$€˜"-É— LQ Í>±=’x’üJ9~F0&¬Lüê’™@šàDÕØ—^З#yÁ "þ‰7°ª<¨ÄM±B ŒpÇŽƒŽ;0C¡¸T €p½­ÐDhÕŒS&\¡UÊ`%œ•.êÌÅÆamn68ÇxLð„9Ô£¦àEP¸ ë@ XG±¯­P”u©‚4F"…npo|¸¼Y]2’¼,åà’ ¦<d/TÙ *wâRàÉtcÚ¤G8É›60I S(v$FÍô”"Ä+ÿ‡¥V&¢“#É,ÞÔ#PÔ©-mÔ@" !@m‚e é/Åú|AÂèZ°_ЃÌ0ÅÙ±ƒ* £òŧìþº®0p7M•¬šðg=<`‡nâáõ8@.Æ™œgq Àƒ©Î-î ÁB€Jdà ACê‚!XТÉKD4¡ƒ©’4jR¨-OÓ¡)«Úƒj"^=?% MG4À'½´|V…J[ßÚt)MÚWnÑ !dÏUÈi'§@ÒÀ”c À ¤0 (ÕLÒ¥.P9‹2ŒÂ(^(.ñX™Ó* 'Rx*©z\¸¢»‰˜Å –Ôš[B%|Hw¯’Àv¬6©!z PÁ^Ü!³5„h tó‡@:èñŠþ\ÊgëÄâ`V –m3¸1d˜b;¦è&,Ïñx€Cf9¶p7Sˆ#E@%Bà ð` Èx‘­ò«ŽÂ’6(V¬‚BùMÄNÑ®Ajì·!)ƒvAR†2/¥u‰ ´½'}de©j(ÔQ›R ©GA¡*´écì¥Gž1¡GÚ2K˜4ª\EËwM"ñxP†L[4§‰ …é#-X$¦ÕçIcmITHÊ¡Q ›7î>ñ†]„:±8Bòcz„a8d8DÞj`xL‡䈱[õÃÂÜágÈñ vþ¯HÃs ˆ*H@fñ€LÜ Øri+‰nרuyÔÇ–§5/xÕ‡*Í3t`ƒ·H ¤n¤Ð¾YT¼4:ðx<ª°q¾\<ã“Ôs£Ö{òGi å~ôtH´Qçƒ×üKÁlE$ޱ†n£N‡) Í:>>??=@@@=?>>@?*EVe¹èO¿ÿB±ø?®ö2£é-Ÿæ“Ù‹Ñ ƒÄz²%sšJbòÿÿÿÿý*FT1¢èIaooopno@>?¯¯¯ïïïðîïðððÏÏÏ¿¿¿°°°    ÿþÿÍÒÎÂή¿¯®¾±©Â¬2 ›Ä¢5E:®®®ÏÑлÀº¡¯¢“­’~ nod|d$,#}&Y¿\/t1 /%¾ÐIJϹ¤Í«›Ð¦“Π¿7ˆÐ‘u܃XÊjtÜ…”Þ¡*¼Á»¡®¤•®™~ ‡m’sk‰q$**w/؆4q5 / ÁϯÀ°±¿°°¾¯¬Á® -¯ÍµÐÐв®­«¡Ÿ#ÐÎÏÏÏÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,Ø€‚‚ƒƒ†Šƒ…‹Ž’••Ž Š¢¤§©«®Š¼½¾ŽÅÆ !ÂÄ"#$%Ô&Öƒ''ÃÅ()*++*,-./‰†0123456789:;<=>é(?@ABCˆ1rI%K XǤ‰“'P¢H™B¥Š•+ùqû€K–,Z¶péâE Dˆ(9û͘0aÄ\S4`Ì2dDèÔùEÄa0YZiR¤IH%M:(;tomcat-connectors-1.2.41-src/docs/images/fix.gif0000644000000000000020000000053112555256553020001 0ustar rootbinGIF89a¥ÿÿÿþþþŸŸŸ€€€ÀÀÀ°°° OOOÁÁÁŒ{s¢t\ŒN7J<ÿûûÿÿý€¯±°,B“K2ÿ¯¦S .þÿÿþþü3–J2ÿ®—QÿûúÿûôC“K5Q 0ÿ¯˜Qÿûó“K3R R>‰O9è¼±3ÿüûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,~@€ȤrY\2KÁ`*… „BÁ@8 ’M‘H¦NÅ`‘eœŸƒCQh8ˆ$9™`)FCX^B !"K#$C%&'()FaJ‘*+zVB,&-. ¨*/0–Vª1234°B¾ÂþA;tomcat-connectors-1.2.41-src/docs/news/0000755000000000000020000000000012555256556016237 5ustar rootbintomcat-connectors-1.2.41-src/docs/news/20150101.html0000644000000000000020000001366712555256556020033 0ustar rootbinThe Apache Tomcat Connectors - News - 2015 News & Status
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - News

2015 News & Status

Printer Friendly Version
print-friendly
version
2015 News & Status
JK-1.2.41 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.41. This is a maintenance and security release.

This release includes the fix for CVE-2014-8111.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/20090301.html0000644000000000000020000001704312555256556020030 0ustar rootbinThe Apache Tomcat Connectors - News - 2009 News and Status
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - News

2009 News and Status

Printer Friendly Version
print-friendly
version
2009 News & Status

22 March - JK-1.2.28 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.28. This is a stable release concentrating mainly on some bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

The most important new features in this version are:

Better Error Detection for Load Balancer Workers

Local and global error states have been improved. You can fine tune the behaviour with the new "error_escalation_time" attribute (see the timeouts documentation).

Dynamic Address and Port Change Using the Status Worker

The status worker now allows you to change the address and the port of an AJP13 worker on the fly. You can e.g. provision dummy workers with a port equal to "0", which will be automatically put into stopped mode during startup. Later, when you want to actually use these workers, you set their address and port to the final values.

Note that already existing connections will go on using the old address and port. This will be improved in future versions.

New Data in Status Worker Display

The status worker display now also contains the timestamp of the last worker errors.

Improved Proxy Flexibility

You can now overwrite more request metadata before the request gets send to the backend. This is helpful in case there are other reverse proxies in front of your web server. A new documentation page explains this in detail.

Improved IIS Support

IIS support has been improved especially when using mutltiple application pools. Furthermore you can now configure the ISAPI plugin to update the uriworkermap.properies file on a regular interval using the watchdog thread.

JNI Worker Deprecation

Workers of type jni are broken since a long time. Since there is no more use for them, they have been deprecated now, and will be removed in a future release.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/20140201.html0000644000000000000020000001551512555256556020025 0ustar rootbinThe Apache Tomcat Connectors - News - 2014 News and Status
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - News

2014 News and Status

Printer Friendly Version
print-friendly
version
2014 News & Status

15 April - JK-1.2.40 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.40. This is a stable release concentrating mainly on bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

11 March - JK-1.2.39 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.39. This is a stable release containing both bug fixes and few new features like IPV6 support. Note that version 1.2.38 was not released due to some minor issues found in release process.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/20100101.html0000644000000000000020000001760312555256556020020 0ustar rootbinThe Apache Tomcat Connectors - News - 2010 News and Status
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - News

2010 News and Status

Printer Friendly Version
print-friendly
version
2010 News & Status

1 November - JK-1.2.31 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.31. This is a stable release concentrating mainly on some bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


1 March - JK-1.2.30 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.30. This is a stable release concentrating mainly on some bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


1 March - JK-1.2.29 withdrawn

Tomcat Connectors 1.2.29 has been withdrawn because of regression inside Microsoft IIS connector.


26 February - JK-1.2.29 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.29. This is a stable release concentrating mainly on some bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/20041100.html0000644000000000000020000002337112555256556020022 0ustar rootbinThe Apache Tomcat Connectors - News - 2004 News and Status
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - News

2004 News and Status

Printer Friendly Version
print-friendly
version
2004 News & Status

17 December - JK-1.2.8 released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.8.

Please see the ChangeLog for a full list of changes.

If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


17 December - JK-1.2.8-rc-1 released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.8-rc-1 (Relase Canditate 1).

We expect it to be ratified as a Stable release when the vote takes place in the next week.

Please see the ChangeLog for a full list of changes.

If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


13 December - JK-1.2.7-beta-3 released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.7-beta-3. The release contains a fix to few configuration problems detected with JK-1.2.7-beta-2 version.

We expect it to be ratified as a Stable release when the vote takes place in the next week.

Please see the ChangeLog for a full list of changes.

If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


7 December - JK-1.2.7-beta-2 released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.7-beta-2. The release contains a fix to few compilation problems detected with JK-1.2.7-beta version. This release also introduces a new domain concept clustering support. See 32317 for details.

We expect it to be ratified as a Stable release when the vote takes place in the next two weeks.

Please see the ChangeLog for a full list of changes.

If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


30 November - JK-1.2.7-beta released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.7-beta. The release contains a significant number of bug fixes and new features.

We expect it to be ratified as a Stable release when the vote takes place in the next two weeks.

Please see the ChangeLog for a full list of changes.

Since release 1.2.7 the socket_timeout property has been renamed to recycle_timeout. The socket_timeout now sets the real timeout for socket operations.

If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


15 November - JK2 is officially unsupported

JK2 has been put in maintainer mode and no further development will take place. The reason for shutting down JK2 development was the lack of developers interest. Other reason was lack of users interest in adopting JK2, caused by configuration complexity when compared to JK.

The latest official JK2 release is 2.0.4.

JK2 will have it's successor within core Apache2.1/2.2 distribution. We have developed new proxy_ajp that is an addition to the mod_proxy and uses Tomcat's AJP protocol stack. It is developped in httpd-2.1 and integrated in it. We have also developed a new proxy_balancer module for load balancing http and ajp protocol stacks.

JK will be fully supported for all other web servers. The next JK release is planned for the end of November. Lots of code from JK2 has been ported to JK



Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/20050101.html0000644000000000000020000002417012555256556020021 0ustar rootbinThe Apache Tomcat Connectors - News - 2005 News and Status
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - News

2005 News and Status

Printer Friendly Version
print-friendly
version
2005 News & Status

8 November - JK-1.2.15 released

The Apache Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.15. This is Stable release and it contains few bug fixes found in 1.2.14 version.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


13 July - JK-1.2.14 released

The Apache Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.14. This is Stable release and it contains few bug fixes found in 1.2.13 version.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


7 May - JK-1.2.13 released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.13. This is development release and contains few bug fixes found in 1.2.12 version.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


7 May - JK-1.2.12 released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.12 The release contains a significant number of bug fixes and new features.

We expect it to be ratified as a Stable release when the vote takes place in the next week.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


29 April - JK-1.2.11 released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.11 The release contains a significant number of bug fixes and new features.

This version has not been released.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


30 March - JK-1.2.10 released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.10 The release contains a significant number of bug fixes and new features.

We expect it to be ratified as a Stable release when the vote takes place in the next two weeks.

Please see the ChangeLog for a full list of changes.

Since release 1.2.10 the JkShmFile property has been added for Apache 1.3.x and Apache 2.x web servers on UNIX and LINUX platforms. Load balancer will not work properly if this directive is not present.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


18 March - JK-1.2.9-beta released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.9-beta. The release contains a significant number of bug fixes and new features.

We expect it to be ratified as a Stable release when the vote takes place in the next two weeks.

Please see the ChangeLog for a full list of changes.

Since release 1.2.9 the JkShmFile property has been added for Apache 1.3.x and Apache 2.x web servers on UNIX and LINUX platforms. Load balancer will not work properly if this directive is not present.

If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.



Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/20060101.html0000644000000000000020000001737412555256556020032 0ustar rootbinThe Apache Tomcat Connectors - News - 2006 News and Status
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - News

2006 News and Status

Printer Friendly Version
print-friendly
version
2006 News & Status

10 December - JK-1.2.20 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.20. This is a stable release adding new features and a few bug fixes to version 1.2.19. Furthermore the documentation has been reorganised.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


17 September - JK-1.2.19 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.19. This is a stable release adding some features and a few bug fixes to version 1.2.18. Furthermore the non-functional code trees for isapi and domino have been removed.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


13 July - JK-1.2.18 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.18. This is a stable release adding a few bug fixes to the not released 1.2.17 version.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


JK-1.2.17 not released

Version 1.2.17 of Tomcat Connectors 1.2.17 has not been released due to a bug in the types chosen for socket arguments.

Please see the ChangeLog for a full list of changes.


JK-1.2.16 not released

Version 1.2.16 of Tomcat Connectors 1.2.16 has not been released due to a bug in the jk status worker. This version adds some features and a few bug fixes to the 1.2.15 version. Furthermore some worker attributes have been deprecated.

Please see the ChangeLog for a full list of changes.



Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/20120301.html0000644000000000000020000002234712555256556020025 0ustar rootbinThe Apache Tomcat Connectors - News - 2012 News and Status
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - News

2012 News and Status

Printer Friendly Version
print-friendly
version
2012 News & Status

31 May - JK-1.2.37 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.37. This is a stable release concentrating mainly on bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

14 May - JK-1.2.36 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.36. This is a stable release concentrating mainly on bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

24 March - JK-1.2.35 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.35. This is a stable release concentrating mainly on bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

19 March - JK-1.2.33 stability issue

The Apache Tomcat team wishes to draw your attention to stability issues that have been identified with the recent mod_jk 1.2.33 release. If you have not yet upgraded to mod_jk 1.2.33 we recommend that you wait for the mod_jk 1.2.34 release which is currently in progress. If you have upgraded and are experienced issues we recommend that you downgrade to mod_jk 1.2.32 until mod_jk 1.2.34 is available.

We apologise for any inconvenience.

13 March - JK-1.2.33 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.33. This is a stable release concentrating mainly on some bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/printer/0000755000000000000020000000000012555256556017722 5ustar rootbintomcat-connectors-1.2.41-src/docs/news/printer/20150101.html0000644000000000000020000000542412555256556021506 0ustar rootbinThe Apache Tomcat Connectors - News - 2015 News & Status
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - News

2015 News & Status

2015 News & Status
JK-1.2.41 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.41. This is a maintenance and security release.

This release includes the fix for CVE-2014-8111.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/printer/20090301.html0000644000000000000020000001060612555256556021511 0ustar rootbinThe Apache Tomcat Connectors - News - 2009 News and Status
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - News

2009 News and Status

2009 News & Status

22 March - JK-1.2.28 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.28. This is a stable release concentrating mainly on some bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

The most important new features in this version are:

Better Error Detection for Load Balancer Workers

Local and global error states have been improved. You can fine tune the behaviour with the new "error_escalation_time" attribute (see the timeouts documentation).

Dynamic Address and Port Change Using the Status Worker

The status worker now allows you to change the address and the port of an AJP13 worker on the fly. You can e.g. provision dummy workers with a port equal to "0", which will be automatically put into stopped mode during startup. Later, when you want to actually use these workers, you set their address and port to the final values.

Note that already existing connections will go on using the old address and port. This will be improved in future versions.

New Data in Status Worker Display

The status worker display now also contains the timestamp of the last worker errors.

Improved Proxy Flexibility

You can now overwrite more request metadata before the request gets send to the backend. This is helpful in case there are other reverse proxies in front of your web server. A new documentation page explains this in detail.

Improved IIS Support

IIS support has been improved especially when using mutltiple application pools. Furthermore you can now configure the ISAPI plugin to update the uriworkermap.properies file on a regular interval using the watchdog thread.

JNI Worker Deprecation

Workers of type jni are broken since a long time. Since there is no more use for them, they have been deprecated now, and will be removed in a future release.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/printer/20140201.html0000644000000000000020000000725512555256556021512 0ustar rootbinThe Apache Tomcat Connectors - News - 2014 News and Status
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - News

2014 News and Status

2014 News & Status

15 April - JK-1.2.40 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.40. This is a stable release concentrating mainly on bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

11 March - JK-1.2.39 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.39. This is a stable release containing both bug fixes and few new features like IPV6 support. Note that version 1.2.38 was not released due to some minor issues found in release process.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/printer/20100101.html0000644000000000000020000001134612555256556021501 0ustar rootbinThe Apache Tomcat Connectors - News - 2010 News and Status
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - News

2010 News and Status

2010 News & Status

1 November - JK-1.2.31 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.31. This is a stable release concentrating mainly on some bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


1 March - JK-1.2.30 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.30. This is a stable release concentrating mainly on some bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


1 March - JK-1.2.29 withdrawn

Tomcat Connectors 1.2.29 has been withdrawn because of regression inside Microsoft IIS connector.


26 February - JK-1.2.29 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.29. This is a stable release concentrating mainly on some bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/printer/20041100.html0000644000000000000020000001514212555256556021502 0ustar rootbinThe Apache Tomcat Connectors - News - 2004 News and Status
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - News

2004 News and Status

2004 News & Status

17 December - JK-1.2.8 released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.8.

Please see the ChangeLog for a full list of changes.

If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


17 December - JK-1.2.8-rc-1 released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.8-rc-1 (Relase Canditate 1).

We expect it to be ratified as a Stable release when the vote takes place in the next week.

Please see the ChangeLog for a full list of changes.

If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


13 December - JK-1.2.7-beta-3 released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.7-beta-3. The release contains a fix to few configuration problems detected with JK-1.2.7-beta-2 version.

We expect it to be ratified as a Stable release when the vote takes place in the next week.

Please see the ChangeLog for a full list of changes.

If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


7 December - JK-1.2.7-beta-2 released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.7-beta-2. The release contains a fix to few compilation problems detected with JK-1.2.7-beta version. This release also introduces a new domain concept clustering support. See 32317 for details.

We expect it to be ratified as a Stable release when the vote takes place in the next two weeks.

Please see the ChangeLog for a full list of changes.

If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


30 November - JK-1.2.7-beta released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.7-beta. The release contains a significant number of bug fixes and new features.

We expect it to be ratified as a Stable release when the vote takes place in the next two weeks.

Please see the ChangeLog for a full list of changes.

Since release 1.2.7 the socket_timeout property has been renamed to recycle_timeout. The socket_timeout now sets the real timeout for socket operations.

If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


15 November - JK2 is officially unsupported

JK2 has been put in maintainer mode and no further development will take place. The reason for shutting down JK2 development was the lack of developers interest. Other reason was lack of users interest in adopting JK2, caused by configuration complexity when compared to JK.

The latest official JK2 release is 2.0.4.

JK2 will have it's successor within core Apache2.1/2.2 distribution. We have developed new proxy_ajp that is an addition to the mod_proxy and uses Tomcat's AJP protocol stack. It is developped in httpd-2.1 and integrated in it. We have also developed a new proxy_balancer module for load balancing http and ajp protocol stacks.

JK will be fully supported for all other web servers. The next JK release is planned for the end of November. Lots of code from JK2 has been ported to JK



Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/printer/20050101.html0000644000000000000020000001574712555256556021516 0ustar rootbinThe Apache Tomcat Connectors - News - 2005 News and Status
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - News

2005 News and Status

2005 News & Status

8 November - JK-1.2.15 released

The Apache Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.15. This is Stable release and it contains few bug fixes found in 1.2.14 version.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


13 July - JK-1.2.14 released

The Apache Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.14. This is Stable release and it contains few bug fixes found in 1.2.13 version.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


7 May - JK-1.2.13 released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.13. This is development release and contains few bug fixes found in 1.2.12 version.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


7 May - JK-1.2.12 released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.12 The release contains a significant number of bug fixes and new features.

We expect it to be ratified as a Stable release when the vote takes place in the next week.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


29 April - JK-1.2.11 released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.11 The release contains a significant number of bug fixes and new features.

This version has not been released.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


30 March - JK-1.2.10 released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.10 The release contains a significant number of bug fixes and new features.

We expect it to be ratified as a Stable release when the vote takes place in the next two weeks.

Please see the ChangeLog for a full list of changes.

Since release 1.2.10 the JkShmFile property has been added for Apache 1.3.x and Apache 2.x web servers on UNIX and LINUX platforms. Load balancer will not work properly if this directive is not present.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


18 March - JK-1.2.9-beta released

The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.9-beta. The release contains a significant number of bug fixes and new features.

We expect it to be ratified as a Stable release when the vote takes place in the next two weeks.

Please see the ChangeLog for a full list of changes.

Since release 1.2.9 the JkShmFile property has been added for Apache 1.3.x and Apache 2.x web servers on UNIX and LINUX platforms. Load balancer will not work properly if this directive is not present.

If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.



Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/printer/20060101.html0000644000000000000020000001115012555256556021477 0ustar rootbinThe Apache Tomcat Connectors - News - 2006 News and Status
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - News

2006 News and Status

2006 News & Status

10 December - JK-1.2.20 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.20. This is a stable release adding new features and a few bug fixes to version 1.2.19. Furthermore the documentation has been reorganised.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


17 September - JK-1.2.19 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.19. This is a stable release adding some features and a few bug fixes to version 1.2.18. Furthermore the non-functional code trees for isapi and domino have been removed.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


13 July - JK-1.2.18 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.18. This is a stable release adding a few bug fixes to the not released 1.2.17 version.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


JK-1.2.17 not released

Version 1.2.17 of Tomcat Connectors 1.2.17 has not been released due to a bug in the types chosen for socket arguments.

Please see the ChangeLog for a full list of changes.


JK-1.2.16 not released

Version 1.2.16 of Tomcat Connectors 1.2.16 has not been released due to a bug in the jk status worker. This version adds some features and a few bug fixes to the 1.2.15 version. Furthermore some worker attributes have been deprecated.

Please see the ChangeLog for a full list of changes.



Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/printer/20120301.html0000644000000000000020000001411512555256556021502 0ustar rootbinThe Apache Tomcat Connectors - News - 2012 News and Status
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - News

2012 News and Status

2012 News & Status

31 May - JK-1.2.37 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.37. This is a stable release concentrating mainly on bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

14 May - JK-1.2.36 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.36. This is a stable release concentrating mainly on bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

24 March - JK-1.2.35 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.35. This is a stable release concentrating mainly on bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

19 March - JK-1.2.33 stability issue

The Apache Tomcat team wishes to draw your attention to stability issues that have been identified with the recent mod_jk 1.2.33 release. If you have not yet upgraded to mod_jk 1.2.33 we recommend that you wait for the mod_jk 1.2.34 release which is currently in progress. If you have upgraded and are experienced issues we recommend that you downgrade to mod_jk 1.2.32 until mod_jk 1.2.34 is available.

We apologise for any inconvenience.

13 March - JK-1.2.33 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.33. This is a stable release concentrating mainly on some bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/printer/20110701.html0000644000000000000020000000531112555256556021503 0ustar rootbinThe Apache Tomcat Connectors - News - 2011 News and Status
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - News

2011 News and Status

2011 News & Status

8 July - JK-1.2.32 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.32. This is a stable release concentrating mainly on some bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/printer/20081001.html0000644000000000000020000002127112555256556021506 0ustar rootbinThe Apache Tomcat Connectors - News - 2008 News and Status
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - News

2008 News and Status

2008 News & Status

28 October - JK-1.2.27 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.27. This is a stable release adding lots of new features and some bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

The most important new features in this version are:

Watchdog Thread for Periodic Tasks

The connector has to run some periodic tasks independant of request processing. Examples are probing or closing down idle backend connections, adjusting load numbers and recovering workers from error state.

Before version 1.2.27 these tasks were done inside the request processing loop. When a new request came in and the task was due, the thread handling the request first executed the internal task and then handled the request. If there were no requests coming in, the tasks would not run. If any of the tasks took unexpectedly long, the response time of the request waiting for the finishing of the task went up.

Starting with this release you can configure a separate watchdog thread inside the web server to run all those tasks independantly of request processing. This new feature is avaliable for the connector when used with Apache httpd 2.x or with Microsoft IIS. To keep the behaviour of the new version consistent with previous releases, this feature is turned off by default. You can activate the watchdog thread via JkWatchdogInterval for Apache or watchdog_interval for IIS.

Connection Probing

In previous releases connection probing (checking whether connections still work) could only be done immediately after a new connection was established and directly before sending each request. Since we now have the watchdog thread available, we also added a periodic probing option, which you can activate with the worker attribute ping_mode. This will also be useful as a protection against the infamous firewall idle connection drop.

The older attributes connect_timeout and prepost_timeout still exist and work the same way they did in previous releases. Since there are now three different probing options, we recommend to migrate your configuration to the newer attributes ping_mode, ping_timeout and connection_ping_interval.

Mount Extensions

Usually one defines workers and mounts for the connector. A worker defines a backend we want to talk to and the configuration parameters of the communication, connection pools etc. The mounts define which URIs we want to forward to which worker (so we also call a mount an URI map rule). In version 1.2.27 you can overwrite certain worker parameter per mount.

One easy to understand example is reply timeouts. Until this release you had to specify a reply timeout for the whole worker. But reply times depend a lot on the type of request. So normally you want to define a general reply timeout and for some special URLs you need to relax the reply timeout, because you know those URLs take much longer to process (like e.g. reporting or other compute intensive tasks).

Another possible case is the activation status. You might use a load balancer worker to forward requests to certain webapps in a farm of Tomcat nodes. If you wanted to update some webapp on one node, you previously had to stop forwarding requests for all webapps on this Tomcat node. What was not possible until now, was stopping forwarding requests restricted to the webapp and the node you wanted to update.

Starting with this release, you can add so-called rule extensions to your uriworkermap file to influence worker parameters per mount. This will work for all Apache versions and for IIS. Remember, that the uriworkermap file automatically gets reloaded after changes without web server restart.

Improved IIS support

We improved IIS support im various ways. It is now possible to use multiple IIS 6 application pools with the ISAPI redirector.

Furthermore some improvements were added as compile time features. The most notable one is chunked encoding support, which was a major refactoring and is therefore still considered experimental. You can download binaries with and without chunked encoding support. In future versions, chunked encoding will likely be availabe in all builds.

Another new feature is an elegant way of configuring error page redirects. All new features are documented on the documentation page about configuring IIS.

Enhanced Status Worker

The status worker now can also manage and show statistics for AJP workers that are not part of a load balancer. Other improvements are the new dump action, the integration of the new configuration attributes, showing average request and transfer rates since the last statistics reset and the ability to display only a single member of a load balancer.

Unfortunately we had to change some request parameters used for the update action of the status worker.

Miscellaneous Improvements

Further enhancements are:

  • Configurable session stickyness indicator: cookie name and URL path parameter name can be freely chosen instead of the servlet spec compliant JSESSIONID and ;jsessionid.
  • Automatically determining the size of the shared memory segment needed to accommodate all workers.
  • New connection establishment timeout socket_connect_timeout.
  • New timeout connection_acquire_timeout for acquiring a free connection from the pool.
  • Improved retry handling by adjusting the meaning of the attribute retries for AJP workers and for load balancers and by adding the new retry_interval.
  • Allowing the web server to provide error pages instead of Tomcat.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/printer/20070301.html0000644000000000000020000001232512555256556021507 0ustar rootbinThe Apache Tomcat Connectors - News - 2007 News and Status
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - News

2007 News and Status

2007 News & Status

21 December - JK-1.2.26 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.26. This is a stable release adding few new features and some bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


7 August - JK-1.2.25 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.25. This is a stable release adding new features and a few bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


27 July - JK-1.2.24 released

This release has been withdrawn.


18 May - JK-1.2.23 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.23. This is a stable release adding new features and a few bug fixes to version 1.2.23.

It fixes an Important vulnerability.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


17 April - JK-1.2.22 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.22. This is a stable release adding new features and a few bug fixes to version 1.2.22.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


1 March - JK-1.2.21 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.21. This is a stable release adding new features and a few bug fixes to version 1.2.20.

It fixes a Critical vulnerability introduced in version 1.2.19

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.



Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/20110701.html0000644000000000000020000001355412555256556020030 0ustar rootbinThe Apache Tomcat Connectors - News - 2011 News and Status
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - News

2011 News and Status

Printer Friendly Version
print-friendly
version
2011 News & Status

8 July - JK-1.2.32 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.32. This is a stable release concentrating mainly on some bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/20081001.html0000644000000000000020000002750712555256556020033 0ustar rootbinThe Apache Tomcat Connectors - News - 2008 News and Status
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - News

2008 News and Status

Printer Friendly Version
print-friendly
version
2008 News & Status

28 October - JK-1.2.27 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.27. This is a stable release adding lots of new features and some bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

The most important new features in this version are:

Watchdog Thread for Periodic Tasks

The connector has to run some periodic tasks independant of request processing. Examples are probing or closing down idle backend connections, adjusting load numbers and recovering workers from error state.

Before version 1.2.27 these tasks were done inside the request processing loop. When a new request came in and the task was due, the thread handling the request first executed the internal task and then handled the request. If there were no requests coming in, the tasks would not run. If any of the tasks took unexpectedly long, the response time of the request waiting for the finishing of the task went up.

Starting with this release you can configure a separate watchdog thread inside the web server to run all those tasks independantly of request processing. This new feature is avaliable for the connector when used with Apache httpd 2.x or with Microsoft IIS. To keep the behaviour of the new version consistent with previous releases, this feature is turned off by default. You can activate the watchdog thread via JkWatchdogInterval for Apache or watchdog_interval for IIS.

Connection Probing

In previous releases connection probing (checking whether connections still work) could only be done immediately after a new connection was established and directly before sending each request. Since we now have the watchdog thread available, we also added a periodic probing option, which you can activate with the worker attribute ping_mode. This will also be useful as a protection against the infamous firewall idle connection drop.

The older attributes connect_timeout and prepost_timeout still exist and work the same way they did in previous releases. Since there are now three different probing options, we recommend to migrate your configuration to the newer attributes ping_mode, ping_timeout and connection_ping_interval.

Mount Extensions

Usually one defines workers and mounts for the connector. A worker defines a backend we want to talk to and the configuration parameters of the communication, connection pools etc. The mounts define which URIs we want to forward to which worker (so we also call a mount an URI map rule). In version 1.2.27 you can overwrite certain worker parameter per mount.

One easy to understand example is reply timeouts. Until this release you had to specify a reply timeout for the whole worker. But reply times depend a lot on the type of request. So normally you want to define a general reply timeout and for some special URLs you need to relax the reply timeout, because you know those URLs take much longer to process (like e.g. reporting or other compute intensive tasks).

Another possible case is the activation status. You might use a load balancer worker to forward requests to certain webapps in a farm of Tomcat nodes. If you wanted to update some webapp on one node, you previously had to stop forwarding requests for all webapps on this Tomcat node. What was not possible until now, was stopping forwarding requests restricted to the webapp and the node you wanted to update.

Starting with this release, you can add so-called rule extensions to your uriworkermap file to influence worker parameters per mount. This will work for all Apache versions and for IIS. Remember, that the uriworkermap file automatically gets reloaded after changes without web server restart.

Improved IIS support

We improved IIS support im various ways. It is now possible to use multiple IIS 6 application pools with the ISAPI redirector.

Furthermore some improvements were added as compile time features. The most notable one is chunked encoding support, which was a major refactoring and is therefore still considered experimental. You can download binaries with and without chunked encoding support. In future versions, chunked encoding will likely be availabe in all builds.

Another new feature is an elegant way of configuring error page redirects. All new features are documented on the documentation page about configuring IIS.

Enhanced Status Worker

The status worker now can also manage and show statistics for AJP workers that are not part of a load balancer. Other improvements are the new dump action, the integration of the new configuration attributes, showing average request and transfer rates since the last statistics reset and the ability to display only a single member of a load balancer.

Unfortunately we had to change some request parameters used for the update action of the status worker.

Miscellaneous Improvements

Further enhancements are:

  • Configurable session stickyness indicator: cookie name and URL path parameter name can be freely chosen instead of the servlet spec compliant JSESSIONID and ;jsessionid.
  • Automatically determining the size of the shared memory segment needed to accommodate all workers.
  • New connection establishment timeout socket_connect_timeout.
  • New timeout connection_acquire_timeout for acquiring a free connection from the pool.
  • Improved retry handling by adjusting the meaning of the attribute retries for AJP workers and for load balancers and by adding the new retry_interval.
  • Allowing the web server to provide error pages instead of Tomcat.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/news/20070301.html0000644000000000000020000002055412555256556020027 0ustar rootbinThe Apache Tomcat Connectors - News - 2007 News and Status
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - News

2007 News and Status

Printer Friendly Version
print-friendly
version
2007 News & Status

21 December - JK-1.2.26 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.26. This is a stable release adding few new features and some bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


7 August - JK-1.2.25 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.25. This is a stable release adding new features and a few bug fixes.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


27 July - JK-1.2.24 released

This release has been withdrawn.


18 May - JK-1.2.23 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.23. This is a stable release adding new features and a few bug fixes to version 1.2.23.

It fixes an Important vulnerability.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


17 April - JK-1.2.22 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.22. This is a stable release adding new features and a few bug fixes to version 1.2.22.

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


1 March - JK-1.2.21 released

The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.21. This is a stable release adding new features and a few bug fixes to version 1.2.20.

It fixes a Critical vulnerability introduced in version 1.2.19

Please see the ChangeLog for a full list of changes.

If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.



Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/printer/0000755000000000000020000000000012555256554016744 5ustar rootbintomcat-connectors-1.2.41-src/docs/printer/index.html0000644000000000000020000002161212555256554020743 0ustar rootbinThe Apache Tomcat Connectors / mod_jk - ISAPI redirector - NSAPI redirector - Documentation Index
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors / mod_jk - ISAPI redirector - NSAPI redirector

Documentation Index

Introduction

This is the top-level entry point of the documentation bundle for the Apache Tomcat Connectors

Select one of the links from the navigation menu (to the left) to drill down to the more detailed documentation that is available. Each available manual is described in more detail below.

Headlines
  • JK-1.2.41 released

    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.41 Stable. This release contains a security fix and bug fixes for issues found in previous releases.

    Download the JK 1.2.41 release.

  • Download previous releases from the archives.

Reference Guide

  • workers.properties

    A Tomcat worker is a Tomcat instance that is waiting to execute servlets on behalf of some web server. For example, we can have a web server such as Apache forwarding servlet requests to a Tomcat process (the worker) running behind it.

    This page contains detailed description of all workers.properties directives.

  • uriworkermap.properties

    The forwarding of requests from the web server to tomcat gets configured by defining mapping rules. The so-called uriworkermap file is a mechanism of defining those rules.

  • Status Worker

    The status worker is a builtin management worker. It displays state information and can also be used to dynamically reconfigure JK.

  • Apache

    This page contains detailed description of all directives related to Apache web server.

  • IIS

    This page contains detailed description of all IIS directives.

Common HowTo

  • Quick Start

    This page describes the configuration files used by JK on the Web Server side for the 'impatients'.

  • All about workers

    This page contains an overview about the various aspects of defining and using workers.

  • Timeouts

    This page describes the possible timeout settings you can use.

  • Load Balancing

    This page contains an introduction on load balancing with JK.

  • Reverse Proxy

    This page contains an introduction to reverse proxies, how JK handles this situation and how you can influence the JK proxying behaviour.

Webserver HowTo

These pages contain detailed descriptions of how to build and install JK for the various web servers.

AJP Protocol Reference

  • AJPv13

    This page describes the Apache JServ Protocol version 1.3 (hereafter ajp13).

  • AJPv13 Extension Proposal

    This page describes an extension proposal for ajp13.

Miscellaneous documentation


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/webserver_howto/0000755000000000000020000000000012555256555020506 5ustar rootbintomcat-connectors-1.2.41-src/docs/webserver_howto/apache.html0000644000000000000020000016560712555256555022634 0ustar rootbinThe Apache Tomcat Connectors - Webserver HowTo - Apache HTTP Server HowTo
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Webserver HowTo

Apache HTTP Server HowTo

Printer Friendly Version
print-friendly
version
Introduction

This document explains how to connect Tomcat to the popular open source web server, Apache httpd. You can use mod_jk, the Tomcat redirector module, with any version of Apache starting with 1.3.

It is recommended that you also read the Workers HowTo document to learn how to setup the working entities between your web server and Tomcat Engines. For more detailed configuration information consult the Reference Guide for workers.properties, uriworkermap and Apache.

Waring: If Apache HTTP Server and Tomcat are configured to serve content from the same filing system location then care must be taken to ensure that httpd is not able to serve inappropriate content such as the contents of the WEB-INF directory or JSP source code. This could occur if the httpd DocumentRoot overlaps with a Tomcat Host's appBase or the docBase of any Context. It could also occur when using the httpd Alias directive with a Tomcat Host's appBase or the docBase of any Context.

This document was originally part of Tomcat: A Minimalistic User's Guide written by Gal Shachor, but has been split off for organisational reasons.

Document Conventions and Assumptions

${tomcat_home} is the root directory of tomcat. Your Tomcat installation should have the following subdirectories:

  • ${tomcat_home}\conf - Where you can place various configuration files
  • ${tomcat_home}\webapps - Containing example applications
  • ${tomcat_home}\bin - Where you place web server plugins

In all the examples in this document ${tomcat_home} will be /var/tomcat3. A worker is defined to be a tomcat process that accepts work from the Apache server.

Supported Configuration

The mod_jk module was developed and tested on:

  • Linux, FreeBSD, AIX, HP-UX, MacOS X, Solaris and should work on major Unixes platforms supporting Apache 1.3 and/or 2.x
  • WinNT4.0-i386 SP4/SP5/SP6a (should be able to work with other service packs), Win2K and WinXP and Win98
  • Cygwin (until you have an apache server and autoconf/automake support tools)
  • Netware
  • i5/OS V5R4 (System I) with Apache HTTP Server 2.0.58. Be sure to have the latest Apache PTF installed.
  • Tomcat 3.2 to Tomcat 8.

The redirector uses ajp12 and ajp13 to send requests to the Tomcat containers. There is also an option to use Tomcat in process, more about the in-process mode can be found in the in process howto.

Who support ajp protocols ?

The ajp12 protocol is only available in Tomcat 3.2.x and 3.3.x.

The ajp12 has been deprecated with Tomcat 3.3.x and you should use instead ajp13 which is the only ajp protocol known by Tomcat 4 and above.

Of course Tomcat 3.2.x and 3.3.x also support ajp13 protocol.

Others servlet engines such as jetty have support for ajp13 protocol

How does it work ?

In a nutshell a web server is waiting for client HTTP requests. When these requests arrive the server does whatever is needed to serve the requests by providing the necessary content.

Adding a servlet container may somewhat change this behaviour. Now the web server needs also to perform the following:

  • Load the servlet container adaptor library and initialise it (prior to serving requests).
  • When a request arrives, it needs to check and see if a certain request belongs to a servlet, if so it needs to let the adaptor take the request and handle it.

The adaptor on the other hand needs to know what requests it is going to serve, usually based on some pattern in the request URL, and to where to direct these requests.

Things are even more complex when the user wants to set a configuration that uses virtual hosts, or when they want multiple developers to work on the same web server but on different servlet container JVMs. We will cover these two cases in the advanced sections.

Obtaining mod_jk

mod_jk can be obtained in two formats - binary and source. Depending on the platform you are running your web server on, a binary version of mod_jk may be available.

It is recommended to use the binary version if one is available. If the binary is not available, follow the instructions given in the below "Building mod_jk" sections for building mod_jk from source. The mod_jk source can be downloaded from a mirror here

The binaries for mod_jk are now available for several platforms. The binaries are located in subdirectories by platform.

For some platforms, such as Windows, this is the typical way of obtaining mod_jk since most Windows systems do not have C compilers.

For others, the binary distribution of mod_jk offers simpler installation.

For example JK 1.2.x can be downloaded from a mirror here (look for JK 1.2 Binary Releases). The "JK 1.2 Binary Releases" link contains binary version for a variety of operating systems for both Apache 1.3 and Apache 2.x.

Installation

mod_jk requires two entities:

  • mod_jk.xxx - The Apache HTTP Server module, depending on your operating system, it will be mod_jk.so, mod_jk.nlm or MOD_JK.SRVPGM (see the build section).
  • workers.properties - A file that describes the host(s) and port(s) used by the workers (Tomcat processes). A sample workers.properties can be found under the conf directory in the source download.

Also as with other Apache HTTP Server modules, mod_jk should be first installed on the modules directory of your Apache webserver, ie : /usr/lib/apache and you should update your httpd.conf file.

Disabling old mod_jserv

If you've previously configured Apache to use mod_jserv, remove any ApJServMount directives from your httpd.conf.

If you're including tomcat-apache.conf or tomcat.conf, you'll want to remove them as well - they are specific to mod_jserv.

The mod_jserv configuration directives are not compatible with mod_jk !

Using Tomcat auto-configure

The auto-configure works only for a single Tomcat running on the same machine where Apache HTTP Server is running. The simplest way to configure Apache HTTP Server to use mod_jk is to turn on the Apache HTTP Server auto-configure setting in Tomcat and put the following include directive at the end of your Apache httpd.conf file (make sure you replace $TOMCAT_HOME with the correct path for your Tomcat installation:

    #To be added at the end of your httpd.conf
    Include $TOMCAT_HOME/conf/jk/mod_jk.conf-auto

Note: this file may also be generated as $TOMCAT_HOME/conf/auto/mod_jk.conf

This will tell Apache HTTP Server to use directives in the mod_jk.conf-auto file in the Apache configuration. This file is created by enabling the Apache auto-configuration by creating your workers.properties file at $TOMCAT_HOME/conf/jk/workers.properties and adding the listener to the Engine element in the server.xml file as per the following example. Please note that this example is specific to Tomcat 5.x, unlike other sections of this document which also apply to previous Tomcat branches.

  ...
  <Engine ...>
    ...
    <Listener className="org.apache.jk.config.ApacheConfig" modJk="/path/to/mod_jk.so" />
    ...
  </Engine>
  ...

Then restart Tomcat and mod_jk.conf should be generated. For more information on this topic, please refer to the API documentation at the Tomcat docs website.

Custom mod_jk configuration

You should use custom configuration when :

  • You couldn't use mod_jk.conf-auto since Tomcat engine isn't on the same machine that your Apache web server, ie when you have an Apache in front of a Tomcat Farm.
  • Another case for custom configuration is when your Apache is in front of many different Tomcat engines, each one having it's own configuration, a general case in ISP hosting
  • Also all Apache webmaster will retain custom configuration to be able to tune the settings to their real needs.
Simple configuration example

Here is a simple configuration:

    # Load mod_jk module
    LoadModule    jk_module  modules/mod_jk.so
    # Add the module (activate this lne for Apache 1.3)
    # AddModule     mod_jk.c
    # Where to find workers.properties
    JkWorkersFile /etc/httpd/conf/workers.properties
    # Where to put jk shared memory
    JkShmFile     /var/log/httpd/mod_jk.shm
    # Where to put jk logs
    JkLogFile     /var/log/httpd/mod_jk.log
    # Set the jk log level [debug/error/info]
    JkLogLevel    info
    # Send servlet for context /examples to worker named worker1
    JkMount  /examples/servlet/* worker1
    # Send JSPs  for context /examples to worker named worker1
    JkMount  /examples/*.jsp worker1
mod_jk Directives

We'll discuss here the mod_jk directives and details behind them

Define workers

JkWorkersFile specify the location where mod_jk will find the workers definitions.

  JkWorkersFile     /etc/httpd/conf/workers.properties


Logging

JkLogFile specify the location where mod_jk is going to place its log file.

  JkLogFile     /var/log/httpd/mod_jk.log

Since JK 1.2.3 for Apache 2.x and JK 1.2.16 for Apache 1.3 this can also be used for piped logging:

  JkLogFile     "|/usr/bin/rotatelogs /var/log/httpd/mod_jk.log 86400"

JkLogLevel set the log level between :

  • info log will contains standard mod_jk activity (default).
  • error log will contains also error reports.
  • debug log will contains all information on mod_jk activity
  JkLogLevel    info

info should be your default selection for normal operations.

JkLogStampFormat will configure the date/time format found on mod_jk logfile. See the mod_jk Apache HTTP server reference for details.

  JkLogStampFormat "[%y-%m-%d %H:%M:%S.%Q] "



You can log mod_jk information using the Apache standard module mod_log_config. The module sets several notes in the Apache httpd notes table. Most of them are are only useful in combination with a load balancer worker. See the mod_jk Apache HTTP server reference for details.

  LogFormat     "%h %l %u %t \"%r\" %>s %b %{JK_WORKER_NAME}n %{JK_LB_FIRST_NAME}n \
                 %{JK_LB_FIRST_BUSY}n %{JK_LB_LAST_NAME}n %{JK_LB_LAST_BUSY}n" mod_jk_log
  CustomLog     logs/access_log     mod_jk_log



You can also log a request protocol in the mod_jk log file instead of the access log. This is not recommended and mostly a backward compatibility feature. The directive JkRequestLogFormat will configure the format of this protocol. It gets configured and enabled on a per virtual host basis. See the mod_jk Apache HTTP server reference for details.

  JkRequestLogFormat     "%w %V %T"



Forwarding

The directive JkOptions allow you to set many forwarding options which will enable (+) or disable (-) following option. Without any leading signs, options will be enabled.

The four following options +ForwardURIxxx are mutually exclusive. Exactly one of them is required, a negative sign prefix is not allowed with them. The default value is "ForwardURIProxy" since version 1.2.24. It was "ForwardURICompatUnparsed" in version 1.2.23 and "ForwardURICompat" until version 1.2.22. You can turn the default off by switching on one of the other two options. You should leave this at it's default value, unless you have a very good reason to change it.

All options are inherited from the global server to virtual hosts. Options that support enabling (plus options) and disabling (minus options), are inherited in the following way:

options(vhost) = plus_options(global) - minus_options(global) + plus_options(vhost) - minus_options(vhost)

Using JkOptions ForwardURIProxy, the forwarded URI will be partially reencoded after processing inside Apache httpd and before forwarding to Tomcat. This will be compatible with local URL manipulation by mod_rewrite and with URL encoded session ids.

  JkOptions     +ForwardURIProxy


Using JkOptions ForwardURICompatUnparsed, the forwarded URI will be unparsed. It's spec compliant and secure. It will always forward the original request URI, so rewriting URIs with mod_rewrite and then forwarding the rewritten URI will not work.

  JkOptions     +ForwardURICompatUnparsed


Using JkOptions ForwardURICompat, the forwarded URI will be decoded by Apache httpd. Encoded characters will be decoded and explicit path components like ".." will already be resolved. This is less spec compliant and is not safe if you are using prefix JkMount. This option will allow to rewrite URIs with mod_rewrite before forwarding.

  JkOptions     +ForwardURICompat


Using JkOptions ForwardURIEscaped, the forwarded URI will be the encoded form of the URI used by ForwardURICompat. Explicit path components like ".." will already be resolved. This will not work in combination with URL encoded session IDs, but it will allow to rewrite URIs with mod_rewrite before forwarding.

  JkOptions     +ForwardURIEscaped


JkOptions RejectUnsafeURI will block all URLs, which contain percent signs '%' or backslashes '\' after decoding.

Most web apps do not use such URLs. Using the option RejectUnsafeURI, you can block several well known URL encoding attacks. By default, this option is not set.

You can also realise such a check with mod_rewrite, which is more powerful but also slightly more complicated.

  JkOptions     +RejectUnsafeURI


JkOptions CollapseSlashesAll will collapse multiple adjacent slashes in request URLs before looking for mount or unmount matches.

  JkOptions     +CollapseSlashesAll


JkOptions CollapseSlashesUnmount will collapse multiple adjacent slashes in request URLs only before looking for unmount matches. This is the default value.

  JkOptions     +CollapseSlashesUnmount


JkOptions CollapseSlashesNone will never collapse multiple adjacent slashes in request URLs before looking for mount or unmount matches. Using this value might make you vulnerable for attacks bypassing your unmount rules.

  JkOptions     +CollapseSlashesNone


JkOptions ForwardDirectories is used in conjunction with DirectoryIndex directive of Apache web server. As such mod_dir should be available to Apache, statically or dynamically (DSO)

When DirectoryIndex is configured, Apache will create sub-requests for each of the local-url's specified in the directive, to determine if there is a local file that matches (this is done by stat-ing the file).

If ForwardDirectories is set to false (default) and Apache doesn't find any files that match, Apache will serve the content of the directory (if directive Options specifies Indexes for that directory) or a 403 Forbidden response (if directive Options doesn't specify Indexes for that directory).

If ForwardDirectories is set to true and Apache doesn't find any files that match, the request will be forwarded to Tomcat for resolution. This is used in cases when Apache cannot see the index files on the file system for various reasons: Tomcat is running on a different machine, the JSP file has been precompiled etc.

Note that locally visible files will take precedence over the ones visible only to Tomcat (i.e. if Apache can see the file, that's the one that's going to get served). This is important if there is more then one type of file that Tomcat normally serves - for instance Velocity pages and JSP pages.

  JkOptions     +ForwardDirectories


Setting JkOptions ForwardLocalAddress, you ask mod_jk to send the local address of the Apache web server instead of remote client address. This can be used by Tomcat remote address valve for allowing connections only from registered Apache web servers.

  JkOptions     +ForwardLocalAddress


Setting JkOptions ForwardPhysicalAddress, you ask mod_jk to send the physical peer TCP IP address as the client address. By default mod_jk uses the logical address as provided by the web server. For example the module mod_remoteip sets the logical IP address to the client IP forwarded by proxies in the X-Forwarded-For header.

  JkOptions     +ForwardPhysicalAddress


JkOptions FlushPackets, you ask mod_jk to flush Apache's connection buffer after each AJP packet chunk received from Tomcat. This option can have a strong performance penalty for Apache and Tomcat as writes are performed more often than would normally be required (ie: at the end of each response).

  JkOptions     +FlushPackets


JkOptions FlushHeader, you ask mod_jk to flush Apache's connection buffer after the response headers have been received from Tomcat.

  JkOptions     +FlushHeader


JkOptions DisableReuse, you ask mod_jk to close connections immediately after their use. Normally mod_jk uses persistent connections and pools idle connections to reuse them, when new requests have to be sent to Tomcat.

Using this option will have a strong performance penalty for Apache and Tomcat. Use this only as a last resort in case of unfixable network problems. If a firewall between Apache and Tomcat silently kills idle connections, try to use the worker attribute socket_keepalive in combination with an appropriate TCP keepalive value in your OS.

  JkOptions     +DisableReuse


JkOptions ForwardKeySize, you ask mod_jk, when using ajp13, to forward also the SSL Key Size as required by Servlet API 2.3. This flag shouldn't be set when servlet engine is Tomcat 3.2.x (off by default).

  JkOptions     +ForwardKeySize


JkOptions ForwardSSLCertChain, you ask mod_jk, when using ajp13, to forward SSL certificate chain (off by default). Mod_jk only passes the SSL_CLIENT_CERT to the AJP connector. This is not a problem with self-signed certificates or certificates directly signed by the root CA certificate. However, there's a large number of certificates signed by an intermediate CA certificate, where this is a significant problem: A servlet will not have the possibility to validate the client certificate on its own. The bug would be fixed by passing on the SSL_CLIENT_CERT_CHAIN to Tomcat via the AJP connector.
This directive exists only since version 1.2.22.

  JkOptions     +ForwardSSLCertChain


The directive JkEnvVar allows you to forward environment variables from Apache server to Tomcat engine. You can add a default value as a second parameter to the directive. If the default value is not given explicitly, the variable will only be send, if it is set during runtime.
The variables can be retrieved on the Tomcat side as request attributes via request.getAttribute(attributeName). Note that the variables send via JkEnvVar will not be listed in request.getAttributeNames().

The variables are inherited from the global server to virtual hosts.

  JkEnvVar     SSL_CLIENT_V_START     undefined


Assigning URLs to Tomcat

If you have created a custom or local version of mod_jk.conf-local as noted above, you can change settings such as the workers or URL prefix.

JkMount directive assign specific URLs to Tomcat. In general the structure of a JkMount directive is:

  JkMount [URL prefix] [Worker name]
  # send all requests ending in .jsp to worker1
  JkMount /*.jsp worker1
  # send all requests ending /servlet to worker1
  JkMount /*/servlet/ worker1
  # send all requests jsp requests to files located in /otherworker will go worker2
  JkMount /otherworker/*.jsp worker2

You can use the JkMount directive at the top level or inside <VirtualHost> sections of your httpd.conf file.

Configuring Apache to serve static web application files

If the Tomcat Host appBase (webapps) directory is accessible by the Apache web server, Apache can be configured to serve web application context directory static files instead of passing the request to Tomcat.

Caution: For security reasons it is strongly recommended that JkMount is used to pass all requests to Tomcat by default and JkUnMount is used to explicitly exclude static content to be served by httpd. It should also be noted that content served by httpd will bypass any security constraints defined in the application's web.xml.

Use Apache's Alias directive to map a single web application context directory into Apache's document space for a VirtualHost:

  # Static files in the examples webapp are served by apache
  Alias /examples /vat/tomcat3/webapps/examples
  # All requests go to worker1 by default
  JkMount /* worker1
  # Serve html, jpg and gif using httpd
  JkUnMount /*.html worker1
  JkUnMount /*.jpg  worker1
  JkUnMount /*.gif  worker1

Starting with mod_jk 1.2.6 for Apache 2.x and 1.2.19 for Apache 1.3, it's possible to exclude some URL/URI from jk processing by setting the env var no-jk, for example with the SetEnvIf Directive.

You could use no-jk env var to fix problem with mod_alias or mod_userdir directive when jk and alias/userdir URLs matches.

  # All URL goes to tomcat except the one containing /home
  <VirtualHost *:80>
      ServerName testxxx.mysys
      DocumentRoot /www/testxxx/htdocs

  # Use SetEnvIf to st no-jk when /home/ is encountered
      SetEnvIf Request_URI "/home/*" no-jk

  # Now /home will goes to /home/dataxxx/
      Alias /home /home/dataxxx/

      <Directory "/home/dataxxx">
          Options Indexes MultiViews
          AllowOverride None
          Order allow,deny
          Allow from all
      </Directory>

      JkMount /* myssys-xxx

  </VirtualHost>

Use the mod_jk JkAutoAlias directive to map all web application context directories into Apache's document space.

Attempts to access the WEB-INF or META-INF directories within a web application context or a Web Archive *.war within the Tomcat Host appBase (webapps) directory will fail with an HTTP 403, Access Forbidden

  # Static files in all Tomcat webapp context directories are served by apache
  JkAutoAlias /var/tomcat3/webapps

  # All requests go to worker1 by default
  JkMount /* ajp13
  # Serve html, jpg and gif using httpd
  JkUnMount /*.html ajp13
  JkUnMount /*.jpg  ajp13
  JkUnMount /*.gif  ajp13

If you encoded all your URLs to contain the session id (;jsessionid=...), and you later decide, you want to move part of the content to Apache httpd, you can tell mod_jk to strip off all session ids from URLs for those requests, that do not get forwarded via mod_jk.

You enable this feature by setting JkStripSession to On. It can be enabled individually for virtual servers. The default value is Off.

Building mod_jk on Unix

The mod_jk build use the widely used configure system.

Prepare your mod_jk configure from subversion
In case you get source from subversion, ie without an existing configure script, you should have autoconf for configuration and installation.

To create tomcat-connectors's autoconf script, you will need libtool 1.5.2, automake 1.10 and autoconf 2.59 or newer. The use of more recent versions is encouraged, e.g. for reliable detection of the features of recent version of operating systems.

Those tools will not be required if you are just using a package downloaded from apache.org, they are only required for developers.

To create the configure script just type :

[user@host] ~ $ ./buildconf.sh

Using configure to build mod_jk

Here's how to use configure to prepare mod_jk for building, just type:

./configure [autoconf arguments] [tomcat-connectors arguments]

You could set CFLAGS and LDFLAGS to add some platform specifics:

[user@host] ~ $ LDFLAGS=-lc ./configure -with-apxs=/home2/local/apache/bin/apxs

If you want to build mod_jk for different version of Apache httpd, like 1.3 or 2.x, you need to go through the full build process for each of them. Please note, that httpd 2.0, 2.2 or 2.4 modules are not binary compatible. You have to compile the module using the Apache version you plan to run it in. The mod_jk build directory used is "apache-2.0" for all 2.x builds.

  • use configure and indicate the correct Apache httpd apxs location (--with-apxs)
  • use make
  • copy the resulting mod_jk.so binary from the apache-1.3 or apache-2.0 subdirectory to the Apache httpd modules location.
  • make clean (to remove all previously compiled object files)
  • Start over with the apxs location for your next Apache httpd version.

configure arguments

Apache related parameters
--with-apxs[=FILE] FILE is the location of the apxs tool. Default is finding apxs in PATH. It builds a shared Apache module. It detects automatically the Apache version. (2.x and 1.3)
--with-apache=DIR DIR is the path where apache sources are located. The apache sources should have been configured before configuring mod_jk. DIR is something like: /home/apache/apache_1.3.19 It builds a static Apache module.
--enable-EAPI This parameter is needed when using Apache-1.3 and mod_ssl, otherwise you will get the error message: "this module might crash under EAPI!" when loading mod_jk.so in httpd. Not needed when --with-apxs has been used
--enable-prefork In case you build mod_jk for a multi-threaded Apache httpd 2.x MPM (Multi-Processing Module), some areas of mod_jk code need to be synchronised to make it thread-safe. Because configure can not easily detect, whether your are using a multi-threaded MPM, mod_jk by default is always build thread-safe for Apache httpd 2.x. If you are sure, that your MPM is not multi-threaded, you can use "--enable-prefork" to force the removal of the synchronisation code (thus increasing performance a bit). For instance, the prefork MPM is not multi-threaded. For Apache httpd 1.3 this flag will be set automatically.
--disable-trace When using log level "trace", mod_jk traces a lot of function calls with "enter" and "exit" log messages. Even if the log level is not "trace", comparing the log levels to decide about logging has some performance impact.
If you use "--disable-trace", then the trace log code doesn't get compiled into the module binary and you might save some cycles during execution.
Even with "--disable-trace" logging debug messages with debug log level will still be possible.
--enable-api-compatibility Only use httpd API functions available in all httpd production releases of the chosen major httpd release branch. This improves binary compatibility of module builds with httpd releases older than the release against mod_jk is build (only between minor httpd versions).
--enable-flock In case the operating system supports flock system call use this flag to enable this faster locks that are implemented as system call instead emulated by GNU C library.
However those locks does not work on NFS mounted volumes, so you can use "--enable-flock" during compile time to force the flocks() calls.

Examples of configure use

Apache 1.3 and 2.x build
[user@host] ~ $ ./configure --with-apxs=/usr/sbin/apxs
[user@host] ~ $ make
[user@host] ~ $ cp ./apache-1.3/mod_jk.so /usr/lib/apache
[user@host] ~ $ make clean
[user@host] ~ $ ./configure --with-apxs=/usr/sbin/apxs2
[user@host] ~ $ make
[user@host] ~ $ cp ./apache-2.0/mod_jk.so /usr/lib/apache2

Building mod_jk for Apache on Windows NT/2K/XP

The module was developed using Visual C++ version 6.0, so having this environment is a prerequisite if you want to perform a custom build.

The steps that you need to take are:

  • Change directory to the apache-1.3 or apache-2.0 source directory depending on your version of Apache.
  • If you want to build mod_jk for Apache 1.3, set an APACHE1_HOME environment variable which points to where your Apache 1.3 is installed. A mod_jk module for Apache 2.x build will require APACHE2_HOME environment variable to be set.
  • Copy mod_jk.so to Apache's modules directory.

An example on how to build mod_jk for Apache 1.3:

Set location for Apache 1.3 sources
c:\>set APACHE1_HOME=c:\apache13
Change directory to the mod_jk module for Apache 1.3
c:\>cd c:\home\apache\jk\native\apache-1.3
Build the sources using MSDEV
c:\>MSDEV mod_jk.dsp /MAKE ALL
Copy the dll to your apache modules directory
c:\>cp release\mod_jk.so c:\apache13\modules\

An example on how to build mod_jk for Apache 2.x:

Set location for Apache 2.x sources
c:\>set APACHE2_HOME=c:\apache20
Change directory to the mod_jk module for Apache 2.x
c:\>cd c:\home\apache\jk\native\apache-2.0
Build the sources using MSDEV
c:\>MSDEV mod_jk.dsp /MAKE ALL
Copy the dll to your apache modules directory
c:\>cp release\mod_jk.so c:\apache20\modules\

If msdev is not in your path, enter the full path to msdev.exe. Also, ApacheCore.lib is expected to exist in the ${APACHEX_HOME}\src\CoreD and ${APACHEX_HOME}\src\CoreR directories before linking will succeed. You will need to build enough of the Apache source to create these libraries. This will build both release and debug versions of the redirector plug-in (mod_jk). An alternative will be to open mod_jk.dsp in msdev and build it using the build menu.

Building mod_jk for Apache on System I - i5/OS (OS400)

Since OS400 V4R5, System I (AS/400) has used Apache 2.0 as their primary web server, replacing the old IBM webserver. It's now possible to build mod_jk on System I thanks to the help of the IBM Rochester Labs which has provided information and patches to adapt mod_jk to i5/OS.

You should have at least Apache 2.0.58 (product 5722DG1), a C Compiler and IFS. Apache 2.0.58 is provided with the most recent set of PTFs for the iSeries Apache server, which can be found at http://www.ibm.com/servers/eserver/iseries/software/http/

The all latest Apache 2 for i5/OS V5R3 (or V5R4) is now 2.0.58 (as of 2007/04/17). Be sure to have the latest PTFs loaded if you want to make use of jk 1.2.15 and higher. NB: The latest mod_jk known to work on i5/OS V5R3 was 1.2.19.

New in i5/OS V5R4, UTF is required, also for Apache modules, as such Apache modules do not require translations to/from EBCDIC but works should be done to port mod_jk 1.2.23 (and higher) to V5R4. From the V5R4 Infocenter : As of i5/OS(tm) V5R4, modules must be recompiled with a UTF locale. This creates an environment where locale-dependent C runtime functions assume that string data is encoded in UTF-8. Any hardcoded constants can be encoded in UTF-8 by adding a #pragma convert(1208) statement in the module. Additionally, input data from the client will no longer be converted to EBCDIC but will be passed as-is. Output data sent from the module is not converted either so it must be encoded in ASCII or UTF8 as required. APR and HTTP APIs as of V5R4, expect data in UTF-8. Note that several APIs have additional functions that allow a CCSID to be set to indicate the encoding of the parameters being passed. Conversion functions between UTF-8 and EBCDIC have been added. Be sure to review APIs used by your module to be aware of current changes.

To configure mod_jk on System I use the CL source provided with the mod_jk source.

  • Get the latest mod_jk source and untar it on a Windows or Unix boxes
  • Create a directory in IFS, ie /home/apache
  • Send the whole jk source directory to System I directory via FTP.
  • Then go to the System I command line :

Create mod_jk library
===>CRTLIB MOD_JK TEXT(‘Apache mod'jk tomcat connector module')
Create service program source file
===>CRTSRCPF MOD_JK/QSRVSRC TEXT(‘Service program source file’)
Create the CL build program source file
===>CRTSRCPF FILE(MOD_JK/QCLSRC) TEXT(‘Build program source file’)
Edit the service program source file
===>STRSEU MOD_JK/QSRVSRC MOD_JK

In the edited file, specify that only jk_module should be exported :

Columns . . : 1 71 Edit MOD_JK/QSRVSRC
SEU==> MOD_JK
*************** Beginning of data *************************************
0001.00 STRPGMEXP PGMLVL(*CURRENT)
0002.00 EXPORT SYMBOL("jk_module")
0003.00 ENDPGMEXP
****************** End of data ****************************************

You could start to build all the modules of mod_jk (cases for V5R4 or previous releases):

Copy the CL build program source for i5/OS before V5R4 from IFS
===>CPYFRMSTMF FROMSTMF('/home/apache/jk/native/apache-2.0/bldjk.qclsrc') +
TOMBR('/QSYS.LIB/MOD_JK.LIB/QCLSRC.FILE/BLDJK.MBR') MBROPT(*REPLACE)
Build the CL build program
===>CRTCLPGM PGM(MOD_JK/BLDJK) SRCFILE(MOD_JK/QCLSRC) TEXT('Apache mod_jk build program')
Launch the build
===>CALL MOD_JK/BLDJK
If the build if successfull, copy the new mod_jk module
===>CRTDUPOBJ OBJ(MOD_JK) FROMLIB(MOD_JK) OBJTYPE(*SRVPGM) TOLIB(QHTTPSVR) NEWOBJ(MOD_JK)

Copy the CL build program source for i5/OS V5R4 from IFS
===>CPYFRMSTMF FROMSTMF('/home/apache/jk/native/apache-2.0/bldjk54.qclsrc') +
TOMBR('/QSYS.LIB/MOD_JK.LIB/QCLSRC.FILE/BLDJK54.MBR') MBROPT(*REPLACE)
Build the CL build program for i5/OS V5R4
===>CRTCLPGM PGM(MOD_JK/BLDJK54) SRCFILE(MOD_JK/QCLSRC) TEXT('Apache mod_jk build program') TGTRLS(*CURRENT)
Launch the build for i5/OS V5R4
===>CALL MOD_JK/BLDJK54
If the build if successfull, copy the new mod_jk module
===>CRTDUPOBJ OBJ(MOD_JK) FROMLIB(MOD_JK) OBJTYPE(*SRVPGM) TOLIB(QHTTPSVR) NEWOBJ(MOD_JK)

Next, you should restart your Apache 2.0 instance and enjoy this piece of OpenSource on System I.

ENDTCPSVR SERVER(*HTTP) HTTPSVR(MYSERVER)
STRTCPSVR SERVER(*HTTP) HTTPSVR(MYSERVER)

Building mod_jk for Apache on MacOS/X

Mac OS X (10.2.x) build notes :

Assuming that you are root :

For Apache 1.3:
[user@host] ~ $ ./configure --with-apxs=/usr/sbin/apxs
[user@host] ~ $ cd apache-1.3
[user@host] ~ $ make -f Makefile.apxs
[user@host] ~ $ cp mod_jk.so /etc/libexec/httpd
For Apache 2.x:
[user@host] ~ $ ./configure --with-apxs=/usr/local/apache2/bin/apxs
(you should point to the directory where you installed Apache 2.x)
[user@host] ~ $ cd apache-2.0
[user@host] ~ $ make -f Makefile.apxs install

Getting mod_jk linked statically with Apache

mod_jk allows to install mod_jk in the Apache source tree to get a statically linked mod_jk. Having mod_jk in the httpd executable brings some performance improvements. The configure option --with-apache prepare mod_jk to install it in the Apache source tree. The option --with-apache works both for Apache 1.3 and Apache 2.x. The examples below show how to get mod_jk in the httpd process.

Installation in Apache-2.x

/home/apache20/httpd-2.0.43 is the directory where the httpd-2.0 sources are located.
[user@host] ~ $ ./configure --with-apache=/home/apache20/httpd-2.0.43
[user@host] ~ $ make
Install the mod_jk library and other files in /home/apache20/httpd-2.0.43/modules:
[user@host] ~ $ make install
It is not possible to configure Apache directly because the config.m4 of mod_jk must be added to the configure of httpd-2.x.
[user@host] ~ $ cd /home/apache20/httpd-2.0.43
[user@host] ~ $ sh buildconf
[user@host] ~ $ configure ... --with-mod_jk
[user@host] ~ $ make
[user@host] ~ $ make install

The enable-jk=share and enable-jk=static are not supported. --with-mod_jk only allow static linking of mod_jk.

Installation in Apache-1.3

/home/apache/apache_1.3.27 is the directory where the apache-1.3 sources are located.
[user@host] ~ $ ./configure --with-apache=/home/apache/apache_1.3.27
[user@host] ~ $ make
Install the libjk library, mod_jk.c, includes and other files in /home/apache/apache_1.3.27/src/modules/jk:
[user@host] ~ $ make install
Configure in the Apache sources:
[user@host] ~ $ cd /home/apache/apache_1.3.27
[user@host] ~ $ configure ... --enable-module=dir --disable-shared=dir \
--activate-module=src/modules/jk/libjk.a \
--disable-shared=jk
[user@host] ~ $ make
[user@host] ~ $ make install

The --enable-shared=jk is also working and builds a dso file.

Just change the configure in the Apache sources:
[user@host] ~ $ configure ... --enable-module=dir --enable-shared=dir \
--activate-module=src/modules/jk/libjk.a \
--enable-shared=jk


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/webserver_howto/nes.html0000644000000000000020000005645412555256555022177 0ustar rootbinThe Apache Tomcat Connectors - Webserver HowTo - SunOne -- Netscape/iPlanet HowTo
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Webserver HowTo

SunOne -- Netscape/iPlanet HowTo

Printer Friendly Version
print-friendly
version
Introduction

This document explains how to set up Sun ONE Web Server previously known as Netscape web servers to cooperate with Tomcat.

Normally the Sun ONE Web Servers come with their own Servlet engine, but you can also configure them to send servlet and JSP requests to Tomcat using the NSAPI redirector plugin.

It is recommended that you also read the Workers HowTo document to learn how to setup the working entities between your web server and Tomcat Engines.

Document Conventions and Assumptions

${tomcat_home} is the root directory of tomcat. Your Tomcat installation should have the following subdirectories:

  • ${tomcat_home}\conf - Where you can place various configuration files
  • ${tomcat_home}\webapps - Containing example applications
  • ${tomcat_home}\bin - Where you place web server plugins

In all the examples in this document ${tomcat_home} will be c:\tomcat. A worker is defined to be a tomcat process that accepts work from the Sun ONE Web Server.

Supported Configuration

The NSAPI-Tomcat redirector was developed and tested on:

  • WINNT 2000/XP/2003 (should be able to work with other service packs) and some Unixes
  • Sun ONE Web Server 6.1
  • Tomcat 4.1 to Tomcat 8.

The redirector uses ajp12 and ajp13 to send requests to the Tomcat containers. There is also an option to use Tomcat in process, more about the in-process mode can be found in the in process howto.

Who support ajp protocols ?

The ajp12 protocol is only available in Tomcat 3.2.x and 3.3.x.

The ajp12 has been deprecated with Tomcat 3.3.x and you should use instead ajp13 which is the only ajp protocol known by Tomcat 4 and above.

Of course Tomcat 3.2.x and 3.3.x also support ajp13 protocol.

Others servlet engines such as jetty have support for ajp13 protocol

How does it work ?

  1. The NSAPI-Tomcat redirector is an Netscape service step plugin, Netscape load the redirector plugin and calls its service handler function for request that are assigned to the "servlet" configuration object.
  2. For each in-coming request Netscape will execute the set of NameTrans directives that we added to obj.conf, the assign-name function will check if it's from parameter matches the request URL.
  3. If a match is found, assign-name will assign the servlet object name to the request. This will cause Netscape to send the request to the servlet configuration object.
  4. Netscape will execute our jk_service extension. The extension collects the request parameters and forwards them to the appropriate worker using the ajp13 protocol (the worker="defworker" parameter in jk_service inform it that the worker for this request is named defworker). the workers properties files, workers.properties, will indicate that defworker use ajp13 protocol.
  5. The extension collects the response from the worker and returns it to the browser.

Installation

A pre-built version of the NSAPI redirector, nsapi_redirect.dll, may be available under the win32/i386 directory of tomcat-connectors distribution. For those using Netscape as your browser, try downloading a zip version of the file, if available. You can also build a copy locally from the source present in tomcat-connectors distribution. The Tomcat redirector requires two entities:

  • nsapi_redirect.dll (Windows) -or- nsapi_redirector.so (Unix) - The NSAPI server plugin, either obtain a pre-built DLL/so or build it yourself (see the build section).
  • workers.properties - A file that describes the host(s) and port(s) used by the workers (Tomcat processes). A sample workers.properties can be found under the conf directory.
The installation includes the following parts:
  • Configuring the NSAPI redirector with a default /examples context and checking that you can serve servlets with Netscape.
  • Adding more contexts to the configuration.

Configuring the NSAPI Redirector

In this document we'll assume that nsapi_redirect.dll is placed in c:\jk\lib\nsapi_redirect.dll, the properties file is inc:\jk\conf and you created a log directory c:\jk\logs

  • If the built in servlet support is working disable it.
  • Add the redirector plugin into the Netscape server configuration. Edit your server magnus.conf and add the following lines:
  
  Init fn="load-modules" funcs="jk_init,jk_service" shlib="c:/jk/lib/nsapi_redirect.dll" shlib_flags="(global|now)"
  Init fn="jk_init" worker_file="c:/jk/conf/workers.properties" log_level="debug" log_file="c:/jk/logs/nsapi.log" shm_file="c:/jk/logs/jk_shm"
  • Edit your server obj.conf and add the following lines:

  
  In the default object NameTrans section
  <Object name="default">
      
  NameTrans fn="assign-name" from="/servlets-examples(|/*)" name="jknsapi" 
  NameTrans fn="assign-name" from="/jsp-examples(|/*)" name="jknsapi"
  ....
  </Object>
  
  Create a new configuration object by adding the following lines to the end of the obj.conf file
  
  <Object name="jknsapi">
  ObjectType fn=force-type type=text/plain
  Service fn="jk_service" method="*" worker="worker1"
  </Object>
  • Edit your worker definition file workers.properties. You should at least choose a connection pool size:
  #An entry that lists all the workers defined. For example:
  worker.list=worker1
  
  # Entries that define the host and port associated with these workers.
  worker.worker1.host=localhost
  worker.worker1.port=8009
  worker.worker1.type=ajp13
  worker.worker1.connection_pool_size=50
  • Restart Web Server (stop and start the server)

That's all, now you should start tomcat and ask for http://server:port/servlets-examples/

The file obj.conf seems to be sensitive to leading white space in lines, especially in the Object element. Make sure you have no leading white space (no indentation) on any line of this file.

Adding additional Contexts

The examples context is useful for verifying your installation, but you will also need to add your own contexts. Adding a new context requires two operations:

  • Adding the context to Tomcat (I am not going to talk about this).
  • Assigning the NSAPI redirector to handle this context.

Assigning the NSAPI redirector to handle this context is simple, all you need to do is to edit obj.conf and add a NameTrans line that looks like:

  NameTrans fn="assign-name" from="/<context name>/*" name="jknsapi"

After saving obj.conf restart Netscape and it will serve the new context.

Advanced Context Configuration

Sometimes it is better to have Netscape serve the static pages (html, gif, jpeg etc.) even if these files are part of a context served by Tomcat. For example, consider the html and gif files in the examples context, there is no need to serve them from the Tomcat process, Netscape will suffice.

Making Netscape serve static files that are part of the Tomcat contexts requires the following:

  • Configuring Netscape to know about the Tomcat contexts
  • Make sure that the WEB-INF directory is protected from access.
  • Configuring Netscape to assign the NSAPI redirector only specific requests that requires JSP/Servlet handling.

Adding a Tomcat context to Netscape requires the addition of a new Netscape virtual directory that covers the Tomcat context.

For example, adding a /example Netscape virtual directory that covers the c:\tomcat\webapps\examples directory.

To add a new virtual directory add the following line to your obj.conf:

  NameTrans fn=pfx2dir from=/examples dir="c:/tomcat/webapps/examples"

WEB-INF protection requires some explanation; Each servlet application (context) has a special directory named WEB-INF, this directory contains sensitive configurations data and Java classes and must be kept hidden from web users. WEB-INF can be protected by adding the following line to the PathCheck section in the default configuration object:

  PathCheck fn="deny-existence" path="*/WEB-INF/*"
  
  This line instructs the Netscape server to reject any request with a URL that contain the path /WEB-INF/.

Configuring Netscape to assign the NSAPI redirector only specific requests is somewhat harder, you will need to specify the exact URL-Path pattern(s) that you want Tomcat to handle (usually only JSP files and servlets).

This requires a change to NameTrans portion of obj.conf.

  For the examples context it requires to replace the following line:
  
  NameTrans fn="assign-name" from="/examples/*" name="jknsapi"
  
  with the following two lines:
  
  NameTrans fn="assign-name" from="/examples/jsp/*.jsp" name="jknsapi"
  NameTrans fn="assign-name" from="/examples/servlet/*" name="jknsapi"

As you can see the second configuration is more explicit, it actually instructs Netscape to assign the redirector with only requests to resources under /examples/servlet/ and resources under /examples/ whose name ends with .jsp.

You can be even more explicit and provide lines such as:

  NameTrans fn="assign-name" from="/examples/servletname" name="jknsapi"
  
  Instructs Netscape to assign the redirector request whose URL-Path equals /example/servletname
Advanced Worker Configuration

Sometimes you want to serve different contexts with different Tomcat processes (for example to spread the load among different machines). To achieve such goal you will need to define several workers and assign each context with its own worker.

Defining workers is done in workers.properties, this file includes two types of entries:

  #An entry that lists all the workers defined. For example:
  worker.list=worker1,worker2
  
  # Entries that define the host and port associated with these workers.
  worker.worker1.host=localhost
  worker.worker1.port=8009
  worker.worker1.type=ajp13

  worker.worker2.host=otherhost
  worker.worker2.port=8009
  worker.worker2.type=ajp13

The above examples defined two workers, now we can use these workers to serve two different contexts each with it's own worker. Submitting requests to different workers is accomplished by using multiple Service directives in the servlet configuration Object, each with a different path pattern parameter.

For example, if we want to submit the /examples context to the worker named worker1 and the /webpages context to the worker named worker2 we should use the following configuration:

  <Object name="jknsapi">
  ObjectType fn=force-type type=text/plain
  Service fn="jk_service" worker="worker1" path="/examples/*"
  Service fn="jk_service" worker="worker2" path="/webpages/*"
  Service fn="jk_service" worker="worker1"
  </Object>

More informations on using and configuring workers in the Workers HowTo and in the worker.properties configuration reference.

Building NSAPI DLL redirector for Windows

The redirector was developed using Visual C++ Ver.6.0, so having this environment is a prereq if you want to perform a custom build. You should also have NES developer SDK The steps that you need to take are:

  • Change directory to the nsapi plugins source directory.
  • Edit nsapi.dsp and update the include and library path to reflect your own Netscape server installation (search for a /I compiler option and /libpath linker option)
  • Make the source with MSDEV
Change directory to the nsapi plugins source directory c:\>cd c:\home\apache\jk\nsapi
Build the sources using MSDEV c:\>MSDEV nsapi.dsp /MAKE ALL

If msdev is not in your path, enter the full path to msdev.exe. This will build both release and debug versions of the redirector plugin. An alternative will be to open the nsapi workspace file (nsapi.dsw) in msdev and build it using the build menu.

Building NSAPI so plugin redirector for Unix

The redirector requires either gcc (Linux) or gcc or the Sun cc compiler (Solaris). The steps that you need to take are:

  • Change directory to the nsapi plugins source directory (src/native).
  • configure for Netscape/iPlanet/SunONE webserver.
  • Change directory to the nsapi netscape directory (./netstape).
  • Set environment variables JAVA_HOME resp. SUITSPOT_HOME to the location of your Java installation resp. Netscape server installation. Depending on the web server version, you must add the subdirectory "plugins" to SUITSPOT_HOME. The variable is correct, if the file $SUITSPOT_HOME/include/nsapi.h exists.
  • Edit Makefile.solaris resp. Makefile.linux and update the variables according to your needs. In the Solaris Makefile, you need to switch the commented lines in order to use the Sun compiler cc instead of GNU gcc.
  • Make the source with gmake.
Change directory to the nsapi plugins source directory c:\>cd /usr/local/src/tomcat-connectors-xxx-src/native
configure for Netscape/iPlanet/SunONE webserver c:\>./configure --enable-netscape
Change directory to the nsapi netscape directory c:\>cd netscape
Set JAVA_HOME (ksh example) c:\>export JAVA_HOME=/path/to/my/java
Set SUITSPOT_HOME (ksh example) c:\>export SUITSPOT_HOME=/path/to/my/netscape/server
Edit the Makefile c:\>vi Makefile.solaris
Make the source with gmake c:\>gmake -f Makefile.solaris

After the build, you will have the required nsapi_redirector.so plugin.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/webserver_howto/iis.html0000644000000000000020000010004012555256555022153 0ustar rootbinThe Apache Tomcat Connectors - Webserver HowTo - IIS HowTo
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Webserver HowTo

IIS HowTo

Printer Friendly Version
print-friendly
version
Introduction

This document explains how to set up IIS to cooperate with Tomcat.

Normally IIS can not execute Servlets and Java Server Pages (JSPs), configuring IIS to use the JK ISAPI redirector plugin will let IIS send servlet and JSP requests to Tomcat (and this way, serve them to clients).

It is recommended that you also read the Workers HowTo document to learn how to setup the working entities between your web server and Tomcat Engines. For more detailed configuration information consult the Reference Guide for workers.properties, uriworkermap and IIS.

Document Conventions and Assumptions

${tomcat_home} is the root directory of tomcat. Your Tomcat installation should have the following subdirectories:

  • ${tomcat_home}\conf - Where you can place various configuration files
  • ${tomcat_home}\webapps - Containing example applications
  • ${tomcat_home}\bin - Where you place web server plugins

In all the examples in this document ${tomcat_home} will be c:\tomcat. A worker is defined to be a tomcat process that accepts work from the IIS server.

Supported Configuration

The IIS-Tomcat redirector works for:

  • WinNT4.0-i386 SP4/SP5/SP6a (should be able to work with other service packs), Win98, WinXP, Win2K, and probably also Win2K3, Vista and Windows 7.
  • IIS4.0 and PWS4.0, IIS 5 to IIS 7.
  • Tomcat 3.2 to Tomcat 8.

The redirector uses ajp12 and ajp13 to send requests to the Tomcat containers. There is also an option to use Tomcat in process, more about the in-process mode can be found in the in process howto.

IIS 5 and 6 Notes

There are extra steps you need to take for configuring Tomcat with IIS 5 and 6. Please see the appropriate links from Tomcat Useful Links.

IIS 7 notes

There is a known bug in IIS that may result in incomplete log messages. See bug 45769 for further details.

64 Bit notes

In a 64 Bit environment - at least for IIS 7 - the used IIS Application Pool should have "Enable 32-bit Applications" set to "False". Otherwise the redirector will not be called and returns an http code 404. If you think, the 32bit version of isapi_redirect.dll would do the job instead, you will get an http code 500, because the library is not loadable into a 64 Bit IIS.

Who support ajp protocols ?

The ajp12 protocol is only available in Tomcat 3.2.x and 3.3.x.

The ajp12 has been deprecated with Tomcat 3.3.x and you should use instead ajp13 which is the only ajp protocol known by Tomcat 4 and above.

Of course Tomcat 3.2.x and 3.3.x also support ajp13 protocol.

Others servlet engines such as jetty have support for ajp13 protocol

How does it work ?

  1. The IIS-Tomcat redirector is an IIS plugin (filter + extension), IIS load the redirector plugin and calls its filter function for each in-coming request.
  2. The filter then tests the request URL against a list of URI-paths held inside uriworkermap.properties, If the current request matches one of the entries in the list of URI-paths, the filter transfers the request to the extension.
  3. The extension collects the request parameters and forwards them to the appropriate worker using the defined protocol like ajp13.
  4. The extension collects the response from the worker and returns it to the browser.

Installation

A pre-built version of the ISAPI redirector server plugin, isapi_redirect.dll, is available under the win32/i386 directory of tomcat-connectors distribution. For those using Netscape as your browser, try downloading a zip version of the file, if available. There can be problems using Netscape to download DLL files. You can also build a copy locally from the source present in tomcat-connectors distribution. The Tomcat redirector requires three entities:

  • isapi_redirect.dll - The IIS server plugin, either obtain a pre-built DLL or build it yourself (see the build section).
  • workers.properties - A file that describes the host(s) and port(s) used by the workers (Tomcat processes). A sample workers.properties can be found under the conf directory.
  • uriworkermap.properties - A file that maps URL-Path patterns to workers. A sample uriworkermap.properties can be found under the conf directory as well.

The installation includes the following parts:

  • Configuring the ISAPI redirector with a default /examples context and checking that you can serve servlets with IIS.
  • Adding more contexts to the configuration.

Configuring the ISAPI Redirector

In this document I will assume that isapi_redirect.dll is placed in c:\tomcat\bin\win32\i386\isapi_redirect.dll and that the properties files which you created are in c:\tomcat\conf.

  1. In the registry, create a new registry key named "HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0"
  2. Add a string value with the name extension_uri and a value of /jakarta/isapi_redirect.dll
  3. Add a string value with the name log_file and a value pointing to where you want your log file to be (for example c:\tomcat\logs\isapi.log).
  4. Add a string value with the name log_level and a value for your log level (can be debug, info, error or emerg).
  5. Add a string value with the name worker_file and a value which is the full path to your workers.properties file (for example c:\tomcat\conf\workers.properties)
  6. Add a string value with the name worker_mount_file and a value which is the full path to your uriworkermap.properties file (for example c:\tomcat\conf\uriworkermap.properties)
  7. Using the IIS management console, add a new virtual directory to your IIS/PWS web site. The name of the virtual directory must be jakarta. Its physical path should be the directory where you placed isapi_redirect.dll (in our example it is c:\tomcat\bin\win32\i386). While creating this new virtual directory assign it with execute access.
  8. Using the IIS management console, add isapi_redirect.dll as a filter in your IIS/PWS web site. The name of the filter should reflect its task (I use the name tomcat), its executable must be our c:\tomcat\bin\win32\i386\isapi_redirect.dll. For PWS, you'll need to use regedit and add/edit the "Filter DLLs" key under HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3SVC\Parameters. This key contains a "," separated list of dlls (full paths) - you need to insert the full path to isapi_redirect.dll.
  9. If you're using IIS 6.0 you must also do the following:
    Using the IIS management console, add the Tomcat Isapi Redirector to the Web Service Extensions.
    1. Right-click on Web Service Extensions and choose Add a new Web Service Extension.
    2. Enter tomcat for the Extension Name.
    3. Add the isapi_redirect.dll to the required files.
    4. Check the Set extension status to Allowed.
    5. Click on OK.
  10. Restart IIS (stop + start the IIS service), make sure that the tomcat filter is marked with a green up-pointing arrow. Under Win98 you may need to cd WINDOWS\SYSTEM\inetsrv and type PWS /stop ( the DLL and log files are locked - even if you click the stop button, PWS will still keep the DLLs in memory. ). Type pws to start it again.

That's all, you should now start Tomcat and ask IIS to serve you the /examples context. Try http://localhost/examples/jsp/index.html for example and execute some of the JSP examples.

If this does not work successfully, refer to the Troubleshooting section below for help on correcting the problem.

Adding additional Contexts

The examples context is useful for verifying your installation, but you will also need to add your own contexts. Adding a new context requires two operations:

  1. Adding the context to Tomcat (I am not going to talk about this).
  2. Adding the context to the ISAPI redirector.

Adding a context to the ISAPI redirector is simple, all you need to do is to edit your uriworkermap.properties and to add a line that looks like:

  /context/*=worker_name

Workers and their name are defined in workers.properties, by default workers.properties comes with a single pre-configured worker named "defworker" so you can use it. As an example, if you want to add a context named "shop", the line that you should add to uriworkermap.properties will be:

  /shop/*=defworker
After saving uriworkermap.properties restart IIS and it will serve the new context.

The above should be all you need for IIS to pass through to Tomcat any request for any URI which corresponds to a Tomcat context (webapp).

Advanced Context Configuration

If your webiste is very busy (more than 100 requests/second, or more than 100 simultaneous client connections), it might sometimes be desirable to have IIS serve static content (html, gif, jpeg etc.) directly, even if these files are part of a context served by Tomcat. Allowing IIS to serve such files directly may avoid the small overhead consisting of passing the request to Tomcat via the redirector, and may free up Tomcat somewhat, by using it only to process requests that only Tomcat can handle (e.g. requests to JSP pages and java servlets).

For example, consider the html and gif files in the examples context : you could serve these files directly with IIS; there is no need to serve them from the Tomcat process.

However, you should be very careful when you implement the following configuration style, because by doing so you are in fact providing a "back-door" to IIS, and allowing it to serve files out of a Tomcat context without Tomcat's knowledge, thus bypassing any security restrictions which Tomcat itself and the Tomcat context (webapp) may place on those files.

Making IIS serve static files that are part of the Tomcat contexts requires the following:

  1. Configuring IIS to know about the Tomcat contexts
  2. Configuring the redirector to leave the static files for IIS

Adding a Tomcat context to IIS requires the addition of a new IIS virtual directory that covers the Tomcat context. For example adding a /example IIS virtual directory that covers the c:\tomcat\webapps\examples directory.

Configuring the redirector is somewhat harder, you will need to specify the exact URL-Path pattern(s) which you want Tomcat to handle (usually only JSP files and servlets). This requires a change to the uriworkermap.properties :

  For the examples context it requires to replace the following line
  /examples/*=defworker
  with the following two lines
  /examples/*.jsp=defworker
  /examples/servlet/*=defworker

As you can see the second configuration is more explicit, it actually instruct the redirector to redirect only requests to resources under /examples/servlet/ and resources under /examples/ whose name ends with .jsp.

You can even be more explicit and provide lines such as:

  /example/servletname=defworker

that instructs the redirector to redirect all requests whose URL-path matches the leading string "/example/servletname" to the worker named defworker.

Protecting the content of your Tomcat contexts

Once again, be aware that by allowing IIS to access the content of your Tomcat context directly, you are potentially bypassing Tomcat's protection of that content. You should thus make sure to protect this content at the IIS level if needed, by using the corresponding IIS management console functions.

In particular, each servlet application (context) has a special directory named WEB-INF, which contains sensitive configuration data and Java classes, and which should always be kept hidden from web users. Using the IIS management console it is possible to protect the WEB-INF directory from user access, but considering that this is a general requirement, and considering that it is easy to forget to implement this protection at the IIS level, the redirector plugin does it automatically for you, and it will reject any request which contains WEB-INF in its URL-path.

Advanced Worker Configuration

Sometimes you may want to serve different contexts with different Tomcat processes (for example to spread the load among different machines). To achieve such a goal you will need to define several workers and assign each context to its own worker.

Defining additional workers is done in the workers.properties file. This file includes two types of entries:

  # An entry that lists all the workers defined
  worker.list=worker1, worker2
  # Entries that define the host and port associated with each of these workers
  worker.worker1.host=localhost
  worker.worker1.port=8009
  worker.worker1.type=ajp13
  worker.worker2.host=otherhost
  worker.worker2.port=8009
  worker.worker2.type=ajp13

The above example defined two workers, now we can use these workers to serve two different contexts each with its own worker:

  example uriworkermap.properties fragment
  /examples/*=worker1
  /webpages/*=worker2

As you can see the examples context is served by worker1 while the webpages context is served by worker2.

More information on using and configuring workers in the Workers HowTo and in the worker.properties configuration reference.

Building ISAPI redirector

The redirector was developed using Visual C++ Ver.6.0, so having this environment is a prerequisite if you want to perform a custom build. You should also have the IIS developer SDK. The steps that you need to take are:

  • Change directory to the isapi plugins source directory.
  • Make the source with MSDEV

Change directory to the isapi plugins source directory
c:\>cd c:\home\apache\jk\iis
Build the sources using MSDEV
c:\>MSDEV isapi.dsp /MAKE ALL

If msdev is not in your path, enter the full path to msdev.exe. This will build both release and debug versions of the redirector plugin. An alternative will be to open the isapi workspace file (isapi.dsw) in msdev and build it using the build menu.

Troubleshooting

It is easy to have the ISAPI redirector not work the first time you try to install it.

If this happens to you, here are some steps to follow to try to correct the problem.

These steps aren't guaranteed to cover all possible problems, but they should help find the typical mistakes.

If you make any corrections during these steps, restart the IIS service as described above in the last step of the installation, then retry the step.

To enable error tracking, make sure web site activity is being logged. For PWS 4.0 make sure "Save Web Site Activity Log" is checked in the Advanced Options of the Personal Web Manager.

Note: These steps assume your worker_mount_file setting points to an unmodified copy of the uriworkermap.properties file.
Results may be misleading if worker_mount_file points to a modified uriworkermap.properties or the uriworkermap.properties-auto file.
It is also assumed that the "/examples" context works correctly if you access Tomcat directly.

Win98

Start the IIS service and Tomcat.

Check for the presence of the ISAPI redirector log file you specified in the log_file setting. If not found, verify the following:

  • Check the "Filter DLLs" setting in the "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3SVC\Parameters" key and make sure the path is correct.
  • Check the spelling of the "HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0" key. Case isn't important, but an incorrect letter will prevent the isapi_redirect.dll from finding its registry settings.
  • Check the log_file setting for typos, name and data. Also insure the directory in which the log file will appear already exists.
  • If the above are set correctly, the ISAPI redirector should be able to create the log file.

Invoke the URL http://localhost/examples/jsp/index.html in your browser. Case is important in Tomcat. The characters following "localhost" in the URL must be lower case. If the page fails to appear, stop the IIS service (required to view the IIS log file). Then examine the last line in the IIS log file in found in SYSTEM/LogFiles/W3SVC1 :

If the last line contains:

  GET "/examples/jsp/index.html HTTP/1.1" 404

then the ISAPI redirector is not recognising that it should be handling requests for the "/examples" context. Check the following:

  • Check the extension_uri name for typos.
  • Check the worker_file setting for typos, name and data.
  • Check the worker_mount_file setting typos, name and data.
  • If these are set correctly, the ISAPI redirector should recognise that it should handle requests for the "/examples" context.

If the last line contains something like:

  GET "/jakarta/isapi_redirect.dll HTTP1.1"

then the ISAPI redirector is recognising that it should handle the request, but is not successful at getting Tomcat to service the request.

You should check the HTTP error code following GET "/..." :

  Error 404
  GET "/..." 404
  • Make sure you entered the URL correctly.
  • Make sure the virtual directory created was called "jakarta". It should display in Personal Web Manager as "/jakarta" (without the quotes).
  • Make sure the extension_uri data begins with "/jakarta/" (without the quotes).
  Error 500
  GET "/..." 500
  • Make sure that "isapi_redirect.dll" follows "/jakarta/" in the extension_uri setting.
  • Check the workers.properties file and make sure the port setting for worker.ajp12.port is the same as the port specified in the server.xml for the "Apache AJP12 support".
  Error 200 or 403
  GET "/..." 200
  GET "/..." 403
  • Make sure you have checked Execute Access for the jakarta virtual directory in the Advanced Options of the Personal Web Manager.

If the above settings are correct, the index.html page should appear in your browser. You should also be able to click the Execute links to execute the JSP examples.

WinNT/Win2K/WinXP

Start the World Wide Web Publishing Service and Tomcat.

Check for the presence of the ISAPI redirector log file you specified in the log_file setting. If not found, check the following:

  • Check the "executable" you set for the filter in the IIS Management Console and make sure the path is correct.
  • Check the spelling of the "HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0" key. Case isn't important, but an incorrect letter will prevent the isapi_redirect.dll from finding its registry settings.
  • Check the log_file setting for typos, name and data. Also insure the directory in which the log file will appear already exists.
  • If the above are set correctly, the ISAPI redirector should be able to create the log file.

Check the tomcat filter you added and make sure its status shows a green upward-pointing arrow. If not, check the following:

  • Check the worker_file setting for typos, name and data.
  • Check the worker_mount_file setting typos, name and data.
  • If the above are set correctly, the green upward-pointing arrow should appear, even if the other settings are wrong.

Invoke the URL http://localhost/examples/jsp/index.html in your browser. Case is important in Tomcat. The characters following "localhost" in the URL must be lower case. If the page fails to appear, examine the last line in the IIS server log file in found in SYSTEM32/LogFiles/W3SVC1.

The last line should contain something like: GET "/jakarta/isapi_redirect.dll HTTP1.1", which indicates the ISAPI redirector is recognising that it should handle the request.

You should check the HTTP error code following GET "/..." :

  Error 404
  GET "/..." 404
  • Make sure you entered the URL correctly.
  Error 500
  GET "/..." 500
  • Make sure the virtual directory created was called "jakarta".
  • Make sure that the extension_uri setting is correct.
  • Check the workers.properties file and make sure the port setting for worker.ajp12.port is the same as the port specified in the server.xml for the "Apache AJP12 support".
  Error 200 or 403
  GET "/..." 200
  GET "/..." 403
  • Make sure you have checked Execute Access for the jakarta virtual directory in the Advanced Options of the Personal Web Manager.

If the above settings are correct, the index.html page should appear in your browser. You should also be able to click the Execute links to execute the JSP examples.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/webserver_howto/printer/0000755000000000000020000000000012555256555022171 5ustar rootbintomcat-connectors-1.2.41-src/docs/webserver_howto/printer/apache.html0000644000000000000020000015737312555256555024320 0ustar rootbinThe Apache Tomcat Connectors - Webserver HowTo - Apache HTTP Server HowTo
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Webserver HowTo

Apache HTTP Server HowTo

Introduction

This document explains how to connect Tomcat to the popular open source web server, Apache httpd. You can use mod_jk, the Tomcat redirector module, with any version of Apache starting with 1.3.

It is recommended that you also read the Workers HowTo document to learn how to setup the working entities between your web server and Tomcat Engines. For more detailed configuration information consult the Reference Guide for workers.properties, uriworkermap and Apache.

Waring: If Apache HTTP Server and Tomcat are configured to serve content from the same filing system location then care must be taken to ensure that httpd is not able to serve inappropriate content such as the contents of the WEB-INF directory or JSP source code. This could occur if the httpd DocumentRoot overlaps with a Tomcat Host's appBase or the docBase of any Context. It could also occur when using the httpd Alias directive with a Tomcat Host's appBase or the docBase of any Context.

This document was originally part of Tomcat: A Minimalistic User's Guide written by Gal Shachor, but has been split off for organisational reasons.

Document Conventions and Assumptions

${tomcat_home} is the root directory of tomcat. Your Tomcat installation should have the following subdirectories:

  • ${tomcat_home}\conf - Where you can place various configuration files
  • ${tomcat_home}\webapps - Containing example applications
  • ${tomcat_home}\bin - Where you place web server plugins

In all the examples in this document ${tomcat_home} will be /var/tomcat3. A worker is defined to be a tomcat process that accepts work from the Apache server.

Supported Configuration

The mod_jk module was developed and tested on:

  • Linux, FreeBSD, AIX, HP-UX, MacOS X, Solaris and should work on major Unixes platforms supporting Apache 1.3 and/or 2.x
  • WinNT4.0-i386 SP4/SP5/SP6a (should be able to work with other service packs), Win2K and WinXP and Win98
  • Cygwin (until you have an apache server and autoconf/automake support tools)
  • Netware
  • i5/OS V5R4 (System I) with Apache HTTP Server 2.0.58. Be sure to have the latest Apache PTF installed.
  • Tomcat 3.2 to Tomcat 8.

The redirector uses ajp12 and ajp13 to send requests to the Tomcat containers. There is also an option to use Tomcat in process, more about the in-process mode can be found in the in process howto.

Who support ajp protocols ?

The ajp12 protocol is only available in Tomcat 3.2.x and 3.3.x.

The ajp12 has been deprecated with Tomcat 3.3.x and you should use instead ajp13 which is the only ajp protocol known by Tomcat 4 and above.

Of course Tomcat 3.2.x and 3.3.x also support ajp13 protocol.

Others servlet engines such as jetty have support for ajp13 protocol

How does it work ?

In a nutshell a web server is waiting for client HTTP requests. When these requests arrive the server does whatever is needed to serve the requests by providing the necessary content.

Adding a servlet container may somewhat change this behaviour. Now the web server needs also to perform the following:

  • Load the servlet container adaptor library and initialise it (prior to serving requests).
  • When a request arrives, it needs to check and see if a certain request belongs to a servlet, if so it needs to let the adaptor take the request and handle it.

The adaptor on the other hand needs to know what requests it is going to serve, usually based on some pattern in the request URL, and to where to direct these requests.

Things are even more complex when the user wants to set a configuration that uses virtual hosts, or when they want multiple developers to work on the same web server but on different servlet container JVMs. We will cover these two cases in the advanced sections.

Obtaining mod_jk

mod_jk can be obtained in two formats - binary and source. Depending on the platform you are running your web server on, a binary version of mod_jk may be available.

It is recommended to use the binary version if one is available. If the binary is not available, follow the instructions given in the below "Building mod_jk" sections for building mod_jk from source. The mod_jk source can be downloaded from a mirror here

The binaries for mod_jk are now available for several platforms. The binaries are located in subdirectories by platform.

For some platforms, such as Windows, this is the typical way of obtaining mod_jk since most Windows systems do not have C compilers.

For others, the binary distribution of mod_jk offers simpler installation.

For example JK 1.2.x can be downloaded from a mirror here (look for JK 1.2 Binary Releases). The "JK 1.2 Binary Releases" link contains binary version for a variety of operating systems for both Apache 1.3 and Apache 2.x.

Installation

mod_jk requires two entities:

  • mod_jk.xxx - The Apache HTTP Server module, depending on your operating system, it will be mod_jk.so, mod_jk.nlm or MOD_JK.SRVPGM (see the build section).
  • workers.properties - A file that describes the host(s) and port(s) used by the workers (Tomcat processes). A sample workers.properties can be found under the conf directory in the source download.

Also as with other Apache HTTP Server modules, mod_jk should be first installed on the modules directory of your Apache webserver, ie : /usr/lib/apache and you should update your httpd.conf file.

Disabling old mod_jserv

If you've previously configured Apache to use mod_jserv, remove any ApJServMount directives from your httpd.conf.

If you're including tomcat-apache.conf or tomcat.conf, you'll want to remove them as well - they are specific to mod_jserv.

The mod_jserv configuration directives are not compatible with mod_jk !

Using Tomcat auto-configure

The auto-configure works only for a single Tomcat running on the same machine where Apache HTTP Server is running. The simplest way to configure Apache HTTP Server to use mod_jk is to turn on the Apache HTTP Server auto-configure setting in Tomcat and put the following include directive at the end of your Apache httpd.conf file (make sure you replace $TOMCAT_HOME with the correct path for your Tomcat installation:

    #To be added at the end of your httpd.conf
    Include $TOMCAT_HOME/conf/jk/mod_jk.conf-auto

Note: this file may also be generated as $TOMCAT_HOME/conf/auto/mod_jk.conf

This will tell Apache HTTP Server to use directives in the mod_jk.conf-auto file in the Apache configuration. This file is created by enabling the Apache auto-configuration by creating your workers.properties file at $TOMCAT_HOME/conf/jk/workers.properties and adding the listener to the Engine element in the server.xml file as per the following example. Please note that this example is specific to Tomcat 5.x, unlike other sections of this document which also apply to previous Tomcat branches.

  ...
  <Engine ...>
    ...
    <Listener className="org.apache.jk.config.ApacheConfig" modJk="/path/to/mod_jk.so" />
    ...
  </Engine>
  ...

Then restart Tomcat and mod_jk.conf should be generated. For more information on this topic, please refer to the API documentation at the Tomcat docs website.

Custom mod_jk configuration

You should use custom configuration when :

  • You couldn't use mod_jk.conf-auto since Tomcat engine isn't on the same machine that your Apache web server, ie when you have an Apache in front of a Tomcat Farm.
  • Another case for custom configuration is when your Apache is in front of many different Tomcat engines, each one having it's own configuration, a general case in ISP hosting
  • Also all Apache webmaster will retain custom configuration to be able to tune the settings to their real needs.
Simple configuration example

Here is a simple configuration:

    # Load mod_jk module
    LoadModule    jk_module  modules/mod_jk.so
    # Add the module (activate this lne for Apache 1.3)
    # AddModule     mod_jk.c
    # Where to find workers.properties
    JkWorkersFile /etc/httpd/conf/workers.properties
    # Where to put jk shared memory
    JkShmFile     /var/log/httpd/mod_jk.shm
    # Where to put jk logs
    JkLogFile     /var/log/httpd/mod_jk.log
    # Set the jk log level [debug/error/info]
    JkLogLevel    info
    # Send servlet for context /examples to worker named worker1
    JkMount  /examples/servlet/* worker1
    # Send JSPs  for context /examples to worker named worker1
    JkMount  /examples/*.jsp worker1
mod_jk Directives

We'll discuss here the mod_jk directives and details behind them

Define workers

JkWorkersFile specify the location where mod_jk will find the workers definitions.

  JkWorkersFile     /etc/httpd/conf/workers.properties


Logging

JkLogFile specify the location where mod_jk is going to place its log file.

  JkLogFile     /var/log/httpd/mod_jk.log

Since JK 1.2.3 for Apache 2.x and JK 1.2.16 for Apache 1.3 this can also be used for piped logging:

  JkLogFile     "|/usr/bin/rotatelogs /var/log/httpd/mod_jk.log 86400"

JkLogLevel set the log level between :

  • info log will contains standard mod_jk activity (default).
  • error log will contains also error reports.
  • debug log will contains all information on mod_jk activity
  JkLogLevel    info

info should be your default selection for normal operations.

JkLogStampFormat will configure the date/time format found on mod_jk logfile. See the mod_jk Apache HTTP server reference for details.

  JkLogStampFormat "[%y-%m-%d %H:%M:%S.%Q] "



You can log mod_jk information using the Apache standard module mod_log_config. The module sets several notes in the Apache httpd notes table. Most of them are are only useful in combination with a load balancer worker. See the mod_jk Apache HTTP server reference for details.

  LogFormat     "%h %l %u %t \"%r\" %>s %b %{JK_WORKER_NAME}n %{JK_LB_FIRST_NAME}n \
                 %{JK_LB_FIRST_BUSY}n %{JK_LB_LAST_NAME}n %{JK_LB_LAST_BUSY}n" mod_jk_log
  CustomLog     logs/access_log     mod_jk_log



You can also log a request protocol in the mod_jk log file instead of the access log. This is not recommended and mostly a backward compatibility feature. The directive JkRequestLogFormat will configure the format of this protocol. It gets configured and enabled on a per virtual host basis. See the mod_jk Apache HTTP server reference for details.

  JkRequestLogFormat     "%w %V %T"



Forwarding

The directive JkOptions allow you to set many forwarding options which will enable (+) or disable (-) following option. Without any leading signs, options will be enabled.

The four following options +ForwardURIxxx are mutually exclusive. Exactly one of them is required, a negative sign prefix is not allowed with them. The default value is "ForwardURIProxy" since version 1.2.24. It was "ForwardURICompatUnparsed" in version 1.2.23 and "ForwardURICompat" until version 1.2.22. You can turn the default off by switching on one of the other two options. You should leave this at it's default value, unless you have a very good reason to change it.

All options are inherited from the global server to virtual hosts. Options that support enabling (plus options) and disabling (minus options), are inherited in the following way:

options(vhost) = plus_options(global) - minus_options(global) + plus_options(vhost) - minus_options(vhost)

Using JkOptions ForwardURIProxy, the forwarded URI will be partially reencoded after processing inside Apache httpd and before forwarding to Tomcat. This will be compatible with local URL manipulation by mod_rewrite and with URL encoded session ids.

  JkOptions     +ForwardURIProxy


Using JkOptions ForwardURICompatUnparsed, the forwarded URI will be unparsed. It's spec compliant and secure. It will always forward the original request URI, so rewriting URIs with mod_rewrite and then forwarding the rewritten URI will not work.

  JkOptions     +ForwardURICompatUnparsed


Using JkOptions ForwardURICompat, the forwarded URI will be decoded by Apache httpd. Encoded characters will be decoded and explicit path components like ".." will already be resolved. This is less spec compliant and is not safe if you are using prefix JkMount. This option will allow to rewrite URIs with mod_rewrite before forwarding.

  JkOptions     +ForwardURICompat


Using JkOptions ForwardURIEscaped, the forwarded URI will be the encoded form of the URI used by ForwardURICompat. Explicit path components like ".." will already be resolved. This will not work in combination with URL encoded session IDs, but it will allow to rewrite URIs with mod_rewrite before forwarding.

  JkOptions     +ForwardURIEscaped


JkOptions RejectUnsafeURI will block all URLs, which contain percent signs '%' or backslashes '\' after decoding.

Most web apps do not use such URLs. Using the option RejectUnsafeURI, you can block several well known URL encoding attacks. By default, this option is not set.

You can also realise such a check with mod_rewrite, which is more powerful but also slightly more complicated.

  JkOptions     +RejectUnsafeURI


JkOptions CollapseSlashesAll will collapse multiple adjacent slashes in request URLs before looking for mount or unmount matches.

  JkOptions     +CollapseSlashesAll


JkOptions CollapseSlashesUnmount will collapse multiple adjacent slashes in request URLs only before looking for unmount matches. This is the default value.

  JkOptions     +CollapseSlashesUnmount


JkOptions CollapseSlashesNone will never collapse multiple adjacent slashes in request URLs before looking for mount or unmount matches. Using this value might make you vulnerable for attacks bypassing your unmount rules.

  JkOptions     +CollapseSlashesNone


JkOptions ForwardDirectories is used in conjunction with DirectoryIndex directive of Apache web server. As such mod_dir should be available to Apache, statically or dynamically (DSO)

When DirectoryIndex is configured, Apache will create sub-requests for each of the local-url's specified in the directive, to determine if there is a local file that matches (this is done by stat-ing the file).

If ForwardDirectories is set to false (default) and Apache doesn't find any files that match, Apache will serve the content of the directory (if directive Options specifies Indexes for that directory) or a 403 Forbidden response (if directive Options doesn't specify Indexes for that directory).

If ForwardDirectories is set to true and Apache doesn't find any files that match, the request will be forwarded to Tomcat for resolution. This is used in cases when Apache cannot see the index files on the file system for various reasons: Tomcat is running on a different machine, the JSP file has been precompiled etc.

Note that locally visible files will take precedence over the ones visible only to Tomcat (i.e. if Apache can see the file, that's the one that's going to get served). This is important if there is more then one type of file that Tomcat normally serves - for instance Velocity pages and JSP pages.

  JkOptions     +ForwardDirectories


Setting JkOptions ForwardLocalAddress, you ask mod_jk to send the local address of the Apache web server instead of remote client address. This can be used by Tomcat remote address valve for allowing connections only from registered Apache web servers.

  JkOptions     +ForwardLocalAddress


Setting JkOptions ForwardPhysicalAddress, you ask mod_jk to send the physical peer TCP IP address as the client address. By default mod_jk uses the logical address as provided by the web server. For example the module mod_remoteip sets the logical IP address to the client IP forwarded by proxies in the X-Forwarded-For header.

  JkOptions     +ForwardPhysicalAddress


JkOptions FlushPackets, you ask mod_jk to flush Apache's connection buffer after each AJP packet chunk received from Tomcat. This option can have a strong performance penalty for Apache and Tomcat as writes are performed more often than would normally be required (ie: at the end of each response).

  JkOptions     +FlushPackets


JkOptions FlushHeader, you ask mod_jk to flush Apache's connection buffer after the response headers have been received from Tomcat.

  JkOptions     +FlushHeader


JkOptions DisableReuse, you ask mod_jk to close connections immediately after their use. Normally mod_jk uses persistent connections and pools idle connections to reuse them, when new requests have to be sent to Tomcat.

Using this option will have a strong performance penalty for Apache and Tomcat. Use this only as a last resort in case of unfixable network problems. If a firewall between Apache and Tomcat silently kills idle connections, try to use the worker attribute socket_keepalive in combination with an appropriate TCP keepalive value in your OS.

  JkOptions     +DisableReuse


JkOptions ForwardKeySize, you ask mod_jk, when using ajp13, to forward also the SSL Key Size as required by Servlet API 2.3. This flag shouldn't be set when servlet engine is Tomcat 3.2.x (off by default).

  JkOptions     +ForwardKeySize


JkOptions ForwardSSLCertChain, you ask mod_jk, when using ajp13, to forward SSL certificate chain (off by default). Mod_jk only passes the SSL_CLIENT_CERT to the AJP connector. This is not a problem with self-signed certificates or certificates directly signed by the root CA certificate. However, there's a large number of certificates signed by an intermediate CA certificate, where this is a significant problem: A servlet will not have the possibility to validate the client certificate on its own. The bug would be fixed by passing on the SSL_CLIENT_CERT_CHAIN to Tomcat via the AJP connector.
This directive exists only since version 1.2.22.

  JkOptions     +ForwardSSLCertChain


The directive JkEnvVar allows you to forward environment variables from Apache server to Tomcat engine. You can add a default value as a second parameter to the directive. If the default value is not given explicitly, the variable will only be send, if it is set during runtime.
The variables can be retrieved on the Tomcat side as request attributes via request.getAttribute(attributeName). Note that the variables send via JkEnvVar will not be listed in request.getAttributeNames().

The variables are inherited from the global server to virtual hosts.

  JkEnvVar     SSL_CLIENT_V_START     undefined


Assigning URLs to Tomcat

If you have created a custom or local version of mod_jk.conf-local as noted above, you can change settings such as the workers or URL prefix.

JkMount directive assign specific URLs to Tomcat. In general the structure of a JkMount directive is:

  JkMount [URL prefix] [Worker name]
  # send all requests ending in .jsp to worker1
  JkMount /*.jsp worker1
  # send all requests ending /servlet to worker1
  JkMount /*/servlet/ worker1
  # send all requests jsp requests to files located in /otherworker will go worker2
  JkMount /otherworker/*.jsp worker2

You can use the JkMount directive at the top level or inside <VirtualHost> sections of your httpd.conf file.

Configuring Apache to serve static web application files

If the Tomcat Host appBase (webapps) directory is accessible by the Apache web server, Apache can be configured to serve web application context directory static files instead of passing the request to Tomcat.

Caution: For security reasons it is strongly recommended that JkMount is used to pass all requests to Tomcat by default and JkUnMount is used to explicitly exclude static content to be served by httpd. It should also be noted that content served by httpd will bypass any security constraints defined in the application's web.xml.

Use Apache's Alias directive to map a single web application context directory into Apache's document space for a VirtualHost:

  # Static files in the examples webapp are served by apache
  Alias /examples /vat/tomcat3/webapps/examples
  # All requests go to worker1 by default
  JkMount /* worker1
  # Serve html, jpg and gif using httpd
  JkUnMount /*.html worker1
  JkUnMount /*.jpg  worker1
  JkUnMount /*.gif  worker1

Starting with mod_jk 1.2.6 for Apache 2.x and 1.2.19 for Apache 1.3, it's possible to exclude some URL/URI from jk processing by setting the env var no-jk, for example with the SetEnvIf Directive.

You could use no-jk env var to fix problem with mod_alias or mod_userdir directive when jk and alias/userdir URLs matches.

  # All URL goes to tomcat except the one containing /home
  <VirtualHost *:80>
      ServerName testxxx.mysys
      DocumentRoot /www/testxxx/htdocs

  # Use SetEnvIf to st no-jk when /home/ is encountered
      SetEnvIf Request_URI "/home/*" no-jk

  # Now /home will goes to /home/dataxxx/
      Alias /home /home/dataxxx/

      <Directory "/home/dataxxx">
          Options Indexes MultiViews
          AllowOverride None
          Order allow,deny
          Allow from all
      </Directory>

      JkMount /* myssys-xxx

  </VirtualHost>

Use the mod_jk JkAutoAlias directive to map all web application context directories into Apache's document space.

Attempts to access the WEB-INF or META-INF directories within a web application context or a Web Archive *.war within the Tomcat Host appBase (webapps) directory will fail with an HTTP 403, Access Forbidden

  # Static files in all Tomcat webapp context directories are served by apache
  JkAutoAlias /var/tomcat3/webapps

  # All requests go to worker1 by default
  JkMount /* ajp13
  # Serve html, jpg and gif using httpd
  JkUnMount /*.html ajp13
  JkUnMount /*.jpg  ajp13
  JkUnMount /*.gif  ajp13

If you encoded all your URLs to contain the session id (;jsessionid=...), and you later decide, you want to move part of the content to Apache httpd, you can tell mod_jk to strip off all session ids from URLs for those requests, that do not get forwarded via mod_jk.

You enable this feature by setting JkStripSession to On. It can be enabled individually for virtual servers. The default value is Off.

Building mod_jk on Unix

The mod_jk build use the widely used configure system.

Prepare your mod_jk configure from subversion
In case you get source from subversion, ie without an existing configure script, you should have autoconf for configuration and installation.

To create tomcat-connectors's autoconf script, you will need libtool 1.5.2, automake 1.10 and autoconf 2.59 or newer. The use of more recent versions is encouraged, e.g. for reliable detection of the features of recent version of operating systems.

Those tools will not be required if you are just using a package downloaded from apache.org, they are only required for developers.

To create the configure script just type :

[user@host] ~ $ ./buildconf.sh

Using configure to build mod_jk

Here's how to use configure to prepare mod_jk for building, just type:

./configure [autoconf arguments] [tomcat-connectors arguments]

You could set CFLAGS and LDFLAGS to add some platform specifics:

[user@host] ~ $ LDFLAGS=-lc ./configure -with-apxs=/home2/local/apache/bin/apxs

If you want to build mod_jk for different version of Apache httpd, like 1.3 or 2.x, you need to go through the full build process for each of them. Please note, that httpd 2.0, 2.2 or 2.4 modules are not binary compatible. You have to compile the module using the Apache version you plan to run it in. The mod_jk build directory used is "apache-2.0" for all 2.x builds.

  • use configure and indicate the correct Apache httpd apxs location (--with-apxs)
  • use make
  • copy the resulting mod_jk.so binary from the apache-1.3 or apache-2.0 subdirectory to the Apache httpd modules location.
  • make clean (to remove all previously compiled object files)
  • Start over with the apxs location for your next Apache httpd version.

configure arguments

Apache related parameters
--with-apxs[=FILE] FILE is the location of the apxs tool. Default is finding apxs in PATH. It builds a shared Apache module. It detects automatically the Apache version. (2.x and 1.3)
--with-apache=DIR DIR is the path where apache sources are located. The apache sources should have been configured before configuring mod_jk. DIR is something like: /home/apache/apache_1.3.19 It builds a static Apache module.
--enable-EAPI This parameter is needed when using Apache-1.3 and mod_ssl, otherwise you will get the error message: "this module might crash under EAPI!" when loading mod_jk.so in httpd. Not needed when --with-apxs has been used
--enable-prefork In case you build mod_jk for a multi-threaded Apache httpd 2.x MPM (Multi-Processing Module), some areas of mod_jk code need to be synchronised to make it thread-safe. Because configure can not easily detect, whether your are using a multi-threaded MPM, mod_jk by default is always build thread-safe for Apache httpd 2.x. If you are sure, that your MPM is not multi-threaded, you can use "--enable-prefork" to force the removal of the synchronisation code (thus increasing performance a bit). For instance, the prefork MPM is not multi-threaded. For Apache httpd 1.3 this flag will be set automatically.
--disable-trace When using log level "trace", mod_jk traces a lot of function calls with "enter" and "exit" log messages. Even if the log level is not "trace", comparing the log levels to decide about logging has some performance impact.
If you use "--disable-trace", then the trace log code doesn't get compiled into the module binary and you might save some cycles during execution.
Even with "--disable-trace" logging debug messages with debug log level will still be possible.
--enable-api-compatibility Only use httpd API functions available in all httpd production releases of the chosen major httpd release branch. This improves binary compatibility of module builds with httpd releases older than the release against mod_jk is build (only between minor httpd versions).
--enable-flock In case the operating system supports flock system call use this flag to enable this faster locks that are implemented as system call instead emulated by GNU C library.
However those locks does not work on NFS mounted volumes, so you can use "--enable-flock" during compile time to force the flocks() calls.

Examples of configure use

Apache 1.3 and 2.x build
[user@host] ~ $ ./configure --with-apxs=/usr/sbin/apxs
[user@host] ~ $ make
[user@host] ~ $ cp ./apache-1.3/mod_jk.so /usr/lib/apache
[user@host] ~ $ make clean
[user@host] ~ $ ./configure --with-apxs=/usr/sbin/apxs2
[user@host] ~ $ make
[user@host] ~ $ cp ./apache-2.0/mod_jk.so /usr/lib/apache2

Building mod_jk for Apache on Windows NT/2K/XP

The module was developed using Visual C++ version 6.0, so having this environment is a prerequisite if you want to perform a custom build.

The steps that you need to take are:

  • Change directory to the apache-1.3 or apache-2.0 source directory depending on your version of Apache.
  • If you want to build mod_jk for Apache 1.3, set an APACHE1_HOME environment variable which points to where your Apache 1.3 is installed. A mod_jk module for Apache 2.x build will require APACHE2_HOME environment variable to be set.
  • Copy mod_jk.so to Apache's modules directory.

An example on how to build mod_jk for Apache 1.3:

Set location for Apache 1.3 sources
c:\>set APACHE1_HOME=c:\apache13
Change directory to the mod_jk module for Apache 1.3
c:\>cd c:\home\apache\jk\native\apache-1.3
Build the sources using MSDEV
c:\>MSDEV mod_jk.dsp /MAKE ALL
Copy the dll to your apache modules directory
c:\>cp release\mod_jk.so c:\apache13\modules\

An example on how to build mod_jk for Apache 2.x:

Set location for Apache 2.x sources
c:\>set APACHE2_HOME=c:\apache20
Change directory to the mod_jk module for Apache 2.x
c:\>cd c:\home\apache\jk\native\apache-2.0
Build the sources using MSDEV
c:\>MSDEV mod_jk.dsp /MAKE ALL
Copy the dll to your apache modules directory
c:\>cp release\mod_jk.so c:\apache20\modules\

If msdev is not in your path, enter the full path to msdev.exe. Also, ApacheCore.lib is expected to exist in the ${APACHEX_HOME}\src\CoreD and ${APACHEX_HOME}\src\CoreR directories before linking will succeed. You will need to build enough of the Apache source to create these libraries. This will build both release and debug versions of the redirector plug-in (mod_jk). An alternative will be to open mod_jk.dsp in msdev and build it using the build menu.

Building mod_jk for Apache on System I - i5/OS (OS400)

Since OS400 V4R5, System I (AS/400) has used Apache 2.0 as their primary web server, replacing the old IBM webserver. It's now possible to build mod_jk on System I thanks to the help of the IBM Rochester Labs which has provided information and patches to adapt mod_jk to i5/OS.

You should have at least Apache 2.0.58 (product 5722DG1), a C Compiler and IFS. Apache 2.0.58 is provided with the most recent set of PTFs for the iSeries Apache server, which can be found at http://www.ibm.com/servers/eserver/iseries/software/http/

The all latest Apache 2 for i5/OS V5R3 (or V5R4) is now 2.0.58 (as of 2007/04/17). Be sure to have the latest PTFs loaded if you want to make use of jk 1.2.15 and higher. NB: The latest mod_jk known to work on i5/OS V5R3 was 1.2.19.

New in i5/OS V5R4, UTF is required, also for Apache modules, as such Apache modules do not require translations to/from EBCDIC but works should be done to port mod_jk 1.2.23 (and higher) to V5R4. From the V5R4 Infocenter : As of i5/OS(tm) V5R4, modules must be recompiled with a UTF locale. This creates an environment where locale-dependent C runtime functions assume that string data is encoded in UTF-8. Any hardcoded constants can be encoded in UTF-8 by adding a #pragma convert(1208) statement in the module. Additionally, input data from the client will no longer be converted to EBCDIC but will be passed as-is. Output data sent from the module is not converted either so it must be encoded in ASCII or UTF8 as required. APR and HTTP APIs as of V5R4, expect data in UTF-8. Note that several APIs have additional functions that allow a CCSID to be set to indicate the encoding of the parameters being passed. Conversion functions between UTF-8 and EBCDIC have been added. Be sure to review APIs used by your module to be aware of current changes.

To configure mod_jk on System I use the CL source provided with the mod_jk source.

  • Get the latest mod_jk source and untar it on a Windows or Unix boxes
  • Create a directory in IFS, ie /home/apache
  • Send the whole jk source directory to System I directory via FTP.
  • Then go to the System I command line :

Create mod_jk library
===>CRTLIB MOD_JK TEXT(‘Apache mod'jk tomcat connector module')
Create service program source file
===>CRTSRCPF MOD_JK/QSRVSRC TEXT(‘Service program source file’)
Create the CL build program source file
===>CRTSRCPF FILE(MOD_JK/QCLSRC) TEXT(‘Build program source file’)
Edit the service program source file
===>STRSEU MOD_JK/QSRVSRC MOD_JK

In the edited file, specify that only jk_module should be exported :

Columns . . : 1 71 Edit MOD_JK/QSRVSRC
SEU==> MOD_JK
*************** Beginning of data *************************************
0001.00 STRPGMEXP PGMLVL(*CURRENT)
0002.00 EXPORT SYMBOL("jk_module")
0003.00 ENDPGMEXP
****************** End of data ****************************************

You could start to build all the modules of mod_jk (cases for V5R4 or previous releases):

Copy the CL build program source for i5/OS before V5R4 from IFS
===>CPYFRMSTMF FROMSTMF('/home/apache/jk/native/apache-2.0/bldjk.qclsrc') +
TOMBR('/QSYS.LIB/MOD_JK.LIB/QCLSRC.FILE/BLDJK.MBR') MBROPT(*REPLACE)
Build the CL build program
===>CRTCLPGM PGM(MOD_JK/BLDJK) SRCFILE(MOD_JK/QCLSRC) TEXT('Apache mod_jk build program')
Launch the build
===>CALL MOD_JK/BLDJK
If the build if successfull, copy the new mod_jk module
===>CRTDUPOBJ OBJ(MOD_JK) FROMLIB(MOD_JK) OBJTYPE(*SRVPGM) TOLIB(QHTTPSVR) NEWOBJ(MOD_JK)

Copy the CL build program source for i5/OS V5R4 from IFS
===>CPYFRMSTMF FROMSTMF('/home/apache/jk/native/apache-2.0/bldjk54.qclsrc') +
TOMBR('/QSYS.LIB/MOD_JK.LIB/QCLSRC.FILE/BLDJK54.MBR') MBROPT(*REPLACE)
Build the CL build program for i5/OS V5R4
===>CRTCLPGM PGM(MOD_JK/BLDJK54) SRCFILE(MOD_JK/QCLSRC) TEXT('Apache mod_jk build program') TGTRLS(*CURRENT)
Launch the build for i5/OS V5R4
===>CALL MOD_JK/BLDJK54
If the build if successfull, copy the new mod_jk module
===>CRTDUPOBJ OBJ(MOD_JK) FROMLIB(MOD_JK) OBJTYPE(*SRVPGM) TOLIB(QHTTPSVR) NEWOBJ(MOD_JK)

Next, you should restart your Apache 2.0 instance and enjoy this piece of OpenSource on System I.

ENDTCPSVR SERVER(*HTTP) HTTPSVR(MYSERVER)
STRTCPSVR SERVER(*HTTP) HTTPSVR(MYSERVER)

Building mod_jk for Apache on MacOS/X

Mac OS X (10.2.x) build notes :

Assuming that you are root :

For Apache 1.3:
[user@host] ~ $ ./configure --with-apxs=/usr/sbin/apxs
[user@host] ~ $ cd apache-1.3
[user@host] ~ $ make -f Makefile.apxs
[user@host] ~ $ cp mod_jk.so /etc/libexec/httpd
For Apache 2.x:
[user@host] ~ $ ./configure --with-apxs=/usr/local/apache2/bin/apxs
(you should point to the directory where you installed Apache 2.x)
[user@host] ~ $ cd apache-2.0
[user@host] ~ $ make -f Makefile.apxs install

Getting mod_jk linked statically with Apache

mod_jk allows to install mod_jk in the Apache source tree to get a statically linked mod_jk. Having mod_jk in the httpd executable brings some performance improvements. The configure option --with-apache prepare mod_jk to install it in the Apache source tree. The option --with-apache works both for Apache 1.3 and Apache 2.x. The examples below show how to get mod_jk in the httpd process.

Installation in Apache-2.x

/home/apache20/httpd-2.0.43 is the directory where the httpd-2.0 sources are located.
[user@host] ~ $ ./configure --with-apache=/home/apache20/httpd-2.0.43
[user@host] ~ $ make
Install the mod_jk library and other files in /home/apache20/httpd-2.0.43/modules:
[user@host] ~ $ make install
It is not possible to configure Apache directly because the config.m4 of mod_jk must be added to the configure of httpd-2.x.
[user@host] ~ $ cd /home/apache20/httpd-2.0.43
[user@host] ~ $ sh buildconf
[user@host] ~ $ configure ... --with-mod_jk
[user@host] ~ $ make
[user@host] ~ $ make install

The enable-jk=share and enable-jk=static are not supported. --with-mod_jk only allow static linking of mod_jk.

Installation in Apache-1.3

/home/apache/apache_1.3.27 is the directory where the apache-1.3 sources are located.
[user@host] ~ $ ./configure --with-apache=/home/apache/apache_1.3.27
[user@host] ~ $ make
Install the libjk library, mod_jk.c, includes and other files in /home/apache/apache_1.3.27/src/modules/jk:
[user@host] ~ $ make install
Configure in the Apache sources:
[user@host] ~ $ cd /home/apache/apache_1.3.27
[user@host] ~ $ configure ... --enable-module=dir --disable-shared=dir \
--activate-module=src/modules/jk/libjk.a \
--disable-shared=jk
[user@host] ~ $ make
[user@host] ~ $ make install

The --enable-shared=jk is also working and builds a dso file.

Just change the configure in the Apache sources:
[user@host] ~ $ configure ... --enable-module=dir --enable-shared=dir \
--activate-module=src/modules/jk/libjk.a \
--enable-shared=jk


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/webserver_howto/printer/nes.html0000644000000000000020000005022412555256555023647 0ustar rootbinThe Apache Tomcat Connectors - Webserver HowTo - SunOne -- Netscape/iPlanet HowTo
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Webserver HowTo

SunOne -- Netscape/iPlanet HowTo

Introduction

This document explains how to set up Sun ONE Web Server previously known as Netscape web servers to cooperate with Tomcat.

Normally the Sun ONE Web Servers come with their own Servlet engine, but you can also configure them to send servlet and JSP requests to Tomcat using the NSAPI redirector plugin.

It is recommended that you also read the Workers HowTo document to learn how to setup the working entities between your web server and Tomcat Engines.

Document Conventions and Assumptions

${tomcat_home} is the root directory of tomcat. Your Tomcat installation should have the following subdirectories:

  • ${tomcat_home}\conf - Where you can place various configuration files
  • ${tomcat_home}\webapps - Containing example applications
  • ${tomcat_home}\bin - Where you place web server plugins

In all the examples in this document ${tomcat_home} will be c:\tomcat. A worker is defined to be a tomcat process that accepts work from the Sun ONE Web Server.

Supported Configuration

The NSAPI-Tomcat redirector was developed and tested on:

  • WINNT 2000/XP/2003 (should be able to work with other service packs) and some Unixes
  • Sun ONE Web Server 6.1
  • Tomcat 4.1 to Tomcat 8.

The redirector uses ajp12 and ajp13 to send requests to the Tomcat containers. There is also an option to use Tomcat in process, more about the in-process mode can be found in the in process howto.

Who support ajp protocols ?

The ajp12 protocol is only available in Tomcat 3.2.x and 3.3.x.

The ajp12 has been deprecated with Tomcat 3.3.x and you should use instead ajp13 which is the only ajp protocol known by Tomcat 4 and above.

Of course Tomcat 3.2.x and 3.3.x also support ajp13 protocol.

Others servlet engines such as jetty have support for ajp13 protocol

How does it work ?

  1. The NSAPI-Tomcat redirector is an Netscape service step plugin, Netscape load the redirector plugin and calls its service handler function for request that are assigned to the "servlet" configuration object.
  2. For each in-coming request Netscape will execute the set of NameTrans directives that we added to obj.conf, the assign-name function will check if it's from parameter matches the request URL.
  3. If a match is found, assign-name will assign the servlet object name to the request. This will cause Netscape to send the request to the servlet configuration object.
  4. Netscape will execute our jk_service extension. The extension collects the request parameters and forwards them to the appropriate worker using the ajp13 protocol (the worker="defworker" parameter in jk_service inform it that the worker for this request is named defworker). the workers properties files, workers.properties, will indicate that defworker use ajp13 protocol.
  5. The extension collects the response from the worker and returns it to the browser.

Installation

A pre-built version of the NSAPI redirector, nsapi_redirect.dll, may be available under the win32/i386 directory of tomcat-connectors distribution. For those using Netscape as your browser, try downloading a zip version of the file, if available. You can also build a copy locally from the source present in tomcat-connectors distribution. The Tomcat redirector requires two entities:

  • nsapi_redirect.dll (Windows) -or- nsapi_redirector.so (Unix) - The NSAPI server plugin, either obtain a pre-built DLL/so or build it yourself (see the build section).
  • workers.properties - A file that describes the host(s) and port(s) used by the workers (Tomcat processes). A sample workers.properties can be found under the conf directory.
The installation includes the following parts:
  • Configuring the NSAPI redirector with a default /examples context and checking that you can serve servlets with Netscape.
  • Adding more contexts to the configuration.

Configuring the NSAPI Redirector

In this document we'll assume that nsapi_redirect.dll is placed in c:\jk\lib\nsapi_redirect.dll, the properties file is inc:\jk\conf and you created a log directory c:\jk\logs

  • If the built in servlet support is working disable it.
  • Add the redirector plugin into the Netscape server configuration. Edit your server magnus.conf and add the following lines:
  
  Init fn="load-modules" funcs="jk_init,jk_service" shlib="c:/jk/lib/nsapi_redirect.dll" shlib_flags="(global|now)"
  Init fn="jk_init" worker_file="c:/jk/conf/workers.properties" log_level="debug" log_file="c:/jk/logs/nsapi.log" shm_file="c:/jk/logs/jk_shm"
  • Edit your server obj.conf and add the following lines:

  
  In the default object NameTrans section
  <Object name="default">
      
  NameTrans fn="assign-name" from="/servlets-examples(|/*)" name="jknsapi" 
  NameTrans fn="assign-name" from="/jsp-examples(|/*)" name="jknsapi"
  ....
  </Object>
  
  Create a new configuration object by adding the following lines to the end of the obj.conf file
  
  <Object name="jknsapi">
  ObjectType fn=force-type type=text/plain
  Service fn="jk_service" method="*" worker="worker1"
  </Object>
  • Edit your worker definition file workers.properties. You should at least choose a connection pool size:
  #An entry that lists all the workers defined. For example:
  worker.list=worker1
  
  # Entries that define the host and port associated with these workers.
  worker.worker1.host=localhost
  worker.worker1.port=8009
  worker.worker1.type=ajp13
  worker.worker1.connection_pool_size=50
  • Restart Web Server (stop and start the server)

That's all, now you should start tomcat and ask for http://server:port/servlets-examples/

The file obj.conf seems to be sensitive to leading white space in lines, especially in the Object element. Make sure you have no leading white space (no indentation) on any line of this file.

Adding additional Contexts

The examples context is useful for verifying your installation, but you will also need to add your own contexts. Adding a new context requires two operations:

  • Adding the context to Tomcat (I am not going to talk about this).
  • Assigning the NSAPI redirector to handle this context.

Assigning the NSAPI redirector to handle this context is simple, all you need to do is to edit obj.conf and add a NameTrans line that looks like:

  NameTrans fn="assign-name" from="/<context name>/*" name="jknsapi"

After saving obj.conf restart Netscape and it will serve the new context.

Advanced Context Configuration

Sometimes it is better to have Netscape serve the static pages (html, gif, jpeg etc.) even if these files are part of a context served by Tomcat. For example, consider the html and gif files in the examples context, there is no need to serve them from the Tomcat process, Netscape will suffice.

Making Netscape serve static files that are part of the Tomcat contexts requires the following:

  • Configuring Netscape to know about the Tomcat contexts
  • Make sure that the WEB-INF directory is protected from access.
  • Configuring Netscape to assign the NSAPI redirector only specific requests that requires JSP/Servlet handling.

Adding a Tomcat context to Netscape requires the addition of a new Netscape virtual directory that covers the Tomcat context.

For example, adding a /example Netscape virtual directory that covers the c:\tomcat\webapps\examples directory.

To add a new virtual directory add the following line to your obj.conf:

  NameTrans fn=pfx2dir from=/examples dir="c:/tomcat/webapps/examples"

WEB-INF protection requires some explanation; Each servlet application (context) has a special directory named WEB-INF, this directory contains sensitive configurations data and Java classes and must be kept hidden from web users. WEB-INF can be protected by adding the following line to the PathCheck section in the default configuration object:

  PathCheck fn="deny-existence" path="*/WEB-INF/*"
  
  This line instructs the Netscape server to reject any request with a URL that contain the path /WEB-INF/.

Configuring Netscape to assign the NSAPI redirector only specific requests is somewhat harder, you will need to specify the exact URL-Path pattern(s) that you want Tomcat to handle (usually only JSP files and servlets).

This requires a change to NameTrans portion of obj.conf.

  For the examples context it requires to replace the following line:
  
  NameTrans fn="assign-name" from="/examples/*" name="jknsapi"
  
  with the following two lines:
  
  NameTrans fn="assign-name" from="/examples/jsp/*.jsp" name="jknsapi"
  NameTrans fn="assign-name" from="/examples/servlet/*" name="jknsapi"

As you can see the second configuration is more explicit, it actually instructs Netscape to assign the redirector with only requests to resources under /examples/servlet/ and resources under /examples/ whose name ends with .jsp.

You can be even more explicit and provide lines such as:

  NameTrans fn="assign-name" from="/examples/servletname" name="jknsapi"
  
  Instructs Netscape to assign the redirector request whose URL-Path equals /example/servletname
Advanced Worker Configuration

Sometimes you want to serve different contexts with different Tomcat processes (for example to spread the load among different machines). To achieve such goal you will need to define several workers and assign each context with its own worker.

Defining workers is done in workers.properties, this file includes two types of entries:

  #An entry that lists all the workers defined. For example:
  worker.list=worker1,worker2
  
  # Entries that define the host and port associated with these workers.
  worker.worker1.host=localhost
  worker.worker1.port=8009
  worker.worker1.type=ajp13

  worker.worker2.host=otherhost
  worker.worker2.port=8009
  worker.worker2.type=ajp13

The above examples defined two workers, now we can use these workers to serve two different contexts each with it's own worker. Submitting requests to different workers is accomplished by using multiple Service directives in the servlet configuration Object, each with a different path pattern parameter.

For example, if we want to submit the /examples context to the worker named worker1 and the /webpages context to the worker named worker2 we should use the following configuration:

  <Object name="jknsapi">
  ObjectType fn=force-type type=text/plain
  Service fn="jk_service" worker="worker1" path="/examples/*"
  Service fn="jk_service" worker="worker2" path="/webpages/*"
  Service fn="jk_service" worker="worker1"
  </Object>

More informations on using and configuring workers in the Workers HowTo and in the worker.properties configuration reference.

Building NSAPI DLL redirector for Windows

The redirector was developed using Visual C++ Ver.6.0, so having this environment is a prereq if you want to perform a custom build. You should also have NES developer SDK The steps that you need to take are:

  • Change directory to the nsapi plugins source directory.
  • Edit nsapi.dsp and update the include and library path to reflect your own Netscape server installation (search for a /I compiler option and /libpath linker option)
  • Make the source with MSDEV
Change directory to the nsapi plugins source directory c:\>cd c:\home\apache\jk\nsapi
Build the sources using MSDEV c:\>MSDEV nsapi.dsp /MAKE ALL

If msdev is not in your path, enter the full path to msdev.exe. This will build both release and debug versions of the redirector plugin. An alternative will be to open the nsapi workspace file (nsapi.dsw) in msdev and build it using the build menu.

Building NSAPI so plugin redirector for Unix

The redirector requires either gcc (Linux) or gcc or the Sun cc compiler (Solaris). The steps that you need to take are:

  • Change directory to the nsapi plugins source directory (src/native).
  • configure for Netscape/iPlanet/SunONE webserver.
  • Change directory to the nsapi netscape directory (./netstape).
  • Set environment variables JAVA_HOME resp. SUITSPOT_HOME to the location of your Java installation resp. Netscape server installation. Depending on the web server version, you must add the subdirectory "plugins" to SUITSPOT_HOME. The variable is correct, if the file $SUITSPOT_HOME/include/nsapi.h exists.
  • Edit Makefile.solaris resp. Makefile.linux and update the variables according to your needs. In the Solaris Makefile, you need to switch the commented lines in order to use the Sun compiler cc instead of GNU gcc.
  • Make the source with gmake.
Change directory to the nsapi plugins source directory c:\>cd /usr/local/src/tomcat-connectors-xxx-src/native
configure for Netscape/iPlanet/SunONE webserver c:\>./configure --enable-netscape
Change directory to the nsapi netscape directory c:\>cd netscape
Set JAVA_HOME (ksh example) c:\>export JAVA_HOME=/path/to/my/java
Set SUITSPOT_HOME (ksh example) c:\>export SUITSPOT_HOME=/path/to/my/netscape/server
Edit the Makefile c:\>vi Makefile.solaris
Make the source with gmake c:\>gmake -f Makefile.solaris

After the build, you will have the required nsapi_redirector.so plugin.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/webserver_howto/printer/iis.html0000644000000000000020000007162712555256555023660 0ustar rootbinThe Apache Tomcat Connectors - Webserver HowTo - IIS HowTo
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Webserver HowTo

IIS HowTo

Introduction

This document explains how to set up IIS to cooperate with Tomcat.

Normally IIS can not execute Servlets and Java Server Pages (JSPs), configuring IIS to use the JK ISAPI redirector plugin will let IIS send servlet and JSP requests to Tomcat (and this way, serve them to clients).

It is recommended that you also read the Workers HowTo document to learn how to setup the working entities between your web server and Tomcat Engines. For more detailed configuration information consult the Reference Guide for workers.properties, uriworkermap and IIS.

Document Conventions and Assumptions

${tomcat_home} is the root directory of tomcat. Your Tomcat installation should have the following subdirectories:

  • ${tomcat_home}\conf - Where you can place various configuration files
  • ${tomcat_home}\webapps - Containing example applications
  • ${tomcat_home}\bin - Where you place web server plugins

In all the examples in this document ${tomcat_home} will be c:\tomcat. A worker is defined to be a tomcat process that accepts work from the IIS server.

Supported Configuration

The IIS-Tomcat redirector works for:

  • WinNT4.0-i386 SP4/SP5/SP6a (should be able to work with other service packs), Win98, WinXP, Win2K, and probably also Win2K3, Vista and Windows 7.
  • IIS4.0 and PWS4.0, IIS 5 to IIS 7.
  • Tomcat 3.2 to Tomcat 8.

The redirector uses ajp12 and ajp13 to send requests to the Tomcat containers. There is also an option to use Tomcat in process, more about the in-process mode can be found in the in process howto.

IIS 5 and 6 Notes

There are extra steps you need to take for configuring Tomcat with IIS 5 and 6. Please see the appropriate links from Tomcat Useful Links.

IIS 7 notes

There is a known bug in IIS that may result in incomplete log messages. See bug 45769 for further details.

64 Bit notes

In a 64 Bit environment - at least for IIS 7 - the used IIS Application Pool should have "Enable 32-bit Applications" set to "False". Otherwise the redirector will not be called and returns an http code 404. If you think, the 32bit version of isapi_redirect.dll would do the job instead, you will get an http code 500, because the library is not loadable into a 64 Bit IIS.

Who support ajp protocols ?

The ajp12 protocol is only available in Tomcat 3.2.x and 3.3.x.

The ajp12 has been deprecated with Tomcat 3.3.x and you should use instead ajp13 which is the only ajp protocol known by Tomcat 4 and above.

Of course Tomcat 3.2.x and 3.3.x also support ajp13 protocol.

Others servlet engines such as jetty have support for ajp13 protocol

How does it work ?

  1. The IIS-Tomcat redirector is an IIS plugin (filter + extension), IIS load the redirector plugin and calls its filter function for each in-coming request.
  2. The filter then tests the request URL against a list of URI-paths held inside uriworkermap.properties, If the current request matches one of the entries in the list of URI-paths, the filter transfers the request to the extension.
  3. The extension collects the request parameters and forwards them to the appropriate worker using the defined protocol like ajp13.
  4. The extension collects the response from the worker and returns it to the browser.

Installation

A pre-built version of the ISAPI redirector server plugin, isapi_redirect.dll, is available under the win32/i386 directory of tomcat-connectors distribution. For those using Netscape as your browser, try downloading a zip version of the file, if available. There can be problems using Netscape to download DLL files. You can also build a copy locally from the source present in tomcat-connectors distribution. The Tomcat redirector requires three entities:

  • isapi_redirect.dll - The IIS server plugin, either obtain a pre-built DLL or build it yourself (see the build section).
  • workers.properties - A file that describes the host(s) and port(s) used by the workers (Tomcat processes). A sample workers.properties can be found under the conf directory.
  • uriworkermap.properties - A file that maps URL-Path patterns to workers. A sample uriworkermap.properties can be found under the conf directory as well.

The installation includes the following parts:

  • Configuring the ISAPI redirector with a default /examples context and checking that you can serve servlets with IIS.
  • Adding more contexts to the configuration.

Configuring the ISAPI Redirector

In this document I will assume that isapi_redirect.dll is placed in c:\tomcat\bin\win32\i386\isapi_redirect.dll and that the properties files which you created are in c:\tomcat\conf.

  1. In the registry, create a new registry key named "HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0"
  2. Add a string value with the name extension_uri and a value of /jakarta/isapi_redirect.dll
  3. Add a string value with the name log_file and a value pointing to where you want your log file to be (for example c:\tomcat\logs\isapi.log).
  4. Add a string value with the name log_level and a value for your log level (can be debug, info, error or emerg).
  5. Add a string value with the name worker_file and a value which is the full path to your workers.properties file (for example c:\tomcat\conf\workers.properties)
  6. Add a string value with the name worker_mount_file and a value which is the full path to your uriworkermap.properties file (for example c:\tomcat\conf\uriworkermap.properties)
  7. Using the IIS management console, add a new virtual directory to your IIS/PWS web site. The name of the virtual directory must be jakarta. Its physical path should be the directory where you placed isapi_redirect.dll (in our example it is c:\tomcat\bin\win32\i386). While creating this new virtual directory assign it with execute access.
  8. Using the IIS management console, add isapi_redirect.dll as a filter in your IIS/PWS web site. The name of the filter should reflect its task (I use the name tomcat), its executable must be our c:\tomcat\bin\win32\i386\isapi_redirect.dll. For PWS, you'll need to use regedit and add/edit the "Filter DLLs" key under HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3SVC\Parameters. This key contains a "," separated list of dlls (full paths) - you need to insert the full path to isapi_redirect.dll.
  9. If you're using IIS 6.0 you must also do the following:
    Using the IIS management console, add the Tomcat Isapi Redirector to the Web Service Extensions.
    1. Right-click on Web Service Extensions and choose Add a new Web Service Extension.
    2. Enter tomcat for the Extension Name.
    3. Add the isapi_redirect.dll to the required files.
    4. Check the Set extension status to Allowed.
    5. Click on OK.
  10. Restart IIS (stop + start the IIS service), make sure that the tomcat filter is marked with a green up-pointing arrow. Under Win98 you may need to cd WINDOWS\SYSTEM\inetsrv and type PWS /stop ( the DLL and log files are locked - even if you click the stop button, PWS will still keep the DLLs in memory. ). Type pws to start it again.

That's all, you should now start Tomcat and ask IIS to serve you the /examples context. Try http://localhost/examples/jsp/index.html for example and execute some of the JSP examples.

If this does not work successfully, refer to the Troubleshooting section below for help on correcting the problem.

Adding additional Contexts

The examples context is useful for verifying your installation, but you will also need to add your own contexts. Adding a new context requires two operations:

  1. Adding the context to Tomcat (I am not going to talk about this).
  2. Adding the context to the ISAPI redirector.

Adding a context to the ISAPI redirector is simple, all you need to do is to edit your uriworkermap.properties and to add a line that looks like:

  /context/*=worker_name

Workers and their name are defined in workers.properties, by default workers.properties comes with a single pre-configured worker named "defworker" so you can use it. As an example, if you want to add a context named "shop", the line that you should add to uriworkermap.properties will be:

  /shop/*=defworker
After saving uriworkermap.properties restart IIS and it will serve the new context.

The above should be all you need for IIS to pass through to Tomcat any request for any URI which corresponds to a Tomcat context (webapp).

Advanced Context Configuration

If your webiste is very busy (more than 100 requests/second, or more than 100 simultaneous client connections), it might sometimes be desirable to have IIS serve static content (html, gif, jpeg etc.) directly, even if these files are part of a context served by Tomcat. Allowing IIS to serve such files directly may avoid the small overhead consisting of passing the request to Tomcat via the redirector, and may free up Tomcat somewhat, by using it only to process requests that only Tomcat can handle (e.g. requests to JSP pages and java servlets).

For example, consider the html and gif files in the examples context : you could serve these files directly with IIS; there is no need to serve them from the Tomcat process.

However, you should be very careful when you implement the following configuration style, because by doing so you are in fact providing a "back-door" to IIS, and allowing it to serve files out of a Tomcat context without Tomcat's knowledge, thus bypassing any security restrictions which Tomcat itself and the Tomcat context (webapp) may place on those files.

Making IIS serve static files that are part of the Tomcat contexts requires the following:

  1. Configuring IIS to know about the Tomcat contexts
  2. Configuring the redirector to leave the static files for IIS

Adding a Tomcat context to IIS requires the addition of a new IIS virtual directory that covers the Tomcat context. For example adding a /example IIS virtual directory that covers the c:\tomcat\webapps\examples directory.

Configuring the redirector is somewhat harder, you will need to specify the exact URL-Path pattern(s) which you want Tomcat to handle (usually only JSP files and servlets). This requires a change to the uriworkermap.properties :

  For the examples context it requires to replace the following line
  /examples/*=defworker
  with the following two lines
  /examples/*.jsp=defworker
  /examples/servlet/*=defworker

As you can see the second configuration is more explicit, it actually instruct the redirector to redirect only requests to resources under /examples/servlet/ and resources under /examples/ whose name ends with .jsp.

You can even be more explicit and provide lines such as:

  /example/servletname=defworker

that instructs the redirector to redirect all requests whose URL-path matches the leading string "/example/servletname" to the worker named defworker.

Protecting the content of your Tomcat contexts

Once again, be aware that by allowing IIS to access the content of your Tomcat context directly, you are potentially bypassing Tomcat's protection of that content. You should thus make sure to protect this content at the IIS level if needed, by using the corresponding IIS management console functions.

In particular, each servlet application (context) has a special directory named WEB-INF, which contains sensitive configuration data and Java classes, and which should always be kept hidden from web users. Using the IIS management console it is possible to protect the WEB-INF directory from user access, but considering that this is a general requirement, and considering that it is easy to forget to implement this protection at the IIS level, the redirector plugin does it automatically for you, and it will reject any request which contains WEB-INF in its URL-path.

Advanced Worker Configuration

Sometimes you may want to serve different contexts with different Tomcat processes (for example to spread the load among different machines). To achieve such a goal you will need to define several workers and assign each context to its own worker.

Defining additional workers is done in the workers.properties file. This file includes two types of entries:

  # An entry that lists all the workers defined
  worker.list=worker1, worker2
  # Entries that define the host and port associated with each of these workers
  worker.worker1.host=localhost
  worker.worker1.port=8009
  worker.worker1.type=ajp13
  worker.worker2.host=otherhost
  worker.worker2.port=8009
  worker.worker2.type=ajp13

The above example defined two workers, now we can use these workers to serve two different contexts each with its own worker:

  example uriworkermap.properties fragment
  /examples/*=worker1
  /webpages/*=worker2

As you can see the examples context is served by worker1 while the webpages context is served by worker2.

More information on using and configuring workers in the Workers HowTo and in the worker.properties configuration reference.

Building ISAPI redirector

The redirector was developed using Visual C++ Ver.6.0, so having this environment is a prerequisite if you want to perform a custom build. You should also have the IIS developer SDK. The steps that you need to take are:

  • Change directory to the isapi plugins source directory.
  • Make the source with MSDEV

Change directory to the isapi plugins source directory
c:\>cd c:\home\apache\jk\iis
Build the sources using MSDEV
c:\>MSDEV isapi.dsp /MAKE ALL

If msdev is not in your path, enter the full path to msdev.exe. This will build both release and debug versions of the redirector plugin. An alternative will be to open the isapi workspace file (isapi.dsw) in msdev and build it using the build menu.

Troubleshooting

It is easy to have the ISAPI redirector not work the first time you try to install it.

If this happens to you, here are some steps to follow to try to correct the problem.

These steps aren't guaranteed to cover all possible problems, but they should help find the typical mistakes.

If you make any corrections during these steps, restart the IIS service as described above in the last step of the installation, then retry the step.

To enable error tracking, make sure web site activity is being logged. For PWS 4.0 make sure "Save Web Site Activity Log" is checked in the Advanced Options of the Personal Web Manager.

Note: These steps assume your worker_mount_file setting points to an unmodified copy of the uriworkermap.properties file.
Results may be misleading if worker_mount_file points to a modified uriworkermap.properties or the uriworkermap.properties-auto file.
It is also assumed that the "/examples" context works correctly if you access Tomcat directly.

Win98

Start the IIS service and Tomcat.

Check for the presence of the ISAPI redirector log file you specified in the log_file setting. If not found, verify the following:

  • Check the "Filter DLLs" setting in the "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3SVC\Parameters" key and make sure the path is correct.
  • Check the spelling of the "HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0" key. Case isn't important, but an incorrect letter will prevent the isapi_redirect.dll from finding its registry settings.
  • Check the log_file setting for typos, name and data. Also insure the directory in which the log file will appear already exists.
  • If the above are set correctly, the ISAPI redirector should be able to create the log file.

Invoke the URL http://localhost/examples/jsp/index.html in your browser. Case is important in Tomcat. The characters following "localhost" in the URL must be lower case. If the page fails to appear, stop the IIS service (required to view the IIS log file). Then examine the last line in the IIS log file in found in SYSTEM/LogFiles/W3SVC1 :

If the last line contains:

  GET "/examples/jsp/index.html HTTP/1.1" 404

then the ISAPI redirector is not recognising that it should be handling requests for the "/examples" context. Check the following:

  • Check the extension_uri name for typos.
  • Check the worker_file setting for typos, name and data.
  • Check the worker_mount_file setting typos, name and data.
  • If these are set correctly, the ISAPI redirector should recognise that it should handle requests for the "/examples" context.

If the last line contains something like:

  GET "/jakarta/isapi_redirect.dll HTTP1.1"

then the ISAPI redirector is recognising that it should handle the request, but is not successful at getting Tomcat to service the request.

You should check the HTTP error code following GET "/..." :

  Error 404
  GET "/..." 404
  • Make sure you entered the URL correctly.
  • Make sure the virtual directory created was called "jakarta". It should display in Personal Web Manager as "/jakarta" (without the quotes).
  • Make sure the extension_uri data begins with "/jakarta/" (without the quotes).
  Error 500
  GET "/..." 500
  • Make sure that "isapi_redirect.dll" follows "/jakarta/" in the extension_uri setting.
  • Check the workers.properties file and make sure the port setting for worker.ajp12.port is the same as the port specified in the server.xml for the "Apache AJP12 support".
  Error 200 or 403
  GET "/..." 200
  GET "/..." 403
  • Make sure you have checked Execute Access for the jakarta virtual directory in the Advanced Options of the Personal Web Manager.

If the above settings are correct, the index.html page should appear in your browser. You should also be able to click the Execute links to execute the JSP examples.

WinNT/Win2K/WinXP

Start the World Wide Web Publishing Service and Tomcat.

Check for the presence of the ISAPI redirector log file you specified in the log_file setting. If not found, check the following:

  • Check the "executable" you set for the filter in the IIS Management Console and make sure the path is correct.
  • Check the spelling of the "HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0" key. Case isn't important, but an incorrect letter will prevent the isapi_redirect.dll from finding its registry settings.
  • Check the log_file setting for typos, name and data. Also insure the directory in which the log file will appear already exists.
  • If the above are set correctly, the ISAPI redirector should be able to create the log file.

Check the tomcat filter you added and make sure its status shows a green upward-pointing arrow. If not, check the following:

  • Check the worker_file setting for typos, name and data.
  • Check the worker_mount_file setting typos, name and data.
  • If the above are set correctly, the green upward-pointing arrow should appear, even if the other settings are wrong.

Invoke the URL http://localhost/examples/jsp/index.html in your browser. Case is important in Tomcat. The characters following "localhost" in the URL must be lower case. If the page fails to appear, examine the last line in the IIS server log file in found in SYSTEM32/LogFiles/W3SVC1.

The last line should contain something like: GET "/jakarta/isapi_redirect.dll HTTP1.1", which indicates the ISAPI redirector is recognising that it should handle the request.

You should check the HTTP error code following GET "/..." :

  Error 404
  GET "/..." 404
  • Make sure you entered the URL correctly.
  Error 500
  GET "/..." 500
  • Make sure the virtual directory created was called "jakarta".
  • Make sure that the extension_uri setting is correct.
  • Check the workers.properties file and make sure the port setting for worker.ajp12.port is the same as the port specified in the server.xml for the "Apache AJP12 support".
  Error 200 or 403
  GET "/..." 200
  GET "/..." 403
  • Make sure you have checked Execute Access for the jakarta virtual directory in the Advanced Options of the Personal Web Manager.

If the above settings are correct, the index.html page should appear in your browser. You should also be able to click the Execute links to execute the JSP examples.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/miscellaneous/0000755000000000000020000000000012555256556020126 5ustar rootbintomcat-connectors-1.2.41-src/docs/miscellaneous/doccontrib.html0000644000000000000020000005143612555256556023153 0ustar rootbinThe Apache Tomcat Connectors - Miscellaneous Documentation - How to Contribute to the Documentation
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Miscellaneous Documentation

How to Contribute to the Documentation

Printer Friendly Version
print-friendly
version
Introduction

This document describes how you can easily contribute to the documentation. I'm going to try to make it easy for everyone to help out with the documentation of Tomcat, more specifically the documentation for the connectors. This is written from a windows user perspective as I believe they will most benefit from it. For people using Unix it should be easy for them to apply these steps. Just substitute Unix syntax where needed.

The documentation is produced using xml with xsl style sheets. This effectivly seperates the content of the documents from the style, so all that contributers need to worry about the content. It is much easier to use than html.

It's all really quite simple. Here is what you will need:

  • A recent version of Ant
  • The source code for the connectors from subversion
  • Any ascii text editor

Getting Started Step by Step

After you get these tools they are simple to set up.

STEP 1. Get Ant

Install Ant. The only advice I have is to choose a simple installation path. Now set an environment variable for ANT_HOME, and then add the location of the Ant/bin directory to your PATH variable. Consult your Operating system documentation for information on how to do this. When you are finished verify that you can run ant from the command line.

Ant is used to build the documentation, among other things, and it must be able to see a file called build.xml. This file is located in the xdocs directory. In the build.xml file there is a target named all that will be used to build the docs.

STEP 2. Get the sources

Get the sources for tomcat-connectors from the subversion repository. If you'll be editing from a windows platform you will need a windows subversion client. There are several available. I like turtoiseSVN. Unix users should install the subversion client of their choice, if they don't already have one.

You are ready to download the sources now. Change directory to the location where you want your repository to be. For simplicity we will call this your SVN_HOME. Mine is located in C:\build.

Run the following command to checkout the sources for the first time. You should only need to do this once.


C:\build\>svn checkout http://svn.apache.org/repos/asf/tomcat/jk/trunk/ tomcat-connectors

You should now be watching all the downloads come in. Now that you have the sources on your machine the hard part is over. From now on, to update your sources all you have to do is cd into any directory in your repository and run the svn update command.

To update your xdocs directory simply cd into the xdocs directory and:
C:\build\tomcat-connectors\>cd xdocs
C:\build\tomcat-connectors\xdocs\>svn update

STEP 3. Test your build environment

Open a command prompt window and cd to the directory where you downloaded the source. Now cd into the xdocs directory so that Ant can see the build.xml file. Then from a command prompt, run the following:


C:\build\tomcat-connectors>cd xdocs
C:\build\tomcat-connectors\xdocs>ant all

.

You should see the ant compiler messages scrolling by rapidly and then stop with the following:

[style] Transforming into C:\build\tomcat-connectors\build\docs\news\printer>
[style] Processing C:\build\tomcat-connectors\xdocs\news\20041100.xml to
C:\build\tomcat-connectors\build\docs\news/20041100.html
[style] Loading stylesheet C:\build\tomcat-connectors\xdocs\style.xsl
[style] Processing C:\build\tomcat-connectors\xdocs\news\20050101.xml to
C:\build\tomcat-connectors\build\docs\news/20050101.html
[style] Processing C:\build\tomcat-connectors\xdocs\news\20060101.xml to
C:\build\tomcat-connectors\build\docs\news/20060101.html
[style] Transforming into C:\build\tomcat-connectors\build\docs>
[style] Processing C:\build\tomcat-connectors\xdocs\index.xml to
C:\build\tomcat-connectors\build\docs\index.html
[style] Loading stylesheet C:\build\tomcat-connectors\xdocs\style.xsl

BUILD SUCCESSFUL
Total time: 10 seconds
C:\build\tomcat-connectors>

All the xml files present in the xdocs directory structure were transformed to html and copied to the SVN_HOME\tomcat-connectors\build\docs directory. Open one of the html files in your browser and see how it looks.

STEP 4. The editing process.

I find it easier to use two windows while doing my updates. One I call my build window. I keep this one in the SVN_HOME\tomcat-connectors\xdocs directory and I only run two commands in this window:


First I run
ant clean
Then I run
ant all

My second window I call my edit window and I keep that one in the SVN_HOME\tomcat-connectors\xdocs directory where I'm doing my edits, diffs and svn updates.

Before you start editing you should always update your local repository to prevent conflicts.

You only need to update the xdocs directory
C:\build\tomcat-connectors>cd xdocs
C:\build\tomcat-connectors\xdocs>
C:\build\tomcat-connectors\xdocs>svn update

Now that your repository is up to date you can begin editing. Find something in the documentation to edit. When you find something remember the name of the file. In your edit window find and edit the xml source file with the same name. After you are done return to the build window, and in the SVN_HOME\tomcat-connectors\xdocs directory run:


C:\build\tomcat-connectors\xdocs> ant clean

This will delete all the previous html files and make the area ready for updated material. Now to make fresh documents that incorporate your changes run:


C:\build\tomcat-connectors\xdocs>ant all

Use your browser to view the edits you just made, they will be in the SVN_HOME\tomcat-connectors\build\docs sub-tree. If it looks good and is ready to go, all that is left to do is to create a patch and submit it.

STEP 5. Creating a patch and submitting it.

From your edit window cd into the directory that contains the xml file you are working on, and run the svn update command. For example, to produce a diff of the index.xml file and call it patch.txt, you would cd into the directory containing the index.xml file and:

C:\build\tomcat-connectors\xdocs\>svn diff index.xml > patch.txt.

Now that you have your patch you are ready to send it in.

Patches to the documentation are handled just like a bug report. You should submit your patches to http://issues.apache.org/bugzilla/ and include a good one line subject. If this is your first time to use the bug database then you should read http://issues.apach e.org/bugzilla/bugwritinghelp.html. You will need to create a user account. At the web site paste your patch into the web form and don't forget to describe what it is your patch is for. Sooner or later a someone with commit privileges will review your suggestion.

Subversion Basics

After you have checked out the sources the first time it is much easier to use subversion. You can cd into any directory of the repository and run svn update to get the latest sources for that directory. For editing purposes you should always update your repository before you start editing to reduce conflicts.

You will need to run svn diff to generate patches for submission. Again cd into the directory containing the file you are editing and run svn diff name_of_the_file_you_edited > patch.txt to generate a patch for submission.

Pay attention to the terminal window during the update.

Lines begining with a A indicate files that have been added.

Lines begining with a D indicate files that have been deleted.

Lines begining with a U mean the local copy was patched to update it to the current version in the master repository.

Lines begining with a G mean your local copy is different from the master copy, and the changes were successfully merged into your copy.

Lines begining with a C mean there was a conflict in merging the changes and you need to review the file and merge the changes manually. Search for >>>> and merge the changes.

Lines begining with a ? indicate files that reside on your local system which are not part of the repository. You will normally see this when you are creating new files for submission.

Updating Web site

Only Committers are able to update the web site (http://tomcat.apache.org/connectors-doc/). To do it:

  • Connect to people.apache.org.
  • umask 002
  • Copy the changed files to /www/tomcat.apache.org/connectors-doc/.
  • or use ant from a checkout tomcat/jk/trunk/xdocs repository:
    ant -Dbuild.dir=/www/tomcat.apache.org -Ddist.name=connectors-doc
  • The changes need around 4 hours to be synced to tomcat.apache.org.

Guides and Resources

A little help to get you started if you need it


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/miscellaneous/changelog.html0000644000000000000020000055175512555256556022765 0ustar rootbinThe Apache Tomcat Connectors - Miscellaneous Documentation - Changelog
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Miscellaneous Documentation

Changelog

Printer Friendly Version
print-friendly
version
Preface

This is the Changelog for Apache Tomcat Connectors. This changelog does not contain all updates and fixes to the Tomcat connectors (yet). It should contain fixes made only after November 10th 2004, when the new documentation project for JK was started.

Changes between 1.2.40 and 1.2.41

Native
fix AJP, LB: Reduce lock contention during maintenance function. This was observable when using a big number of AJP13 and LB workers, especially in combination with the Apache httpd prefork MPM. (rjung)
fix 57060: Allow building from outside of source tree. Patch contributed by Petr Sumbera. (rjung)
fix 56703: Status: Fix inflated counter for current number of backend connections especially when a connection timeout occurred on the backend. (rjung)
fix 56661: Fix Servlet API getLocalAddr(). Works for Tomcat 6.0.42, 7.0.55 and 8.0.11 and Apache and ISAPI plugins. (rjung)
update Status: Log old and new values when changing worker attributes. (rjung)
fix 56667: Status: Fix log message when changing activation state of all members. (rjung)
fix 56565: Fix IPV6 address resolve on non-dual network stacks. (mturk)
fix 50511: Reduce log level for "OPTIONS *" requests from warning to debug. (rjung)
fix Apache: Copy log notes instead of using references to prevent access to memory from closed pool. (rjung)
add Add option to control handling of multiple adjacent slashes in mount and unmount. New default is collapsing the slashes only in unmount. Configuration is done via new JkOption for Apache ("CollapseSlashesAll", "CollapseSlashesNone" or "CollapseSlashesUnmount") and via property "collapse_slashes" for IIS (values "all", "none", "unmount"). This is the fix for CVE-2014-8111. (rjung)
add Add more checks for shared memory allocation. (rjung)
add 56869: Status: Add maximum number of open backend connections to status worker. Patch contributed by Martin Knoblauch. (rjung)
add 56770: AJP: Add worker name to all log messages. Patch contributed by Martin Knoblauch. (rjung)
fix 50186: Docs: Clarify relation between "connection_pool_timeout" and "keepAliveTimeout" or "connectionTimeout" in the Tomcat AJP connector configuration. (rjung)
fix 52334: LB: Calculate worker recovery time based on last recovery attempt time instead of original error time after the first recovery attempt. (rjung)
fix 54596 part 1: IIS: Fix missing last character when parsing relative file names with no ".." directory components from configuration. (rjung)
fix 54596 part 2: IIS: Fix using relative file names in config with ".." path segments that go up the directory hierarchy higher than the starting point of the relative file name. (rjung)
fix Status: Add logging if status worker output was dropped due to insufficient buffer size. (rjung)
fix Reduce log buffer from 8KB to 1KB. Add logging in case of failed logging and add trailing "..." to lines which were likely truncated. (rjung)
update Replace fixed allocation of 32 entries for fail_on_status by dynamic allocation. (rjung)
add Enforce implementation restriction on maximal length "60" of worker attributes "name", "host", "route", "domain", "redirect", "session_cookie", "session_path" and "set_session_cookie". Checks were added to configuration file processing and configuration updates via the status worker. (rjung)
add 52483: Apache: Add debug logging for result of JkOptions configuration processing. (rjung)
fix 54177: Status: Use numeric time stamps instead of textual ones to avoid non-well-formed XML output. Textual timestamps are formatted according to locale settings and reencoding them to UTF-8 would be cumbersome. (rjung)
fix 56618: Status: Use percent decoding when reading query string parameters. For example this fixes editing IPv6 addresses via the status worker if the client encodes ":" as "%3A". Patch contributed by Christopher Schultz. (rjung)
fix 56452: Fix crash in debug logging for IPv6 adresses. Patch contributed by Christopher Schultz. (rjung)
fix 34526: Apache: Improve compatibility with mod_deflate request body inflation. An automatic detection of mod_deflate inflation is not implemented. Use the new Apache environment variable JK_IGNORE_CL instead, to let mod_jk ignore an existing Content-Length request header. (rjung)
update 44454: LB: Add warning to docs about problems with "busyness" load balancing method. (rjung)
fix 44454: Improve busy counter by using atomics. (rjung)
fix 56703: Status: Improve connected counter. Use atomics and for mod_jk (Apache) currectly count down connections closed by child processes that are stopped. (rjung)
fix 44571: Ensure that we return with status 503 if we can not get and endpoint for a worker. (rjung)
fix Apache: Improve log handling during graceful or normal restart. (rjung)
fix Don't update last access time of worker connections during optional checking of idle connections using CPing. Updating the time stamp breaks closing idle connections. (rjung)
fix Adjust linger parameters used during connection shutdown. (rjung)
fix Fix annoying redefine warnings for the autoconf PACKAGE defines during configure based builds. (rjung)
fix Status: Use multi-line table headers and fix invalid xml output. (rjung)
fix 44571: Implement an optional limit on concurrent requests allowed for a worker (attribute "busy_limit"). Original patch contributed by zealot0630 at gmail dot com. (rjung)
fix Correct log message "all endpoints are disconnected" to "no usable connection found, will create a new one". Tone done from info log level to debug for the common case. (rjung)
add 57536: AJP: Allow to configure connection source address. This should only be used on multi-homed hosts. The feature is experimental. (rjung)
add 57540: AJP: Forward name of SSL protocol used for handling the request (SSLv3, TLSv1, TLSv1.1, TLSv1.2). (rjung)
Changes between 1.2.39 and 1.2.40

Native
fix Fix forwarding of chunked requests, which is broken in version 1.2.39. (rjung)
fix 56352: Fix regression in memory release. (mturk)
fix Fix status worker display of worker IP address after name or port was changed. (rjung)
update 56297: Improve key hash function. Copied from APR. (rjung)
fix 55683: Remove quotes from quoted session cookies. (rjung)
fix 53542: ISAPI: Fix grammar in 503 error page. (rjung)
fix 55696: Crash on Mac OS X 10.9 during config parsing. (rjung)
Changes between 1.2.37 and 1.2.39

Native
update Deprecate nt_service from Apache Tomcat Connectors. (mturk)
fix 56133: Fix possible crash when a request fails during request body transfer to the back end and reply_timeout was set. Patch contributed by Hiroto Shimizu. (rjung)
fix Fix status worker not updating parameters for all members. (mturk)
fix 55853: HTTPD: Use the correct API for setting Content-Length. Patch contributed by areese yahoo-inc.com. (rjung)
add Add IPV6 support for connection to webserver. New directive prefer_ipv6 has been added to control the hostname resolution and preserve backward compatibility. (mturk)
add Add --disable-sock-cloexec to configure to disable use of SOCK_CLOEXEC (using FD_CLOEXEC + fnctl instead) so built modules will work with Linux kernels prior to 2.6.27. (timw)
update Clean up config file parsing. Worker names are now restricted to 60 bytes. (rjung)
update Allow to set a stickyness cookie in case a web framework breaks Tomcat's adding of the routing ID to the end of the JSESSIONID cookie. (rjung)
update Use max_packet_size also for request body forwarding. (rjung)
update Apache 2.4: By default forward logical client address as provided by mod_remoteip. When setting JkOptions ForwardPhysicalAddress mod_jk will instead forward the physical peer address. (rjung)
update Minor documentation improvements. (rjung)
Changes between 1.2.36 and 1.2.37

Native
fix Fix regression which can crash webserver in case worker is defined both as member of load balancer and as standalone worker. (mturk)
fix Fix core if debug log level is specified and there is no session identifier present. (mturk)
Changes between 1.2.35 and 1.2.36

Native
fix Use named shared memory objects so that we preserve runtime configured data instead of resetting on each child creation. (mturk)
fix Fix dead-lock caused by not releasing mutex on close. (mturk)
fix Fix compilation of mod_jk for HTTPD 1.3. (rjung)
fix 46893: HTTPD 1.3: Apply fix to HTTPD 1.3. It was fixed for HTTPD 2.x already in version 1.2.30. (rjung)
update HTTPD 1.3: Allow to set path parameter used when doing JkStripSession. This was available for HTTPD 2.x already since mod_jk 1.2.27. (rjung)
Changes between 1.2.33 and 1.2.35

Native
fix HTTPD: Fix crash on unknown worker names. (mturk)
fix IIS: Fix crash on worker process recycle. (mturk)
fix 52659: IIS: Fix shared memory corruption. (mturk)
fix 52921: HTTPD: Fix crash in uri mapping. (mturk)
Changes between 1.2.32 and 1.2.33

Native
fix 52793: AJP: Fix default value of forwarded worker activation state. Contributed by Yoshihito Fukuyama. (rjung)
fix HTTPD: Improve support for HTTPD 2.4 by using client_* instead of remote_* variables. (rjung)
fix 52564: Fix building with format checking gcc security hardening cflags. Contributed by Tony Mancill. (rjung)
fix 52567: Balancer member in recovery state can switch back into error state if it is idle. (rjung)
update Log error if unable to load URI workermap file, and improve logging of unreadable worker files on IIS. (timw)
update Remove deprecated JNI worker and build dependency on Java SDK. (mturk)
fix 51253: Forward WWW-Authenticate header when using server generated error pages (rjung, mturk).
update 46406: IIS: Support relative paths in configuration. The paths are presumed to be relative from isapi_redirect.dll. (mturk)
fix 50233: Do not use hard limit on uri size (mturk).
update IIS: Use Windows Server 2003 SP1, Windows XP SP2 as minimal version supported. (mturk)
fix 47038: Fix compiler warning when using --enable-flock for configure. (rjung)
add 51326: URI Map: Add "session_cookie" and "session_path" rule extensions. Contributed by Eiji Takahashi. (rjung)
update 51333: IIS: Document configuration requirement for 64 Bit environment. (rjung)
add 51743: HTTPD: Support rule extensions when defining the request worker with an environment variable (e.g. JK_WORKER_NAME). (rjung)
fix 51769: IIS: Allow URIs which contain "META-INF" or "WEB-INF" as long as they are not path components of the URI. (rjung)
fix 52056: HTTPD: JK request log does not always log correct response status. Fixed by refactoring JK request log to use the standard request log hook. (rjung)
add HTTPD: Allow to choose a sticky worker using the environment variable JK_ROUTE. This can be used if sessions and routes are send with the request in a non-standard way. (rjung)
add URI Map: Add "sticky_ignore" extension attributes to uri worker map. It allows to disable stickyness for individual mounts. (rjung)
add HTTPD: Allow dynamic disabling of stickyness using the environment variable JK_STICKY_IGNORE. This can be useful to break cookie stickyness for non-sticky requests like login forms. (rjung)
add LB: New balancing method "Next" to distribute sessions in a round-robin way. (rjung)
add LB: Add counter for created sessions to status worker and HTTPD notes. It actually counts the number of requests that do not carry a session id. (rjung)
add URI Map: Add "stateless" extension attributes to uri worker map. This can improve session load balancing. (rjung)
add HTTPD: Allow dynamic switching of requests to "stateless" using the environment variable JK_STATELESS. (rjung)
update AJP: Improve logging when request does not fix into an AJP packet. (rjung)
Changes between 1.2.31 and 1.2.32

Native
fix 51417: Fix worker busy detection by querying the worker endpoint. Abandoned connections can leave a worker in busy state without decrementing busy counter. (mturk)
fix 50339: Fix whitespace trimming when parsing attribute lists. (rjung)
fix 41263: Support Servlet API getRemotePort(). Works for Tomcat 5.5.28, 6.0.20 and 7.0.0 and Apache and ISAPI plugins. (rjung)
fix 41923: AJP: Close AJP connection to Tomcat on client write error when recovery_options 4 is specified, aborting the response write on the Tomcat side. (timw)
update AJP: Cap the lingering bytes that will be read when shutting down an AJP socket at 32k to prevent CPU spikes in the web server when a client aborts on a large response body. Also reduce total linger time to 2s. (timw)
fix 50839: AJP: Fix 30sec CPU spike due to incorrect counting of lingering bytes causing a busy loop when a client aborts connection during a response write. Fixes regression in 1.2.31. (timw)
add LB: Forward worker activation state as request attribute "JK_LB_ACTIVATION". Possible values are "ACT" (active), "DIS" (disabled) and "STP" (stopped). (rjung)
fix HTTPD: Forward WWW-Authenticate from backend when status is 401 and server generated error pages are used. (rjung)
fix 50363: IIS: Prevent chunk encoding of empty message bodies for 204, 205 and 304 responses. (timw)
fix 50975: IIS: Fix hanging of Transfer-Encoding: chunked requests when Content-Length header is present in request as well. Also addresses situation where IIS appears to create a Content-Length header for a small chunk encoded request when none was present in the original request. (timw)
fix 47679: IIS: stop truncation of request headers when ISAPI redirector used as an extension without the corresponding filter installed. (timw)
fix NSAPI: Use lower case header names for responses. Otherwise the web server might add chunked transfer encoding header in addition to our content length header.
update Docs: Improve load balancer documentation. (rjung)
Changes between 1.2.30 and 1.2.31

Native
fix 49413: AJP13: Drop flush packets send by the backend after the response has been finished. (rjung)
update AJP: Log the local and remote socket address. (mturk)
update Watchdog: Move the maintain workers outside the critical section allowing other threads to use the connection pool during maintenance. (mturk)
update Common: Add svn revision to init log message. (rjung)
fix Common: Don't destroy errno during trace logging. (rjung)
update Apache: Add support for Apache 2.3/2.4. (rjung)
update Apache: Added version number resource for mod_jk.so on Windows. (timw)
update 48501: IIS: Added rotatelogs style log rotation to ISAPI Redirector. (timw)
fix 38895: IIS: Use RAW headers instead of CGI headers by default to prevent conversion of underscores '_' to hyphens '-' in header names. Old behaviour can be enabled by defining USE_CGI_HEADERS. (timw)
fix 49511: IIS: Do not override IIS log information when subsequent requests on a keep-alive connection are not mapped into the ISAPI Redirector. (timw)
fix Docs: Document SSLOptions needed for SSL information forwarding. (rjung)
update Docs: Grammar and style improvements and clarification about serving static content by IIS. Patch provided by André Warnier. (rjung)
fix Docs: Update subversion paths used in docs. (rjung)
Changes between 1.2.28 and 1.2.30

Native
update Apache: Improve compatibility with Apache 2.3. (rjung)
fix 46632: Apache: Do not register child cleanup for our pools. (mturk)
fix 46893: Apache: Log warning only if JkShmSize was actually set in the configuration. (mturk)
update IIS: Include optional chunking support. Off by default. (mturk)
fix 48763: IIS: Do not send Content-Length when using chunked encoding or length larger 4GB. (mturk)
fix 48223: IIS: Propagate correct backend error code to IIS. (rjung)
fix 47867: IIS: crash during startup, when compiled with VS2008 and workers.properties contains unsupported properties. Patch provided by Indrek Juhani (rjung)
fix 47628: IIS: Fix deadlock when restarting the Application Pool caused by not releasing the critical section lock. Patch provided by Bret Prucha. (mturk)
fix IIS/NSAPI: Correct log file flushing after each line. (mturk)
add NSAPI: Add Microsoft Visual C++ Makefile. (mturk)
update AJP: Improve socket shutdown handling. (mturk)
update AJP: Ensure we never reuse a non reusable socket. (mturk)
update AJP: Tolerate a single excess packet when waiting for cpong. (mturk)
update AJP: Check protocol correctness more strictly. (mturk)
update 48410: AJP: Use poll instead select so we can work with more then 1024 sockets. (mturk)
fix 46503: AJP/Status: Garbage data in worker domain and route. (mturk)
fix 48276: AJP: When worker contact cannot be resolved mark the worker as disabled instead failing to start the server. (mturk)
fix 48169: AJP: Improve CGI interoperability by closing all sockets during EXEC. (mturk)
add Status: Add number of open backend connections to status worker. This feature is experimental, the displayed value might not be accurate. (mturk)
update 47224: Status: When address gets changed invalidate all opened sockets in the endpoint cache. This will cause new backend connections to get opened using new address. (mturk)
fix 48305: Status: Do not show "secret" property when doing dump. (mturk)
fix 45610: Status: Don't accept requests with empty value for sub worker parameter. (rjung)
fix 45610: Status: Fix erroneous unsetting of sticky_session and sticky_session_force when updating other load balancer attributes via the status worker. (rjung)
fix 47222: Status: Add ping_timeout to the shared memory and allow dynamic configuration. (mturk)
fix Status: Remove duplicate "errors" line in property view of AJP13 workers that are part of a load balancer. (rjung)
fix LB: Fix route logging. (rjung)
update Logging: Automatically detect size of thread id for logging. (rjung)
update Logging: Add optional log file locking for Windows when defining JK_LOG_LOCKING. (mturk)
update Configuration: Update example configuration. (rjung)
update Docs: Update information about tools needed to create a release. (rjung)
fix 47983: Docs: Fix typo in example config which breaks startup. (rjung)
update Build: Force copy of automake files. (rjung)
update Build: Tomcat code repository structure cleanup reflected in documentation and build script. (rjung, mturk)
Changes between 1.2.27 and 1.2.28

Native
add Apache: Add more environment variables to overwrite request information. Useful in case a proxy is in front of Apache and sends us original request information e.g. via custom headers. (rjung)
update Apache: No longer preallocate entries for JK request log. (rjung)
fix 46352: Apache: Fix crash when using SetHandler jakarta-servlet in VHost without any JkMount. Crash due to incorrect initialization of mount extensions. (rjung)
fix Apache: JkWatchdogInterval had wrong interval calculation causing a 10 times higher watchdog interval then configured. (mturk)
fix Apache: Activate forwarding of SSL key size by default. (rjung)
fix 46169: Apache 1.3: Backport use_server_errors mount extension. (rjung)
fix 46763: Apache 2.0: Survive the log mutex during graceful restart. Patch provided by Eiji Takahashi. (mturk)
fix 46416: Apache 2.0 on Windows: Include mstcipip.h even if the apr doesn't include it. (mturk)
update IIS: Update uriworkermap.properties file on a regular interval. This requires both worker_mount_reload and watchdog_interval to be defined. (mturk)
update IIS: Remove obsolete entries from registry file. (mturk)
fix 46579: IIS: Use local environment table instead environment variables for setting the JKISAPI_PATH and JKISAPI_NAME. (mturk)
update LB: Add new property error_escalation_time to fine tune escalation of local errors to global errors. (rjung)
update LB: If the sticky session affinity mark contains a dot, treat the part before the dot as the domain name. This allows to have full node session affinity with domain failover. (mturk)
fix LB: make forced recovery work with local error states. (rjung)
fix LB: Only update error state and error time, if we actually have a new state. (rjung)
fix LB: Set global worker state to error when we reach max_reply_timeouts, or fail_on_status triggered hard error. (rjung)
update AJP: Add a new error type JK_AJP_PROTOCOL_ERROR. (mturk)
update AJP: Allow worker ports lower or equal to 1024. (rjung)
update AJP: Improve some AJP error log messages. (mturk)
update Status: Allow changing worker address and port of AJP workers. The address is resolved on next request for that worker. (mturk)
update Status: Allow update actions to show error messages in the result page. (rjung)
update Status: Refactor update actions. (rjung)
update Status: Do not redirect to the show or list page, if an error occured during an action. (rjung)
update Status: Include error time in display. (rjung)
update Status: Remove redundant port information from worker display. Rename address column and remove its explanation from the legend. (rjung)
update Status: Optimize forced uriworkermap.properties reload. (mturk)
fix Status: Fix crash in text display. (rjung)
fix Status: Show - Edit - Show always ends in single lb member show, even when started from all members lb show. (rjung)
fix Status: Wildcards in sub worker names were broken for update actions. (rjung)
fix Status: Add use_server_errors to map display. (rjung)
update SHM: Move locking into the data pull and push methods. (rjung)
update JNI: Deprecate JNI workers. (rjung)
fix Netware: Missing define for MAX_PATH. Patch by Guenter Knauf. (rjung)
update Docs: Add a new HowTo page about reverse proxies. (rjung)
update Docs: Add an explanation of local error states to the timeouts documentation. (rjung)
update Docs: Clarify relation between socket_timeout and socket_connect_timeout. (rjung)
update Docs: Clarify IIS URL rewrite feature. (rjung)
fix 46834,46734: Docs: Fix a couple of missing or broken links. (markt,rjung)
fix Docs: Add 2008 news to main page and menues. (mturk, rjung)
Changes between 1.2.26 and 1.2.27

Native
fix 46109: Decay reply_timeouts even when lb method is busyness. Also reset reply_timeouts during forced recovery. (rjung)
update AJP13: Recycle connection if previous request didn't complete. (mturk)
update Maintain should not run multiple times in parallel. (mturk)
fix Apache: Fix small memory leak during restart. (mturk)
update Improve signal handling during socket shutdown. (mturk)
add URI Map: Add debug dump function for uri worker map. (rjung)
update Add revision number to version info for non-release builds. (rjung)
add IIS: Optionally allow chunked encoding for responses. At the moment only usable, if build with ISAPI_ALLOW_CHUNKING defined. Based on patch by Tim Whittington. (rjung)
update IIS: Optionally use raw headers instead of CGI headers. Fixes problem "underscore=dash" problem in header names. At the moment only available, if build with USE_RAW_HEADERS defined. (rjung)
update IIS: Optionally improve IIS 5.1 compatibility. At the moment only available, if build with AUTOMATIC_AUTH_NOTIFICATION defined. Based on patch by Tim Whittington. (rjung)
fix IIS: Fix memory corruption due to parallel initialization by multiple threads. (rjung)
update Windows: Use non-default socket keepalive interval. (mturk)
add IIS: Add environment variables JKISAPI_PATH and JKISAPI_NAME. (mturk)
add Added socket_connect_timeout directive for setting the connect timeout for the socket. This enables to have low connection timeout but higher operational timeouts. (mturk)
fix AJP13: [CVE-2008-5519] Always send initial POST packet even if the client disconnected after sending request but before providing POST data. In that case or in case the client broke the connection in a middle of read send an zero size packet informing container about broken client connection. (mturk)
add AJP13: Added connection_acquire_timeout directive for setting the absolute timeout the worker will wait for a free endpoint. (mturk)
update Apache: Allow to set path parameter used when doing JkStripSession. (mturk)
update Refactor retries implementation and change semantics of retries attributes. (mturk)
update Status: Allow showing only a single member for a load balancer. (rjung)
update Status: Add display of seconds since last statistics reset and access and transfer rates. (rjung)
add AJP13: Add a configurable retry_interval time. (rjung)
update Documentation: Enhance description of connection_pool_size. (rjung)
update IIS: Refactor error page generation. (mturk)
fix IIS: SERVER_NAME variable can be the same for multiple different server instances if requests are handled according to the ip:port combination. Use INSTANCE_ID variable to which the request belongs instead. (mturk)
add Allow forwarding server error pages. This can be done on per-uri basis using new use_server_errors extension. (mturk)
add Added session_cookie and session_path for configuring default session identifiers. (mturk)
update Use max_packet_size also as TCP send and receive buffer size. (mturk)
update Apache: Do not allow Apache to start in multi-threaded mode if mod_jk was only build for single threaded server (prefork). (mturk)
fix 45812: Add done() service method that causes sending EOS bucket for Apache httpd 2.x. This allows filter chain to work properly. (mturk)
add Added connection_ping_interval, ping_timeout and ping_mode directives. (mturk)
fix Apache: Use correct ld flags provided by apxs when building module. Prevents some crashes on AIX for httpd 1.3 module. (rjung)
fix Documentation: "val" attribute numbering in status worker needs to start with 0 instead of 1. (rjung)
update Documentation: Remove JNI parameters from sample configuration in the workers common howto. (rjung)
fix 45026: For Apache httpd 2.x add "Unknown Reason" as the reason phrase, if we get an empty one from the backend. Otherwise httpd 2.x returns status 500. (rjung)
fix Build: Fix Cygwin build. (rjung)
update Documentation: Add info to docs, that variables sent via JkEnvVar are not listed in request.getAttributeNames(). (rjung)
add Add watchdog background thread for Apache 2.x and IIS doing internal maintenance (idle connection checks, backend probing). See JkWatchdogInternal (Apache) and watchdog_interval (IIS). (mturk)
update Change log level of some messages from error to info. (mturk)
fix Documentation: Fix docs for worker attribute "secret". (rjung)
update Detect correct plugin name for various web servers via additional preprocessor defines. (rjung)
fix LB: Do not put loadbalancer node in error state if there is opened channel. This fixes the bug when new connection fails due to busyness, causing opened connections fail stickyness. This brings back per-node busy counter and private state array for each request. We can mark the state as error for failover to work while still operating and reporting node as OK if there are opened working connections. (mturk)
fix 44738: Fix merging of JkOption ForwardURI* between virtual hosts. Patch contributed by Toshihiro Sasajima. (rjung)
add URI Map: Add extension attributes to uri worker map. Allowed are reply_timeout, active/disabled/stopped and fail_on_status. Usage currently only implemented for httpd and IIS. (rjung+mturk)
fix URI Map: Make dynamic reloading atomic and free memory not needed any longer. (rjung)
add Configure: Don't use post httpd 2.2.0 API functions when building with new --enable-api-compatibility configure switch. (rjung)
fix Apache: JkAutoAlias does not work in combination with JkMountCopy if there are no JkMount in virtual host. (rjung)
update LB: Optimize state macros to improve performance. (rjung)
add Apache: Allow dynamic setting of reply timeout using the environment variable JK_REPLY_TIMEOUT. (rjung)
add Status: Add manageability for ajp parameters of ajp workers and ajp lb members. (rjung)
update Status: Change parameter names of update action to make them more easily distinguishable from other parameters. (rjung)
add Status: Add ajp worker statistics also for workers, that are not lb members. (rjung)
update AJP: Refactor factories, move ajp13/ajp14 common parts into ajp_factory. (rjung)
update Status: Only sync shm worker config values of the workers for which we changed values. (rjung)
fix Status: Set lb_factor instead of distance. (rjung)
update Status: Minor layout changes, use drop down instead of multiple text links. (rjung)
update SHM: Use local copies of read mostly attributes of lb sub workers in lb and status worker. (rjung)
update Status: Add "dump" action to dump our initial configuration. (rjung)
update Status: Use property table to decide which cmd action uses which output elements. (rjung)
update Common: Include original configuration map in worker_env to make it available for workers, e.g. the status worker. (rjung)
update LB: Refactor "route" return for httpd note. Don't use a member of the worker_record, because that's not thread safe. (rjung)
update Common: Refactor "retries", remove from service and jk_worker, move into ajp worker instead. (rjung)
update SHM: Use distinct structs for lb and ajp13 in shm. Improves type safety and saves a few bytes. (rjung)
update SHM: Remove unused attributes. (rjung)
update SHM: Automatically determine shm size for all web servers. (rjung)
update SHM: Make open/attach logging consistent for all web servers. (rjung)
update Status: Include server local time in output. (rjung)
fix 44116: Fix handling of multiple JSESSIONID cookies. (rjung)
fix 37850: Use thread safe localtime_r where appropriate. (rjung)
fix Use thread safe strtok_r on more platforms, especially AIX. (rjung)
update Status: Improve XSS hardening. (rjung)
update 35303: Move initialization of service members with defaults from web server specific code to our generic jk_init_ws_service() function. (rjung)
fix 36385: Add missing prepost CPing/CPong directly after connect in case prepost CPing is used, but no connect CPing. (rjung)
update 37322: Apache: Enhance robustness of message formating in jk_error_exit(). (rjung)
fix 44147: Multiple load balancing workers problem. (rjung)
Changes between 1.2.25 and 1.2.26

Native
fix 42003: Allocate memory instead using fixed size from the stack. (mturk)
fix 43229: Load balancer does not do fail over after reply timeouts. (rjung)
fix JKStatus: Repair detailed Apache httpd version display. This was broken for httpd version 2.2.4+. (rjung)
update LB/AJP: Refactoring of jk_connect.c, jk_ajp_common.c, jk_lb_worker.c (rjung)
fix Configure: Repair broken apxs auto-detection. (rjung)
update Configure: Remove trace logging from compiled code via new --disable-trace configure switch. (rjung)
update Common: Maintain idle connections in decreasing (LRU) slot order. (rjung)
update Apache: Create JK_WORKER_ROUTE and JK_REQUEST_DURATION notes for access log even if no JkRequestLogFormat is set. (rjung)
update JKStatus: Enhance URI to worker map listing for Apache httpd. We now list maps for all virtual servers and not only the one, in which JKStatus itself was called. (rjung)
update JKStatus: Enhance URI to worker map listing. Update stale uriworkermap.properties immediately. (rjung)
fix 43873: Fix small memory leak occuring during httpd restart. (rjung)
update Common: Allow '*' for the worker name in exclusion rules (resp. JkUnMount) which will override all workers. (rjung)
fix 42038: Correct overlay of mounts and unmounts for IIS. (rjung)
fix 43684: Replace JkMountFile by JkMountFileReload in uriworkermap.properties docs. (rjung)
update Apache: Add new value "All" for JkMountCopy. (rjung)
fix 43516: Memory leak for Apache httpd module of size 8KB for every virtual host without JK directive after each restart. (rjung)
update Apache: Cleanup init and destroy of server configuration. (rjung)
update Apache: Remove global configuration items from per server configuration. (rjung)
update Apache: Remove unused attributes secret_key and automount/JkAutoMount. (rjung)
update Cleanup of jk_uri_worker_map. (rjung)
update Documentation: Small additions to JkShmFile documentation. Contributed by Gerhardus Geldenhuis. (rjung)
fix AJP13: Ignore flush packets before we received the response headers. (rjung)
fix Fix crash during startup when using worker configuration inheritance (attribute "reference") and log level debug. (rjung)
fix AJP13: Match header names exactly against pre defined constants. Avoid possible confusion with custom header names using a standard header name as a prefix. (rjung)
fix jkstatus: Fix correct parameter validation at JkStatusUpdateTask and JkStatusUpdateLoadbalancerTask ant tasks. Reported by Christian Mittendorf. (pero)
Changes between 1.2.24 and 1.2.25

Native
update IIS: Fix shm shutdown behaviour. (rjung)
update General: fail_on_status used in a load balancer can optionally do fail over without putting the failed worker in error state. (rjung)
update NSAPI: Improve build description for Unix. (rjung)
update NSAPI: Add initialization startup message containing JK version. (rjung)
fix General: Declare static functions as static. (jim)
update Documentation: Clarify fail_on_status behaviour. (rjung)
fix General: Do fail_on_status before returning the response headers. (rjung)
update NSAPI: Fix shm shutdown behaviour. (rjung)
update NSAPI: Set return status even if request ended with an error. (rjung)
update NSAPI: Allow using without shm_file on WIN32 and Netware. (rjung)
fix NSAPI: Fix Crash of nsapi for log level debug and unset refect_unsafe. (rjung)
update NSAPI: Improve Solaris and Linux Makefiles for nsapi build. (rjung)
fix Build: Improve pid_t type detection during configure on Solaris. (rjung)
update Build: Experimental build support for gcc on WIN32 and Netware. (fuankg)
update Build: Makefile optimizations for Apache httpd 1.3/Netware . (fuankg)
fix General: Fix missing flush bug introduced in 1.2.24. (rjung)
Changes between 1.2.23 and 1.2.24

Native
update Documentation: Improved workers.properties description in the reference guide. (rjung)
update Documentation: Add a HowTo about the various timeouts. rjung)
update Logging: add milliseconds to the default timestamp format, if we have gettimeofday(). (rjung)
update Apache: add milliseconds (%Q) and microseconds (%q) as possible JkLogStampFormat conversion specifiers. This does not use strftime(), but needs gettimeofday(). (rjung)
update IIS & Sun: Log service failures also, if return code is negative. (rjung)
fix 42849: Abort startup of Apache httpd 1.3 in case mod_jk initialization failed. We already do the same for Apache httpd 2.x. (rjung)
fix 42849: Refuse to operate with IIS in case the initialization failed. Instead requesting isapi_redirect.dll 500 will be returned to the user. This is as closest as it can get to Apache Httpd where we refuse to start the server in case of fatal initialization errors. (mturk)
fix Load Balancer: Fix a deadlock in lb worker, which was exposed on Solaris for threaded Apache MPMs. (rjung)
update Logging: handle LWP IDs as 32 Bit unsigned. Try to make it work, although pthread IDs are opaque. (rjung)
update JkStatus: Added manipulation of max_reply_timeouts. (rjung)
update LB, Status: Add feature max_reply_timeouts, to make lb tolerant against occasional long running requests. (rjung)
update JkStatus: Added OK/IDLE as the successor of N/A. (rjung)
update Status worker: Renamed runtime states. All states have a major state (OK or ERR) and a substate. Changed the name N/A to OK/IDLE. Added docs about the meaning of the states to the status worker page in the reference guide. No new states have been added to code. (rjung)
update Common: Add recovery options for recovering idempotent http methods HEAD and GET. (rjung)
fix Correct documentation for worker attributes retries and recovery_options. (rjung)
fix Make writing log lines and line endings more atomic. (rjung)
update Common: Refactored and unified jk_map_read_prop* and jk_map_load_prop* for all use cases. (rjung)
update Common/Apache/IIS/Netscape: Add an option to check decoded URLs for potentially malicious constructions. (rjung)
update IIS: Document auth_complete and uri_select. (rjung)
update Apache/IIS/Netscape: Change the default forwarding encoding to the new proxy method. (jfclere, rjung)
update Common: Optionally reencode URIs before forwarding to the backend. Based on the URI reencoding done bei httpd mod_proxy. (jfclere, rjung)
update Common: auto-detect correct print format for pid_t. This fixes at least compiler warnings on Solaris. (rjung)
fix 42608: Handle Content-length as unsigned 64Bit to allow for huge up- and downloads. (rjung)
update Apache: Add forwarding uri to debug log. (rjung)
update Docs: Clarify relation between worker names and jvmRoute for load balancing. (rjung)
fix Use initial zero timeout for jk_is_socket_connected. The resulting detection is the same but offers a huge performance increase with mod_jk. In most cases the Operating System does not favor the 1 microsecond timeout, but it rather rounds that up to much higher value (frequency of interrupt timer which on most systems defaults to 100Hz). Patch provided by David McLaughlin. (mturk)
update NSAPI: Check correct log file and shm file configuration during startup. (rjung)
fix NSAPI: Add support for the general options concerning retries, flushing and connection persistance. (rjung)
fix NSAPI: fix crashes due to use of mount attribute in workers.properties. Changed initialization order. (rjung)
fix Improved handling of libtool and discrepancies between CC env variable and CC used during apache build by configure script. (rjung)
fix Always build with thread support, unless flag --enable-prefork is set during for configure. (rjung)
update Use snprintf/vsnprintf from ap_snprintf.c for platforms other than Windows, which might lack snprintf/vsnprintf implementations when NOT build for Apache httpd 2.x/APR (e.g. Sub Web Server) or without using configure. (fuankg)
update Imported ap_snprintf() from Apache 1.3. (fuankg)
fix Fix incorrect log object cleanup during statup, leading to crashes at least on iSeries. (rjung)
update Add jk_stat() and jk_file_exists() as wrapper functions. i5/OS V5R4 expects filename in ASCII for fopen but requires them in EBCDIC for stat(). (hgomez)
update i5/OS (AS/400) V5R4 port where Apache 2.0 modules should now use UTF8. (hgomez)
update Docs: Add comments on i5/OS build for V5R4 and previous releases. (hgomez)
Changes between 1.2.22 and 1.2.23

Native
update [CVE-2007-0450] and [CVE-2007-1860]: Change the default value of JkOptions to ForwardURICompatUnparsed. The old default value was ForwardURICompat. This should make URL interpretation between Apache httpd and Tomcat consistent (prevent double decoding problems). (rjung)
Changes between 1.2.21 and 1.2.22

Native
fix Refactor line endings logging to make it correct for all platforms and webservers. (mturk)
update Added command line windows make files. (mturk)
update Allow fail_on_status directive to be multi line. (mturk)
fix 42076: Fix name of new option from ForwardCertChain to ForwardSSLCertChain as documented. (rjung)
fix Docs: Fix a couple of typos, change format of a few tables, fix links to news pages. (rjung)
fix Fix correct URL for TC 6 examples in new IIS rewrite.properties configuration example file. (rjung)
fix Add svn properties to several files. (rjung)
update Add TC 6 examples to uriworkermap.properties in config examples. (rjung)
update Allow multiple status codes for fail_on_status directive. The status codes can be delimited by space or comma characters. (mturk)
update IIS. Added pcre like regular expressions for url rewrite rules. (mturk)
fix 41922: Apache 1.3. Enable JkEnvVar. (mturk)
update Apache. Add --enable-flock configure parameter for explicit compilation of faster flock() system calls for OS supporting those calls. By default the fcntl system call for locking will be used that is a little bit slower but it can work on NFS mounted volumes as well. (mturk)
fix 41562: Add Debug logging for read from client in ISAPI Redirector. Contributed by Tim Whittington. (mturk)
update Apache. Add ForwardSSLCertChain JkOption. Contributed by Patrik Schnellmann. (mturk)
fix IIS. Do not forbid access to web-inf or meta-inf if there is no mapped worker. This allows to have resource with those names that are outside mapped contexts. (mturk)
update Apache. Use process id for creating shared memory name and delete shared memory and shared memory lock files on exit. (mturk)
fix IIS. Fix Keep-Alive regression introduced in 1.2.21. (mturk)
update Delete unused check for empty init_map during startup. (rjung)
fix 41770: Fix startup error if no JkWorkersFile is used. (rjung)
update Use JK_TRUE/JK_FALSE instead of OK/!OK as return values in init_jk(). (rjung)
update Minor adjustments to apache startup log messages (when to use STDERR, remove deprecated NOERRNO flag, shm warning and warnings for usage of default files). (rjung)
update Replace APR precompiler directive by httpd mpm_query to detect MPM threading. Add a debug log message about auto-detected pool size. (rjung)
fix Make MMN check easier to understand and a little more precise (for new ap_get_server_banner()/ap_get_server_description()). We use the new API only for Apache httpd 2.3. This way our binaries are not tightly coupled to a minor 2.0 version, and we don't use ap_get_server_banner() any way. (rjung)
fix Use the full description string ap_get_server_description() instead of the truncated info from ap_get_server_banner(), because this info gets used internally (status worker display and ajp14 backend communication) and is not send back to the normal user. (rjung)
fix 41757: Document the "--enable-prefork" flag of configure. (rjung)
update Enhance log messages for failures when parsing attribute maps. (rjung)
fix Correct log message during worker initialization, in case remote host could not be resolved. We logged the default host name "localhost" instead of the configured one. (rjung)
fix 41770: Fix the second part of the bug: local_worker and local_worker_only is missing from the list of deprecated attributes (and not supported either), so prevents the web server from startup. (rjung)
Changes between 1.2.20 and 1.2.21

Native
fix [CVE-2007-0774]: A denial of service and critical remote code execution vulnerability. Caused by buffer overflow in map_uri_to_worker() when URL were longer that 4095 bytes. Reported by ZDI (www.zerodayintiative.com). Please note this issue only affected versions 1.2.19 and 1.2.20 of the Apache Tomcat JK Web Server Connector and not previous versions. Tomcat 5.5.20 and Tomcat 4.1.34 included a vulnerable version in their source packages. Other versions of Tomcat were not affected.
add Check the worker. parameters and don't start if the parameter is not a valid one. (jfclere)
add 41439: Allow session IDs to get stripped off URLs of static content in Apache by adding JkStripSession directive (configurable per vhost). (mturk)
add Change semantics of empty defaults for JkEnvVar variables. Until 1.2.19: not allowed. In 1.2.20: send variables as empty strings, if neither set to non empty in config, nor during runtime. Starting with 1.2.21: If config has no second argument only send variable if set (even when set to empty string) during runtime. Allows good combination with condition attribute in tomcat access log. (rjung)
fix 41610: Fix incorrect detection of missing Content-Length header leading to duplicate headers. Contributed by Boris Maras. (rjung)
fix Better build support for SunONE (Netscape/iPlanet) webservers. (jim)
add Add warning if duplicate map keys are read and are not allowed, e.g. when parsing uriworkermap.properties. (rjung)
fix Don't concat worker names, if uriworkermap.properties has a duplicate pattern, instead overwrite the worker. (rjung)
fix Log deprecation message even in duplication case. (rjung)
fix uriworkermap.properties: Fix off-by-one problem when deleting URL mapping during reloading of uriworkermap.properties. (rjung)
add 41439: Allow session IDs to get stripped off URLs of static content in IIS (configurable). (rjung)
add 41333: Refactoring isapi_plugin configuration reading. (rjung)
add 41332: Add some more errno logging and unify the format. (rjung)
add JkStatus: Improved logging by adding status worker name to messages. Added messages to the recover worker action. (rjung)
add JkStatus: Refactoring searching for workers and sub workers. (rjung)
add 41318: Add configuration to make status worker user name checks case insensitive. (rjung)
add JkStatus: Add estimated time until next global maintenance to other mime types and adopt jkstatus ant task. (rjung)
add JkStatus: Show estimated time until next global maintenance. Change displayed time until next recovery to a min/max pair. (rjung)
add JkStatus: Allow a user of a read/write status worker to switch it to and from read_only mode temporarily. (rjung)
fix JkStatus: Do not show read/write commands in a read_only status worker. (rjung)
add JkStatus: Allow lb sub workers in error state to be marked for recovery administratively from the status worker. (rjung)
add Load Balancer: Do not try to recover multiple times in parallel. Use additional runtime states "PROBE" and "FORCED". (rjung)
fix JkStatus: Improve data synchronization between different processes. (rjung)
fix 41381: Fix segfault in feature fail_on_status (wrong order of log arguments). Patch by Juri Haberland. (rjung)
fix Use correct windows line endings for log file on WIN32 platform. (rjung)
Changes between 1.2.19 and 1.2.20

Native
add JkStatus Ant Task documentation page. (pero/rjung)
add JkStatus Ant Tasks: Add new tasks for update and reset. (pero)
update JkStatus Ant Tasks: Update for new xml status format. (pero)
update Allow integer and string values when setting enumeration/boolean attributes via status worker update action. (rjung)
add Docs: New reference guide page for status worker. (rjung)
update Docs: Renaming the config dir to reference and using the title Reference Guide in the docs. (rjung)
update Added retry_on_status for workers directive. (mturk)
update Status Worker: Add directive to make property prefix and good/bad rule configurable. (rjung)
update Status Worker: Omit lb members when att=nosw. (rjung)
update Status Worker: New command cmd=version for a short version output. (rjung)
update Status Worker: New output stype mime=prop produces property lists. (rjung)
fix Apache: Fix incorrect handling of JkEnvVar when Vars are set multiple times. (rjung)
update Renamed jvm_route to route. Deprecated jvm_route, but still use it as fallback when parsing the worker configuration. (rjung)
update IIS: Make uriworkermap file reload check interval configurable. (mturk)
update Apache: Make uriworkermap file reload check interval configurable. (rjung)
update Status Worker: Add directives for customizing the XML output (ns, xmlns, doctype). (mturk)
add Docs: New page with description of uriworkermap. (rjung)
update Docs: Added short description of max_packet_size to worker reference. (rjung)
update Status Worker: All functions accessible also for xml and txt mime types (list, show, update, reset). (rjung)
update Status Worker: New global health indicators for load balancers named bad (error, recovering or stopped), degraded (busy or disabled) and good (the rest, active and OK or N/A). (rjung)
update Status Worker: New edit page, to change one attribute for all members of a load balancer. (rjung)
update Status Worker: Standard logging for status worker. (rjung)
update Status Worker: code refactoring. (rjung)
update Status Worker: New attribute user (list) denies access, if the request user in the sense of remote_user is not in this list. Empty list = no deny (rjung)
update Status Worker: New attribute read_only disables the parts of the status worker, that change states and configurations. (rjung)
fix 36121: Don't change main uri when mod_jk serves included uri. (markt)
update Apache VHosts: Merge JkOptions +base - -base + +vhost - -vhost. (rjung)
update Apache Docs: Adding requirements, context information, default values and inheritance rules to the Apache config documentation. (rjung)
update Status Worker: Add source type to status worker, remove the redundant "context" column in the map listing (context=uri). (rjung)
update uriworkermap: On reload of the file, all old entries from the previous file version get deleted, before the new ones are being read. (rjung)
fix Keep normal maps and exclusion maps internally separate. Don't treat them as the same when adding a rule. (rjung)
update Status Worker: Display mapping rules also for non-lb workers and in global view. (rjung)
update Apache VHosts: Use the vhost log files instead of the main log. (rjung)
update Apache VHosts: Allow individual timestamp formats by refactoring the formatting method. (rjung)
update Apache VHosts: Adding all missing config items to the virtual host level. Don't overwrite the settings from the global server, but inherit them in case they are not set in the virtual host. (rjung)
update Apache: remove unnecessary function names from log messages. (rjung)
update Apache: add a default log file location and a message, if the default gets used. (rjung)
update Apache: add missing JK_IS_DEBUG_LEVEL() (rjung)
update Apache VHosts: Allow JkWorkersFile, JKWorkerProperty, JkShmFile and JkShmFileSize only in global virtual server. (rjung)
update Add some more jk_close_socket() and reduce log level for some info messages. (rjung)
update Load Balancer: Added the Sessions strategy. Contributed by Takayuki Kaneko. (rjung)
update Docs: Minor enhancements and syncing with more recent versions. (rjung)
fix 40997: Separate uri mappings from their '!' counterpart when checking for duplicates in uriworkermap reloading. (rjung)
fix 40877: Make sure the shared memory is reset on attach for multiple web server child processes. (mturk)
update IIS: Added shm_size property to be able to deal with over 64 workers configurations. (mturk)
update IIS: Increase default thread count to 250, so its the same as Apache Httpd default configuration. (mturk)
fix 40966: Fix socket descriptor checks on windows. (mturk)
fix 40965: Initialize missing service parameters. (mturk)
fix 40938: Fix releasing of rewrite map. Thanks to Chris Adams for spotting that. (mturk)
update Apache: Added +FlushHeader JkOptions. (mturk)
update Added explicit flush when AJP body packet size is zero. (mturk)
fix 40856: Fixing case sensitivity bug in URL mapping. (rjung)
fix 40793: Documentation: Improvements to Apache HowTo provided by Paul Charles Leddy. (markt)
fix 40774: Fixing wrong recursion termination. This one restricted the "reference" feature unintentionally to 20 workers. (rjung)
fix 40716: Adding "reference" feature to IIS and Netscape. (rjung)
fix Documentation: Corrected SetEnvIf syntax in JK_WORKER_NAME example. (rjung)
fix Documentation: Added forgotten STATE and ACTIVATION notes for load balancer logging in Apache. (rjung)
update Apache: Use instdso.sh instead libtool: libtool does not work on HP-UX for example. (jfclere)
Changes between 1.2.18 and 1.2.19

Native
update Docs: Add SetHandler and new env var to Apache config docs. (rjung)
update Apache 1.3: Backport "no-jk" feature. (rjung)
update Apache: Add an environment variable to make SetHandler "jakarta-servlet" more useful. The variable is JK_WORKER_NAME, but can be changed by the new directive JkWorkerIndicator. (rjung)
fix LB: Don't use single worker shortcut, if the single worker is being diabled. (rjung)
fix Status worker: Add short explanation of activation and error states to legend. (rjung)
fix Docs: Add meaning of zero timeout values for various timeouts in workers.properties. (rjung)
fix LB: Cleanup of Mladens forced recovery. (rjung)
fix LB: Do not change lb_value for recovering workers to max, if we are using BUSYNESS method. (rjung)
fix Apache: Since 1.2.14 mod_jk failed to detect client abort. (rjung)
fix Docs: Corrected description of JkEnvVar. (rjung)
fix Solaris: Detect filio.h in configure to make the new connection detection build on solaris (r432825). (rjung)
update Add feature to force the recovery of workers that are member of loadbalancer if all the members are in error state. This fixes the time gap where 503 was returned caused by recovery_timeout although the backend was ready to handle the requests. (mturk)
update Docs: Seperate deprecated directives in their own table. (rjung)
update Docs: Allow "-" and "_" in worker names. (rjung)
update Allow multiple lines with attributes "balance_workers" and "mount". (rjung)
fix Make jk_is_some_property match more precisely. (rjung)
update JkStatus: Make refresh interval changeable. (rjung)
fix JkStatus: Adjust display of recover time wrt. global maintenance. (rjung)
update LB: Resetting worker state from OK to NA, if worker has been idle too long. (rjung)
fix Avoid compiler warnings concerning the use of lb_*_type arrays. Use functions instead. (rjung)
update Added %R JkRequestLogFormat option for Apache 1 and Apache 2. (mturk)
update Allow changing jvm Route from status manager. (mturk)
fix Do not retun 400 if Tomcat fails in the midle of the post request. Return 500 insted. (mturk)
update LB: Combine ok/error/recovering/busy runtime states into a single scalar. (rjung)
update LB: Combine active/disabled/stopped configuration states into a single scalar. (rjung)
update LB: Add several Apache notes to enable standard logging for load balancer results. (rjung)
update LB: Reorganisation of the main load balancer service loop. (rjung)
update Implement hierarchical worker configuration via attribute "reference". (rjung)
update Log deprecated properties. (rjung)
fix IIS: Fix simple_rewrite for the cases where the rewritten url is larger then the original one. (mturk)
update New JkOption "DisableReuse" to disable connection persistence. (jim)
update LB: Move sessionid retrieval out of get_most_suitable_worker into service. (rjung)
update Code cleanup for all service methods (use TRACE, JK_LOG_NULL_PARAMS, null pointer checks). (rjung)
update JKSTATUS: add refresh link. No refresh for updates. Redirect to list view after update. (rjung)
update Add new hook add_log_items into servers. (rjung)
update APACHE httpd: Rename apache logging notes. (rjung)
update LB: Rename lock and method constants. Add constants for defaults. (rjung)
fix Default log level should be INFO and not DEBUG. Default log level should be the same for all server types. (rjung)
fix Make rewrite_rule_map and log_level as non mandatory directives for isapi_redirect. (mturk)
fix 40107: Rewrite is_socket_connected function. Non blocking socket is not used any more. (mturk)
update Allow building with VS2005 without too many warnings. (mturk)
fix Decide by MMN, which piped log API we should use. mod_jk 1.2.18 broke compilation with Apache 1.3 pre 1.3.28. (rjung)
Changes between 1.2.17 and 1.2.18

Native
fix Using socklen_t in getsockopt. Also introducing jk_sock_t. (mturk)
update Allow recovery wait time below 60 seconds (new minimum is 1 second). (mturk)
Changes between 1.2.16 and JK 1.2.17

Native
fix Fix hanging jk status worker when certain attributes are being updated due to double locking. (rjung)
update Allow JkMount to behave like uriworkermap.properties by parsing pipe symbol as two directive marker. (mturk)
Changes between 1.2.15 and JK 1.2.16

Native
update Added simple rewrite capability for IIS. Although simple it will fulfill most needs. (mturk)
update Added RECOVER_ABORT_IF_CLIENTERROR recovery_option that closes the connection if client connection is broken during the request. (mturk)
update Renamed cache_timeout directive to connection_pool_timeout. (mturk)
update Added connection_pool_minsize directive. (mturk)
update Deprecate recycle_timeout directive. (mturk)
update Corrected some HTML syntax bugs in output of status worker. (rjung)
update Added the refresh=n parameter to the status worker. It will update the display every n seconds. (rjung)
update Balancer: Add attribute distance to balanced workers to express preferences between workers. (rjung)
update Balancer: Add attribute jvm_route to balanced workers to be able to use the same target in different balancers. (rjung)
update Status: Add lb_mult to status. (rjung)
update Balancer: Make different balancing strategies work in a similar way (use lb_value, use decay during global maintenance, use integer factors for weights. (rjung)
update Balancer: Improve locking. (rjung)
update Balancer: Workers start slower after recovering. (rjung)
update Balancer: Make different balancing strategies work in a similar way (use lb_value, use decay during global maintenance, use integer factors lb_mult for weights). (rjung)
update Balancer: Move recovery check to global maintenance. (rjung)
update Balancer: Add global maintenance method, that is called in only one process. (rjung)
update Extend our use of autoconf to find a 32Bit and a 64Bit unsigned type and their printf formats. (rjung)
update Logging: piped loggers for JkLogFile and Apache 1.3. (rjung)
update Logging: Add PID to log lines for each log level apart from REQUEST. (rjung)
update Logging: flush buffered logs to keep lines in correct order. Output final newline together with log message. (rjung)
update Reducing shm size. (rjung)
update Only log removing of old worker, when we actually do it. (rjung)
fix 37469: Fix shared memory close for forked childs. The shared memory will be closed by the parent process. (mturk)
fix 37332: Fix potential misuse of buffer length with snprintf functions. (mturk)
fix 38859: [CVE-2006-7197] Protect mod_jk against buggy or malicious AJP servers in the backend. Patch provided by Ruediger Pluem. (mturk)
fix 38889: Use worker map sorting depending on the path elements, to comply with Servlet spec. Patch provided by Steve Revilak. (mturk)
update 36138: Added Busyness lb method. Patch provided by Chris Lamprecht. (mturk)
fix Fix pessimistic locking mode. The patch correctly handles the burst load, by syncing the access to the shared memory data. (mturk)
fix 38806: Reclycle worker even if it is disabled. This fixes hot-standby workers in error state. (mturk)
fix 37167: Allow building with BSD-ish like make. (mturk)
fix ISAPI plugin (isapi_redirect.dll) did not provide correct request data for IIS to include in the IIS log. (markt)
Changes between 1.2.14 and 1.2.15

Native
fix Fix AJP13 Cookie2 parsing. Cookie2 was always send as Cookie. Patch provided by Andre Gebers. (mturk)
fix 35862: NSAPI plugin attempts to read freed memory and attempts to dereference a null pointer. Patch provided by Brian Kavanagh. (markt)
Changes between 1.2.13 and 1.2.14

Native
fix Fix lb for worker mpm's with cachesize set to lower number then ThreadsPerChild is. If retries is set to value larger then 3 sleep for 100 ms on each attempt. This enables to tune the connection cache, and serialize incoming connections instead returning busy if connection count is larger then cachesize. (mturk)
fix 36525: Solaris core dump. (mturk)
fix 36102: Worker actions do not persist. (mturk)
fix 35864: Status worker doesn't list workers. Patch provided by Martin Goldhahn. (mturk)
fix 35809: JkMountCopy don't work for Apache 2.0 Patch provided by Christophe Dubach. (mturk)
fix 35298: Multiple JK/ISAPI redirectors on a single IIS site are not supported Patch provided by Tim Whittington. (mturk)
Changes between 1.2.12 and 1.2.13

Native
fix 34397: Emergency was handled as Error. (jfclere)
fix 34474: // in URL were not handled correctly with Apache-1.3. (jfclere)
fix Use 64 bits int for transferred/read bytes.
update Added JkOptions +FlushPackets used to optimize memory usage when sending large data. (mturk)
update Added lock directive for load balancer that allows more acurate load balancing in case of burst load. (mturk)
update Added worker.maintain directive to allow customizing default 10 second timeout. On busy servers this value needs to be set on higher value. (mturk)
fix Fix for NetWare compiler to deal with different types between AP13 and AP2 SDKs. (fuankg)
update Emit much more legible user.dmp crash analysis output for WIN32. (wrowe)
fix 34558: Fix first failover request. (mturk)
Changes between 1.2.11 and 1.2.12

Native
update Added ForwardLocalAddress JkOptions flag for passing local instead remote address. Useful for remote addr valve. (mturk)
fixFix that worker does not get used, when stopped flag is set to true. (pero)
update Add loadbalance default worker secret attribute to the documentation (pero)
Changes between 1.2.10 and 1.2.11

Native
fixBackport SC_M_JK_STORED from JK2 for passing arbitrary methods instead failing the request. (mturk)
fixAdded missing SEARCH and ACL http methods. (mturk)
update Add worker secret attribute to the documentation (pero)
update Add a stopped flag to worker configuration. Set flag to true and the complete traffic to the worker will be stopped. Also update the Ant JkStatusUpdateTask at Tomcat 5.5.10 release. Only usefull in a replicated session cluster.(pero)
updateAdded worker maintain function that will maintain all the workers instead just the current one. This enables to recycle the connections on all workers. (mturk)
updateUse shutdown when recycling connections instead hard breaking the socket. (mturk)
updateAdd unique directives checking. The directives if unique are now overwritten instead concatenated. (mturk)
updateAllow multiple worker.list directives. (mturk)
fix 34577: For IIS log original request instead loging the request for ISAPI extension. (mturk)
fix 34558: Make sure the returned status codes are the same for ajp and lb workers. (mturk)
fix 34423: Use APR_USE_FLOCK_SERIALIZE for setting log lock on platforms like FreeBSD. Patch provided by Allan Saddi. (mturk)
fix 33843: Fix obtaining LDFLAGS that were used for building Apache HTTPD. Patch provided by Beat Kneubuehl. (mturk)
fix 34358: Enable load balancer method configuration. (glenn)
fix 34357: In some situations Apache 2 mod_jk could segfault when the JkAutoAlias directive is used. (glenn)
update Add --enable-prefork to the documentation (pero)
updateUpdate tomcat_trend.pl for new error log string formatting. (glenn)
Changes between 1.2.8 and 1.2.10

Native
updateSet default shared memory to 64K instead 1M. (mturk)
fixDo not mark the worker in error state if headers are larger then AJP13 limit. (mturk)
update On iSeries you should use the latest PTF for Apache 2.0 (which is now 2.0.52) and ad minima SI17402/SI17061 or cumulative including them. (hgomez)
update Change the xml status format to xml attribute syntax (pero)
fix 33248: Fix builds where apxs defines multiple directories for APR includes. (mturk)
fix 32696: Return 404 instead 403 when WEB-INF is requested to comply with Servlet spec. (mturk)
updateAdded ANT task for managing jkstatus. (pero)
update If socket_timeout is set, check if socket is alive before sending any request to Tomcat. (mturk)
update Added JkMountFile for Apache web servers. This file can contain uri mappings in the form (/url=worker), and is checked for updates at regular 60 second interval. (mturk)
update Added status worker for managing worker runtime data using web page. (mturk)
update Added load balancer method directive that is used for setting the algorithm used for balancing workers. Method can be either Request (default) or Traffic. (mturk)
update Added shared memory to allow dynamic configuration. Shared memory is needed only for unix platform and web servers having multiple child processes. For Apache web server two new directives has been added (JkShmFile and JkShmSize). (mturk)
update Added textupdate mode to status worker to handle remote updates from ant tasks.(pero)
fix 33562: Fix Reply_timeout when recovery_options is larger than 1. Patch provided by Takashi Satou. (mturk)
fix 33308: Fix segfaults when ForwardDirectories is enabled with Apache 1.3
Changes between 1.2.7 and 1.2.8

Native
update Allow anyone to debug and diagnose stack dumps using windbg or any other debugging tool, and (if they add the .pdb files to their installation) to make sense of dr watson logs. Patch provided by William A. Rowe (wrowe)
fix Fix in_addr_t usage by using the real struct ignoring typedef. Patch provided by William A. Rowe (wrowe)
fix Fix url rewriting by restoring the in place uri from which the jsessionid was removed. (mturk)
update Make load balancer algorithm thread safe by introducing mutex to the load balancer worker. (mturk)
fix Fix sending error pages for IIS to client by adding Content-Type header using correct api function call. (mturk)
fix 32696: Prevent IIS from crushing when web-inf url was requested. (mturk)
update Use default cachesize for servers that support discovering the number of threads per child process. (mturk).
fix Fix Apache content-length header parsing using case insensitive compare. (billbarker)
fix Fix parsing AJP headers using case insensitive compare. (mturk)
fix Use infinite socket timeout if socket_timeout is set to zero or less then zero. (mturk)
update Change balanced_workers to balance_workers but keep backward compatibility preserving the old directive. (mturk).
fix Fix ajp initialization for workers with cache_size set to zero. (mturk)
update 32317: Making mod_jk replication aware (Clustering Support). Patch provided by Rainer Jung. (mturk).
fix 31132: Core dump when JkLogFile is missing from conf. (mturk)
Changes between 1.2.6 and 1.2.7

Native
update Added new property named recover_time that can be used to change the default 60 second recover time. (mturk)
update Added custom retries for worker, so we don't depend on default setting. If set to a number grater then 3, it will sleep for 100ms on retry greater then 3 and then try again. (mturk)
update Added JkWorkerProperty directive that enables omiting workers.properties file. For example: JkWorkerProperty worker.ajp13a.port=8009. (mturk)
fix Check all JSESSIONID cookies for a valid jvmRoute. If you have multiple Tomcats with overlapping domains, then you can get multiple cookies without a defined order. This will route correctly as long as the different domains don't have any Tomcats in common. (billbarker)
update Added JkUnMount directive for negative mappings that works as opposite to JkMount directives. It is used for blocking of particular URL or content type. (mturk)
update Added wildchar match uri mappings. One can now use JkMount to map /app/*/servlet/* or /app?/*/*.jsp. (mturk)
update Rewrite the logging by adding Trace options. (mturk)
update Added socket_timeout property that sets the timeout for the socket itself. (mturk)
fix Changed socket_timeout property to recycle_timeout. This better explains what the directive actually does. (mturk)
fix Changed the load balancer algorithm. The idea behind this new scheduler is the following: lbfactor is how much we expect this worker to work, or the worker's work quota. lbstatus is how urgent this worker has to work to fulfill its quota of work. We distribute each worker's work quota to the worker, and then look which of them needs to work most urgently (biggest lbstatus). This worker is then selected for work, and its lbstatus reduced by the total work quota we distributed to all workers. Thus the sum of all lbstatus does not change.(*) If some workers are disabled, the others will still be scheduled correctly. (mturk)
fix Fix iis redirector that was figuring .properties file on each request. (mturk)
fix Start fixing 64/32 bit compatibility issues. (mturk)
Changes between 1.2.5 and 1.2.6

Native
fix Fix POST Recovery problems in LB mode. (hgomez)
add Add CPING/CPONG support to avoid problems with hang tomcats. (hgomez)
update Make POST recovery in LB configurable. (hgomez)
update Update to Apache License 2.0. (hgomez)
add For Apache 2.0, when the env var no-jk is present, mod_jk didn't handle request (declined) and as such dont forward requests to tomcats even if URL match. To be used with SetEnvIf or BrowserMatch directives for example to exclude some URL/URI or Browser (hgomez).
fix Add a fix for iSeries (AS/400) which use XOPEN/Unix98 APIs and need sa_len to be set when calling connect(), it will resolve the error EINVAL in jk_connect. (hgomez)
Changes between 1.2.4 and 1.2.5

Native
fix Fix a thread safe bug when mapping URI's. (billbarker)
fix Fix a thread safe bug when resolving worker host name when using mod_jk with Apache 2 and the worker MPM. (hgomez)
fix Remove an unnecessary error message when connections to all load balanced workers fail. (glenn)
fix When mod_jk cannot connect to a worker include the name of the worker in the error message. This is especially helpful when you are using load balanced workers. (glenn)
fix Fix problem with mod_jk.log getting opened multiple times for Apache 2. Only one mod_jk.log can be configured. (glenn)
fix Fix Apache 2 connector so that DirectoryIndex works for an index.jsp page if JkOptions ForwardDirectories was configured. (hgomez)
fix Fix exposure of JSP source if a //path/to.jsp URL was requested in Apache 1.3 and Apache 2.0 connector. (billbarker)
Changes between 1.2.3 and 1.2.4

Native
add Fix use of libtool for Apache mod_jk builds with more recent versions of Apache 2. (jfclere)
fix Use reentrant version of strtok() for web server's which use threads. This fixes a thread safe bug under Apache 2 and the worker MPM. (glenn)
fix Fix the Apache 2 mod_jk hook priority so that mod_jk works well with both mod_alias and mod_dir. (glenn)
Changes between 1.2.2 and 1.2.3

Native
add Add the ability to configure JkLog to pipe its log output to an executable such as Apache rotatelogs or cronolog. Apache 2.0 only. (glenn)
add Add JkAutoAlias to Apache 2.0. (glenn)
update Apache 2/1.3, if Tomcat returns an error but not content, let Apache handle processing the error returned by Tomcat. (glenn)
add Added the load balancer sticky_session property. If set to 0 requests with servlet SESSION ID's can be routed to any Tomcat worker. Default is 1, sessions are sticky. (glenn)
fix Cleaned up detection and reporting of aborted client connections. This cleanup also makes sure that mod_jk does not pass any requests on to Tomcat if the remote client aborted its connection. (glenn)
fix Fixed a bug in Apache 2.0 which caused a POST request forwarded to Tomcat to fail if it generated SSI directives which were post processed by mod_include. (glenn)
fix Fixed a bug in JkRequestLogFormat when printing the request URI that could cause a URI with hex escapes sequences to be formatted wrong. (glenn)
Changes between 1.2.1 and 1.2.2

Native
update tomcat_trend.pl updated script to support changed logging of aborted requests. (glenn)
fix jk set correctly the content-type in Apache 2.0, making it ready to works with mod_deflate and AddOutputFilterByType. (hgomez)
fix jk will check result of get_endpoint and handle a failure. This call can fail if the allocation for the endpoint fails because of low memory conditions causing a dereference of NULL when we try and access the endpoint. (mmanders)
Changes between 1.2.0 and 1.2.1

Native
fix 14282: Don't send initial chunk for chunked encoding. (costin)
add Add perl scripts for analyzing mod_jk logs and generating graphs/reports. (glenn)
fix Make JK honor the CanonicalHost directive. (hgomez)
fix Log cleanup. (costin)
fix Fix typos in jk xdocs/docs. (hgomez)
fix Add JkRequestLogFormat to Apache 2.0. (hgomez)
fix Final patches to make JK iSeries compliant. (hgomez)
JK 2

JK2 has been put in maintainer mode and no further development will take place. The reason for shutting down JK2 development was the lack of developers interest. Other reason was lack of users interest in adopting JK2, caused by configuration complexity when compared to JK.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/miscellaneous/jkstatustasks.html0000644000000000000020000003165312555256556023742 0ustar rootbinThe Apache Tomcat Connectors - Miscellaneous Documentation - Status Worker Ant Tasks
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Miscellaneous Documentation

Status Worker Ant Tasks

Printer Friendly Version
print-friendly
version
Introduction

Since version 1.2.19 the JK release contains additional ant tasks. They can be used to manage the JK web server plugins via the special status worker.

Manage JK with remote Ant Tasks
Simple antlib integration

<?xml version="1.0" encoding="UTF-8"?>

<project name="modjk-status" 
         xmlns:jk="urn:org-apache-jk-status"
         default="status" basedir=".">

	<property name="profile" value=""/>
	<property file="jkstatus${profile}.properties"/>
	<property file="jkstatus.properties.default"/>

    <path id="jkstatus.classpath">
      <fileset dir="${catalina.home}/bin">
          <include name="commons-logging-api-*.jar"/>
      </fileset>
      <pathelement location="${catalina.home}/server/lib/catalina-ant.jar"/>
      <pathelement location="../dist/tomcat-jkstatus-ant.jar"/>
      <pathelement location="${catalina.home}/server/lib/tomcat-util.jar"/>
    </path>

    <typedef resource="org/apache/jk/status/antlib.xml"       
           uri="urn:org-apache-jk-status" classpathref="jkstatus.classpath"/> 
           
    <target name="status" >       
 	    <jk:status url="${jkstatus.url}" 
	                username="${jkstatus.username}"
	                password="${jkstatus.password}"
	                resultproperty="worker"
	      	        echo="off"
	                failOnError="off"/>
	    <echoproperties prefix="worker" />
    </target>
</project>    

Test Result

[echoproperties] #Ant properties
[echoproperties] #Sun Dec 10 20:40:21 CET 2006
[echoproperties] worker.node01.lbmult=1
[echoproperties] worker.loadbalancer.lock=Optimistic
[echoproperties] worker.node02.transferred=0
[echoproperties] worker.loadbalancer.sticky_session=false
[echoproperties] worker.node01.distance=0
[echoproperties] worker.node01.client_errors=0
[echoproperties] worker.node02.lbmult=1
[echoproperties] worker.node01.port=7309
[echoproperties] worker.node01.elected=0
[echoproperties] worker.loadbalancer.good=2
[echoproperties] worker.loadbalancer.method=Sessions
[echoproperties] worker.server.port=2090
[echoproperties] worker.loadbalancer.map.2.type=Wildchar
[echoproperties] worker.node02.route=node02
[echoproperties] worker.node01.route=node01
[echoproperties] worker.node01.lbvalue=0
[echoproperties] worker.node01.lbfactor=1
[echoproperties] worker.node01.max_busy=0
[echoproperties] worker.node01.busy=0
[echoproperties] worker.node01.redirect=
[echoproperties] worker.node02.distance=0
[echoproperties] worker.loadbalancer.name=loadbalancer
[echoproperties] worker.loadbalancer.sticky_session_force=false
[echoproperties] worker.node02.state=N/A
[echoproperties] worker.node01.state=N/A
[echoproperties] worker.node01.transferred=0
[echoproperties] worker.loadbalancer.map.length=2
[echoproperties] worker.node01.type=ajp13
[echoproperties] worker.node01.address=127.0.0.1\:7309
[echoproperties] worker.result.type=OK
[echoproperties] worker.loadbalancer.member_count=2
[echoproperties] worker.loadbalancer.map_count=2
[echoproperties] worker.loadbalancer.mtime_to_maintenance_min=12
[echoproperties] worker.loadbalancer.mtime_to_maintenance_max=75
[echoproperties] worker.node02.lbfactor=1
[echoproperties] worker.node02.max_busy=0
[echoproperties] worker.jk_version=mod_jk/1.2.21-dev
[echoproperties] worker.loadbalancer.bad=0
[echoproperties] worker.node02.redirect=
[echoproperties] worker.node01.host=localhost
[echoproperties] worker.node02.activation=ACT
[echoproperties] worker.loadbalancer.map.1.source=JkMount
[echoproperties] worker.loadbalancer.retries=2
[echoproperties] worker.node02.elected=0
[echoproperties] worker.loadbalancer.map.2.source=JkMount
[echoproperties] worker.node02.port=7409
[echoproperties] worker.loadbalancer.length=2
[echoproperties] worker.node02.lbvalue=0
[echoproperties] worker.loadbalancer.degraded=0
[echoproperties] worker.loadbalancer.map.1.type=Wildchar
[echoproperties] worker.loadbalancer.map.2.uri=/myapps*
[echoproperties] worker.node02.client_errors=0
[echoproperties] worker.length=1
[echoproperties] worker.node01.domain=d20
[echoproperties] worker.loadbalancer.recover_time=60
[echoproperties] worker.server.name=localhost
[echoproperties] worker.node02.domain=
[echoproperties] worker.result.message=Action finished
[echoproperties] worker.node02.busy=0
[echoproperties] worker.node01.readed=0
[echoproperties] worker.node01.errors=0
[echoproperties] worker.node02.address=127.0.0.1\:7409
[echoproperties] worker.node02.readed=0
[echoproperties] worker.loadbalancer.busy=0
[echoproperties] worker.web_server=Apache/2.0.59 (Unix) mod_jk/1.2.21-dev
[echoproperties] worker.node02.errors=0
[echoproperties] worker.node02.type=ajp13
[echoproperties] worker.loadbalancer.map.1.uri=/ClusterTest*
[echoproperties] worker.node01.activation=ACT
[echoproperties] worker.loadbalancer.max_busy=0
[echoproperties] worker.loadbalancer.type=lb
[echoproperties] worker.node02.host=localhost

Update Load Balancer

     <target name="updatelb" >       
 	    <jk:updateloadbalancer url="${jkstatus.url}" 
	                username="${jkstatus.username}"
	                password="${jkstatus.password}"
	                loadbalancer="loadbalancer"
	                method="Busyness"
	                retries="2"
	                recoverWaitTime="60"
	                lock="Optimistic"
	                forceStickySession="false"
	                stickySession="false"/>
     </target>

Update Worker

     <target name="updatew" >       
 	    <jk:updateworker url="${jkstatus.url}" 
	                username="${jkstatus.username}"
	                password="${jkstatus.password}"
	                loadbalancer="loadbalancer"
	      	        worker="node01"
	                lbfactor="2"
	                activation="Active"
	                redirect=""
	                domain=""
	                route="node01"
	                distance="0"/>
     </target>

Reset Worker

     <target name="reset" >       
 	    <jk:reset url="${jkstatus.url}" 
	                username="${jkstatus.username}"
	                password="${jkstatus.password}"
	                loadbalancer="loadbalancer"
	      	        worker="node01"
	                />
     </target>


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/miscellaneous/printer/0000755000000000000020000000000012555256556021611 5ustar rootbintomcat-connectors-1.2.41-src/docs/miscellaneous/printer/doccontrib.html0000644000000000000020000004316612555256556024637 0ustar rootbinThe Apache Tomcat Connectors - Miscellaneous Documentation - How to Contribute to the Documentation
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Miscellaneous Documentation

How to Contribute to the Documentation

Introduction

This document describes how you can easily contribute to the documentation. I'm going to try to make it easy for everyone to help out with the documentation of Tomcat, more specifically the documentation for the connectors. This is written from a windows user perspective as I believe they will most benefit from it. For people using Unix it should be easy for them to apply these steps. Just substitute Unix syntax where needed.

The documentation is produced using xml with xsl style sheets. This effectivly seperates the content of the documents from the style, so all that contributers need to worry about the content. It is much easier to use than html.

It's all really quite simple. Here is what you will need:

  • A recent version of Ant
  • The source code for the connectors from subversion
  • Any ascii text editor

Getting Started Step by Step

After you get these tools they are simple to set up.

STEP 1. Get Ant

Install Ant. The only advice I have is to choose a simple installation path. Now set an environment variable for ANT_HOME, and then add the location of the Ant/bin directory to your PATH variable. Consult your Operating system documentation for information on how to do this. When you are finished verify that you can run ant from the command line.

Ant is used to build the documentation, among other things, and it must be able to see a file called build.xml. This file is located in the xdocs directory. In the build.xml file there is a target named all that will be used to build the docs.

STEP 2. Get the sources

Get the sources for tomcat-connectors from the subversion repository. If you'll be editing from a windows platform you will need a windows subversion client. There are several available. I like turtoiseSVN. Unix users should install the subversion client of their choice, if they don't already have one.

You are ready to download the sources now. Change directory to the location where you want your repository to be. For simplicity we will call this your SVN_HOME. Mine is located in C:\build.

Run the following command to checkout the sources for the first time. You should only need to do this once.


C:\build\>svn checkout http://svn.apache.org/repos/asf/tomcat/jk/trunk/ tomcat-connectors

You should now be watching all the downloads come in. Now that you have the sources on your machine the hard part is over. From now on, to update your sources all you have to do is cd into any directory in your repository and run the svn update command.

To update your xdocs directory simply cd into the xdocs directory and:
C:\build\tomcat-connectors\>cd xdocs
C:\build\tomcat-connectors\xdocs\>svn update

STEP 3. Test your build environment

Open a command prompt window and cd to the directory where you downloaded the source. Now cd into the xdocs directory so that Ant can see the build.xml file. Then from a command prompt, run the following:


C:\build\tomcat-connectors>cd xdocs
C:\build\tomcat-connectors\xdocs>ant all

.

You should see the ant compiler messages scrolling by rapidly and then stop with the following:

[style] Transforming into C:\build\tomcat-connectors\build\docs\news\printer>
[style] Processing C:\build\tomcat-connectors\xdocs\news\20041100.xml to
C:\build\tomcat-connectors\build\docs\news/20041100.html
[style] Loading stylesheet C:\build\tomcat-connectors\xdocs\style.xsl
[style] Processing C:\build\tomcat-connectors\xdocs\news\20050101.xml to
C:\build\tomcat-connectors\build\docs\news/20050101.html
[style] Processing C:\build\tomcat-connectors\xdocs\news\20060101.xml to
C:\build\tomcat-connectors\build\docs\news/20060101.html
[style] Transforming into C:\build\tomcat-connectors\build\docs>
[style] Processing C:\build\tomcat-connectors\xdocs\index.xml to
C:\build\tomcat-connectors\build\docs\index.html
[style] Loading stylesheet C:\build\tomcat-connectors\xdocs\style.xsl

BUILD SUCCESSFUL
Total time: 10 seconds
C:\build\tomcat-connectors>

All the xml files present in the xdocs directory structure were transformed to html and copied to the SVN_HOME\tomcat-connectors\build\docs directory. Open one of the html files in your browser and see how it looks.

STEP 4. The editing process.

I find it easier to use two windows while doing my updates. One I call my build window. I keep this one in the SVN_HOME\tomcat-connectors\xdocs directory and I only run two commands in this window:


First I run
ant clean
Then I run
ant all

My second window I call my edit window and I keep that one in the SVN_HOME\tomcat-connectors\xdocs directory where I'm doing my edits, diffs and svn updates.

Before you start editing you should always update your local repository to prevent conflicts.

You only need to update the xdocs directory
C:\build\tomcat-connectors>cd xdocs
C:\build\tomcat-connectors\xdocs>
C:\build\tomcat-connectors\xdocs>svn update

Now that your repository is up to date you can begin editing. Find something in the documentation to edit. When you find something remember the name of the file. In your edit window find and edit the xml source file with the same name. After you are done return to the build window, and in the SVN_HOME\tomcat-connectors\xdocs directory run:


C:\build\tomcat-connectors\xdocs> ant clean

This will delete all the previous html files and make the area ready for updated material. Now to make fresh documents that incorporate your changes run:


C:\build\tomcat-connectors\xdocs>ant all

Use your browser to view the edits you just made, they will be in the SVN_HOME\tomcat-connectors\build\docs sub-tree. If it looks good and is ready to go, all that is left to do is to create a patch and submit it.

STEP 5. Creating a patch and submitting it.

From your edit window cd into the directory that contains the xml file you are working on, and run the svn update command. For example, to produce a diff of the index.xml file and call it patch.txt, you would cd into the directory containing the index.xml file and:

C:\build\tomcat-connectors\xdocs\>svn diff index.xml > patch.txt.

Now that you have your patch you are ready to send it in.

Patches to the documentation are handled just like a bug report. You should submit your patches to http://issues.apache.org/bugzilla/ and include a good one line subject. If this is your first time to use the bug database then you should read http://issues.apach e.org/bugzilla/bugwritinghelp.html. You will need to create a user account. At the web site paste your patch into the web form and don't forget to describe what it is your patch is for. Sooner or later a someone with commit privileges will review your suggestion.

Subversion Basics

After you have checked out the sources the first time it is much easier to use subversion. You can cd into any directory of the repository and run svn update to get the latest sources for that directory. For editing purposes you should always update your repository before you start editing to reduce conflicts.

You will need to run svn diff to generate patches for submission. Again cd into the directory containing the file you are editing and run svn diff name_of_the_file_you_edited > patch.txt to generate a patch for submission.

Pay attention to the terminal window during the update.

Lines begining with a A indicate files that have been added.

Lines begining with a D indicate files that have been deleted.

Lines begining with a U mean the local copy was patched to update it to the current version in the master repository.

Lines begining with a G mean your local copy is different from the master copy, and the changes were successfully merged into your copy.

Lines begining with a C mean there was a conflict in merging the changes and you need to review the file and merge the changes manually. Search for >>>> and merge the changes.

Lines begining with a ? indicate files that reside on your local system which are not part of the repository. You will normally see this when you are creating new files for submission.

Updating Web site

Only Committers are able to update the web site (http://tomcat.apache.org/connectors-doc/). To do it:

  • Connect to people.apache.org.
  • umask 002
  • Copy the changed files to /www/tomcat.apache.org/connectors-doc/.
  • or use ant from a checkout tomcat/jk/trunk/xdocs repository:
    ant -Dbuild.dir=/www/tomcat.apache.org -Ddist.name=connectors-doc
  • The changes need around 4 hours to be synced to tomcat.apache.org.

Guides and Resources

A little help to get you started if you need it


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/miscellaneous/printer/changelog.html0000644000000000000020000054731112555256556024441 0ustar rootbinThe Apache Tomcat Connectors - Miscellaneous Documentation - Changelog
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Miscellaneous Documentation

Changelog

Preface

This is the Changelog for Apache Tomcat Connectors. This changelog does not contain all updates and fixes to the Tomcat connectors (yet). It should contain fixes made only after November 10th 2004, when the new documentation project for JK was started.

Changes between 1.2.40 and 1.2.41

Native
fix AJP, LB: Reduce lock contention during maintenance function. This was observable when using a big number of AJP13 and LB workers, especially in combination with the Apache httpd prefork MPM. (rjung)
fix 57060: Allow building from outside of source tree. Patch contributed by Petr Sumbera. (rjung)
fix 56703: Status: Fix inflated counter for current number of backend connections especially when a connection timeout occurred on the backend. (rjung)
fix 56661: Fix Servlet API getLocalAddr(). Works for Tomcat 6.0.42, 7.0.55 and 8.0.11 and Apache and ISAPI plugins. (rjung)
update Status: Log old and new values when changing worker attributes. (rjung)
fix 56667: Status: Fix log message when changing activation state of all members. (rjung)
fix 56565: Fix IPV6 address resolve on non-dual network stacks. (mturk)
fix 50511: Reduce log level for "OPTIONS *" requests from warning to debug. (rjung)
fix Apache: Copy log notes instead of using references to prevent access to memory from closed pool. (rjung)
add Add option to control handling of multiple adjacent slashes in mount and unmount. New default is collapsing the slashes only in unmount. Configuration is done via new JkOption for Apache ("CollapseSlashesAll", "CollapseSlashesNone" or "CollapseSlashesUnmount") and via property "collapse_slashes" for IIS (values "all", "none", "unmount"). This is the fix for CVE-2014-8111. (rjung)
add Add more checks for shared memory allocation. (rjung)
add 56869: Status: Add maximum number of open backend connections to status worker. Patch contributed by Martin Knoblauch. (rjung)
add 56770: AJP: Add worker name to all log messages. Patch contributed by Martin Knoblauch. (rjung)
fix 50186: Docs: Clarify relation between "connection_pool_timeout" and "keepAliveTimeout" or "connectionTimeout" in the Tomcat AJP connector configuration. (rjung)
fix 52334: LB: Calculate worker recovery time based on last recovery attempt time instead of original error time after the first recovery attempt. (rjung)
fix 54596 part 1: IIS: Fix missing last character when parsing relative file names with no ".." directory components from configuration. (rjung)
fix 54596 part 2: IIS: Fix using relative file names in config with ".." path segments that go up the directory hierarchy higher than the starting point of the relative file name. (rjung)
fix Status: Add logging if status worker output was dropped due to insufficient buffer size. (rjung)
fix Reduce log buffer from 8KB to 1KB. Add logging in case of failed logging and add trailing "..." to lines which were likely truncated. (rjung)
update Replace fixed allocation of 32 entries for fail_on_status by dynamic allocation. (rjung)
add Enforce implementation restriction on maximal length "60" of worker attributes "name", "host", "route", "domain", "redirect", "session_cookie", "session_path" and "set_session_cookie". Checks were added to configuration file processing and configuration updates via the status worker. (rjung)
add 52483: Apache: Add debug logging for result of JkOptions configuration processing. (rjung)
fix 54177: Status: Use numeric time stamps instead of textual ones to avoid non-well-formed XML output. Textual timestamps are formatted according to locale settings and reencoding them to UTF-8 would be cumbersome. (rjung)
fix 56618: Status: Use percent decoding when reading query string parameters. For example this fixes editing IPv6 addresses via the status worker if the client encodes ":" as "%3A". Patch contributed by Christopher Schultz. (rjung)
fix 56452: Fix crash in debug logging for IPv6 adresses. Patch contributed by Christopher Schultz. (rjung)
fix 34526: Apache: Improve compatibility with mod_deflate request body inflation. An automatic detection of mod_deflate inflation is not implemented. Use the new Apache environment variable JK_IGNORE_CL instead, to let mod_jk ignore an existing Content-Length request header. (rjung)
update 44454: LB: Add warning to docs about problems with "busyness" load balancing method. (rjung)
fix 44454: Improve busy counter by using atomics. (rjung)
fix 56703: Status: Improve connected counter. Use atomics and for mod_jk (Apache) currectly count down connections closed by child processes that are stopped. (rjung)
fix 44571: Ensure that we return with status 503 if we can not get and endpoint for a worker. (rjung)
fix Apache: Improve log handling during graceful or normal restart. (rjung)
fix Don't update last access time of worker connections during optional checking of idle connections using CPing. Updating the time stamp breaks closing idle connections. (rjung)
fix Adjust linger parameters used during connection shutdown. (rjung)
fix Fix annoying redefine warnings for the autoconf PACKAGE defines during configure based builds. (rjung)
fix Status: Use multi-line table headers and fix invalid xml output. (rjung)
fix 44571: Implement an optional limit on concurrent requests allowed for a worker (attribute "busy_limit"). Original patch contributed by zealot0630 at gmail dot com. (rjung)
fix Correct log message "all endpoints are disconnected" to "no usable connection found, will create a new one". Tone done from info log level to debug for the common case. (rjung)
add 57536: AJP: Allow to configure connection source address. This should only be used on multi-homed hosts. The feature is experimental. (rjung)
add 57540: AJP: Forward name of SSL protocol used for handling the request (SSLv3, TLSv1, TLSv1.1, TLSv1.2). (rjung)
Changes between 1.2.39 and 1.2.40

Native
fix Fix forwarding of chunked requests, which is broken in version 1.2.39. (rjung)
fix 56352: Fix regression in memory release. (mturk)
fix Fix status worker display of worker IP address after name or port was changed. (rjung)
update 56297: Improve key hash function. Copied from APR. (rjung)
fix 55683: Remove quotes from quoted session cookies. (rjung)
fix 53542: ISAPI: Fix grammar in 503 error page. (rjung)
fix 55696: Crash on Mac OS X 10.9 during config parsing. (rjung)
Changes between 1.2.37 and 1.2.39

Native
update Deprecate nt_service from Apache Tomcat Connectors. (mturk)
fix 56133: Fix possible crash when a request fails during request body transfer to the back end and reply_timeout was set. Patch contributed by Hiroto Shimizu. (rjung)
fix Fix status worker not updating parameters for all members. (mturk)
fix 55853: HTTPD: Use the correct API for setting Content-Length. Patch contributed by areese yahoo-inc.com. (rjung)
add Add IPV6 support for connection to webserver. New directive prefer_ipv6 has been added to control the hostname resolution and preserve backward compatibility. (mturk)
add Add --disable-sock-cloexec to configure to disable use of SOCK_CLOEXEC (using FD_CLOEXEC + fnctl instead) so built modules will work with Linux kernels prior to 2.6.27. (timw)
update Clean up config file parsing. Worker names are now restricted to 60 bytes. (rjung)
update Allow to set a stickyness cookie in case a web framework breaks Tomcat's adding of the routing ID to the end of the JSESSIONID cookie. (rjung)
update Use max_packet_size also for request body forwarding. (rjung)
update Apache 2.4: By default forward logical client address as provided by mod_remoteip. When setting JkOptions ForwardPhysicalAddress mod_jk will instead forward the physical peer address. (rjung)
update Minor documentation improvements. (rjung)
Changes between 1.2.36 and 1.2.37

Native
fix Fix regression which can crash webserver in case worker is defined both as member of load balancer and as standalone worker. (mturk)
fix Fix core if debug log level is specified and there is no session identifier present. (mturk)
Changes between 1.2.35 and 1.2.36

Native
fix Use named shared memory objects so that we preserve runtime configured data instead of resetting on each child creation. (mturk)
fix Fix dead-lock caused by not releasing mutex on close. (mturk)
fix Fix compilation of mod_jk for HTTPD 1.3. (rjung)
fix 46893: HTTPD 1.3: Apply fix to HTTPD 1.3. It was fixed for HTTPD 2.x already in version 1.2.30. (rjung)
update HTTPD 1.3: Allow to set path parameter used when doing JkStripSession. This was available for HTTPD 2.x already since mod_jk 1.2.27. (rjung)
Changes between 1.2.33 and 1.2.35

Native
fix HTTPD: Fix crash on unknown worker names. (mturk)
fix IIS: Fix crash on worker process recycle. (mturk)
fix 52659: IIS: Fix shared memory corruption. (mturk)
fix 52921: HTTPD: Fix crash in uri mapping. (mturk)
Changes between 1.2.32 and 1.2.33

Native
fix 52793: AJP: Fix default value of forwarded worker activation state. Contributed by Yoshihito Fukuyama. (rjung)
fix HTTPD: Improve support for HTTPD 2.4 by using client_* instead of remote_* variables. (rjung)
fix 52564: Fix building with format checking gcc security hardening cflags. Contributed by Tony Mancill. (rjung)
fix 52567: Balancer member in recovery state can switch back into error state if it is idle. (rjung)
update Log error if unable to load URI workermap file, and improve logging of unreadable worker files on IIS. (timw)
update Remove deprecated JNI worker and build dependency on Java SDK. (mturk)
fix 51253: Forward WWW-Authenticate header when using server generated error pages (rjung, mturk).
update 46406: IIS: Support relative paths in configuration. The paths are presumed to be relative from isapi_redirect.dll. (mturk)
fix 50233: Do not use hard limit on uri size (mturk).
update IIS: Use Windows Server 2003 SP1, Windows XP SP2 as minimal version supported. (mturk)
fix 47038: Fix compiler warning when using --enable-flock for configure. (rjung)
add 51326: URI Map: Add "session_cookie" and "session_path" rule extensions. Contributed by Eiji Takahashi. (rjung)
update 51333: IIS: Document configuration requirement for 64 Bit environment. (rjung)
add 51743: HTTPD: Support rule extensions when defining the request worker with an environment variable (e.g. JK_WORKER_NAME). (rjung)
fix 51769: IIS: Allow URIs which contain "META-INF" or "WEB-INF" as long as they are not path components of the URI. (rjung)
fix 52056: HTTPD: JK request log does not always log correct response status. Fixed by refactoring JK request log to use the standard request log hook. (rjung)
add HTTPD: Allow to choose a sticky worker using the environment variable JK_ROUTE. This can be used if sessions and routes are send with the request in a non-standard way. (rjung)
add URI Map: Add "sticky_ignore" extension attributes to uri worker map. It allows to disable stickyness for individual mounts. (rjung)
add HTTPD: Allow dynamic disabling of stickyness using the environment variable JK_STICKY_IGNORE. This can be useful to break cookie stickyness for non-sticky requests like login forms. (rjung)
add LB: New balancing method "Next" to distribute sessions in a round-robin way. (rjung)
add LB: Add counter for created sessions to status worker and HTTPD notes. It actually counts the number of requests that do not carry a session id. (rjung)
add URI Map: Add "stateless" extension attributes to uri worker map. This can improve session load balancing. (rjung)
add HTTPD: Allow dynamic switching of requests to "stateless" using the environment variable JK_STATELESS. (rjung)
update AJP: Improve logging when request does not fix into an AJP packet. (rjung)
Changes between 1.2.31 and 1.2.32

Native
fix 51417: Fix worker busy detection by querying the worker endpoint. Abandoned connections can leave a worker in busy state without decrementing busy counter. (mturk)
fix 50339: Fix whitespace trimming when parsing attribute lists. (rjung)
fix 41263: Support Servlet API getRemotePort(). Works for Tomcat 5.5.28, 6.0.20 and 7.0.0 and Apache and ISAPI plugins. (rjung)
fix 41923: AJP: Close AJP connection to Tomcat on client write error when recovery_options 4 is specified, aborting the response write on the Tomcat side. (timw)
update AJP: Cap the lingering bytes that will be read when shutting down an AJP socket at 32k to prevent CPU spikes in the web server when a client aborts on a large response body. Also reduce total linger time to 2s. (timw)
fix 50839: AJP: Fix 30sec CPU spike due to incorrect counting of lingering bytes causing a busy loop when a client aborts connection during a response write. Fixes regression in 1.2.31. (timw)
add LB: Forward worker activation state as request attribute "JK_LB_ACTIVATION". Possible values are "ACT" (active), "DIS" (disabled) and "STP" (stopped). (rjung)
fix HTTPD: Forward WWW-Authenticate from backend when status is 401 and server generated error pages are used. (rjung)
fix 50363: IIS: Prevent chunk encoding of empty message bodies for 204, 205 and 304 responses. (timw)
fix 50975: IIS: Fix hanging of Transfer-Encoding: chunked requests when Content-Length header is present in request as well. Also addresses situation where IIS appears to create a Content-Length header for a small chunk encoded request when none was present in the original request. (timw)
fix 47679: IIS: stop truncation of request headers when ISAPI redirector used as an extension without the corresponding filter installed. (timw)
fix NSAPI: Use lower case header names for responses. Otherwise the web server might add chunked transfer encoding header in addition to our content length header.
update Docs: Improve load balancer documentation. (rjung)
Changes between 1.2.30 and 1.2.31

Native
fix 49413: AJP13: Drop flush packets send by the backend after the response has been finished. (rjung)
update AJP: Log the local and remote socket address. (mturk)
update Watchdog: Move the maintain workers outside the critical section allowing other threads to use the connection pool during maintenance. (mturk)
update Common: Add svn revision to init log message. (rjung)
fix Common: Don't destroy errno during trace logging. (rjung)
update Apache: Add support for Apache 2.3/2.4. (rjung)
update Apache: Added version number resource for mod_jk.so on Windows. (timw)
update 48501: IIS: Added rotatelogs style log rotation to ISAPI Redirector. (timw)
fix 38895: IIS: Use RAW headers instead of CGI headers by default to prevent conversion of underscores '_' to hyphens '-' in header names. Old behaviour can be enabled by defining USE_CGI_HEADERS. (timw)
fix 49511: IIS: Do not override IIS log information when subsequent requests on a keep-alive connection are not mapped into the ISAPI Redirector. (timw)
fix Docs: Document SSLOptions needed for SSL information forwarding. (rjung)
update Docs: Grammar and style improvements and clarification about serving static content by IIS. Patch provided by André Warnier. (rjung)
fix Docs: Update subversion paths used in docs. (rjung)
Changes between 1.2.28 and 1.2.30

Native
update Apache: Improve compatibility with Apache 2.3. (rjung)
fix 46632: Apache: Do not register child cleanup for our pools. (mturk)
fix 46893: Apache: Log warning only if JkShmSize was actually set in the configuration. (mturk)
update IIS: Include optional chunking support. Off by default. (mturk)
fix 48763: IIS: Do not send Content-Length when using chunked encoding or length larger 4GB. (mturk)
fix 48223: IIS: Propagate correct backend error code to IIS. (rjung)
fix 47867: IIS: crash during startup, when compiled with VS2008 and workers.properties contains unsupported properties. Patch provided by Indrek Juhani (rjung)
fix 47628: IIS: Fix deadlock when restarting the Application Pool caused by not releasing the critical section lock. Patch provided by Bret Prucha. (mturk)
fix IIS/NSAPI: Correct log file flushing after each line. (mturk)
add NSAPI: Add Microsoft Visual C++ Makefile. (mturk)
update AJP: Improve socket shutdown handling. (mturk)
update AJP: Ensure we never reuse a non reusable socket. (mturk)
update AJP: Tolerate a single excess packet when waiting for cpong. (mturk)
update AJP: Check protocol correctness more strictly. (mturk)
update 48410: AJP: Use poll instead select so we can work with more then 1024 sockets. (mturk)
fix 46503: AJP/Status: Garbage data in worker domain and route. (mturk)
fix 48276: AJP: When worker contact cannot be resolved mark the worker as disabled instead failing to start the server. (mturk)
fix 48169: AJP: Improve CGI interoperability by closing all sockets during EXEC. (mturk)
add Status: Add number of open backend connections to status worker. This feature is experimental, the displayed value might not be accurate. (mturk)
update 47224: Status: When address gets changed invalidate all opened sockets in the endpoint cache. This will cause new backend connections to get opened using new address. (mturk)
fix 48305: Status: Do not show "secret" property when doing dump. (mturk)
fix 45610: Status: Don't accept requests with empty value for sub worker parameter. (rjung)
fix 45610: Status: Fix erroneous unsetting of sticky_session and sticky_session_force when updating other load balancer attributes via the status worker. (rjung)
fix 47222: Status: Add ping_timeout to the shared memory and allow dynamic configuration. (mturk)
fix Status: Remove duplicate "errors" line in property view of AJP13 workers that are part of a load balancer. (rjung)
fix LB: Fix route logging. (rjung)
update Logging: Automatically detect size of thread id for logging. (rjung)
update Logging: Add optional log file locking for Windows when defining JK_LOG_LOCKING. (mturk)
update Configuration: Update example configuration. (rjung)
update Docs: Update information about tools needed to create a release. (rjung)
fix 47983: Docs: Fix typo in example config which breaks startup. (rjung)
update Build: Force copy of automake files. (rjung)
update Build: Tomcat code repository structure cleanup reflected in documentation and build script. (rjung, mturk)
Changes between 1.2.27 and 1.2.28

Native
add Apache: Add more environment variables to overwrite request information. Useful in case a proxy is in front of Apache and sends us original request information e.g. via custom headers. (rjung)
update Apache: No longer preallocate entries for JK request log. (rjung)
fix 46352: Apache: Fix crash when using SetHandler jakarta-servlet in VHost without any JkMount. Crash due to incorrect initialization of mount extensions. (rjung)
fix Apache: JkWatchdogInterval had wrong interval calculation causing a 10 times higher watchdog interval then configured. (mturk)
fix Apache: Activate forwarding of SSL key size by default. (rjung)
fix 46169: Apache 1.3: Backport use_server_errors mount extension. (rjung)
fix 46763: Apache 2.0: Survive the log mutex during graceful restart. Patch provided by Eiji Takahashi. (mturk)
fix 46416: Apache 2.0 on Windows: Include mstcipip.h even if the apr doesn't include it. (mturk)
update IIS: Update uriworkermap.properties file on a regular interval. This requires both worker_mount_reload and watchdog_interval to be defined. (mturk)
update IIS: Remove obsolete entries from registry file. (mturk)
fix 46579: IIS: Use local environment table instead environment variables for setting the JKISAPI_PATH and JKISAPI_NAME. (mturk)
update LB: Add new property error_escalation_time to fine tune escalation of local errors to global errors. (rjung)
update LB: If the sticky session affinity mark contains a dot, treat the part before the dot as the domain name. This allows to have full node session affinity with domain failover. (mturk)
fix LB: make forced recovery work with local error states. (rjung)
fix LB: Only update error state and error time, if we actually have a new state. (rjung)
fix LB: Set global worker state to error when we reach max_reply_timeouts, or fail_on_status triggered hard error. (rjung)
update AJP: Add a new error type JK_AJP_PROTOCOL_ERROR. (mturk)
update AJP: Allow worker ports lower or equal to 1024. (rjung)
update AJP: Improve some AJP error log messages. (mturk)
update Status: Allow changing worker address and port of AJP workers. The address is resolved on next request for that worker. (mturk)
update Status: Allow update actions to show error messages in the result page. (rjung)
update Status: Refactor update actions. (rjung)
update Status: Do not redirect to the show or list page, if an error occured during an action. (rjung)
update Status: Include error time in display. (rjung)
update Status: Remove redundant port information from worker display. Rename address column and remove its explanation from the legend. (rjung)
update Status: Optimize forced uriworkermap.properties reload. (mturk)
fix Status: Fix crash in text display. (rjung)
fix Status: Show - Edit - Show always ends in single lb member show, even when started from all members lb show. (rjung)
fix Status: Wildcards in sub worker names were broken for update actions. (rjung)
fix Status: Add use_server_errors to map display. (rjung)
update SHM: Move locking into the data pull and push methods. (rjung)
update JNI: Deprecate JNI workers. (rjung)
fix Netware: Missing define for MAX_PATH. Patch by Guenter Knauf. (rjung)
update Docs: Add a new HowTo page about reverse proxies. (rjung)
update Docs: Add an explanation of local error states to the timeouts documentation. (rjung)
update Docs: Clarify relation between socket_timeout and socket_connect_timeout. (rjung)
update Docs: Clarify IIS URL rewrite feature. (rjung)
fix 46834,46734: Docs: Fix a couple of missing or broken links. (markt,rjung)
fix Docs: Add 2008 news to main page and menues. (mturk, rjung)
Changes between 1.2.26 and 1.2.27

Native
fix 46109: Decay reply_timeouts even when lb method is busyness. Also reset reply_timeouts during forced recovery. (rjung)
update AJP13: Recycle connection if previous request didn't complete. (mturk)
update Maintain should not run multiple times in parallel. (mturk)
fix Apache: Fix small memory leak during restart. (mturk)
update Improve signal handling during socket shutdown. (mturk)
add URI Map: Add debug dump function for uri worker map. (rjung)
update Add revision number to version info for non-release builds. (rjung)
add IIS: Optionally allow chunked encoding for responses. At the moment only usable, if build with ISAPI_ALLOW_CHUNKING defined. Based on patch by Tim Whittington. (rjung)
update IIS: Optionally use raw headers instead of CGI headers. Fixes problem "underscore=dash" problem in header names. At the moment only available, if build with USE_RAW_HEADERS defined. (rjung)
update IIS: Optionally improve IIS 5.1 compatibility. At the moment only available, if build with AUTOMATIC_AUTH_NOTIFICATION defined. Based on patch by Tim Whittington. (rjung)
fix IIS: Fix memory corruption due to parallel initialization by multiple threads. (rjung)
update Windows: Use non-default socket keepalive interval. (mturk)
add IIS: Add environment variables JKISAPI_PATH and JKISAPI_NAME. (mturk)
add Added socket_connect_timeout directive for setting the connect timeout for the socket. This enables to have low connection timeout but higher operational timeouts. (mturk)
fix AJP13: [CVE-2008-5519] Always send initial POST packet even if the client disconnected after sending request but before providing POST data. In that case or in case the client broke the connection in a middle of read send an zero size packet informing container about broken client connection. (mturk)
add AJP13: Added connection_acquire_timeout directive for setting the absolute timeout the worker will wait for a free endpoint. (mturk)
update Apache: Allow to set path parameter used when doing JkStripSession. (mturk)
update Refactor retries implementation and change semantics of retries attributes. (mturk)
update Status: Allow showing only a single member for a load balancer. (rjung)
update Status: Add display of seconds since last statistics reset and access and transfer rates. (rjung)
add AJP13: Add a configurable retry_interval time. (rjung)
update Documentation: Enhance description of connection_pool_size. (rjung)
update IIS: Refactor error page generation. (mturk)
fix IIS: SERVER_NAME variable can be the same for multiple different server instances if requests are handled according to the ip:port combination. Use INSTANCE_ID variable to which the request belongs instead. (mturk)
add Allow forwarding server error pages. This can be done on per-uri basis using new use_server_errors extension. (mturk)
add Added session_cookie and session_path for configuring default session identifiers. (mturk)
update Use max_packet_size also as TCP send and receive buffer size. (mturk)
update Apache: Do not allow Apache to start in multi-threaded mode if mod_jk was only build for single threaded server (prefork). (mturk)
fix 45812: Add done() service method that causes sending EOS bucket for Apache httpd 2.x. This allows filter chain to work properly. (mturk)
add Added connection_ping_interval, ping_timeout and ping_mode directives. (mturk)
fix Apache: Use correct ld flags provided by apxs when building module. Prevents some crashes on AIX for httpd 1.3 module. (rjung)
fix Documentation: "val" attribute numbering in status worker needs to start with 0 instead of 1. (rjung)
update Documentation: Remove JNI parameters from sample configuration in the workers common howto. (rjung)
fix 45026: For Apache httpd 2.x add "Unknown Reason" as the reason phrase, if we get an empty one from the backend. Otherwise httpd 2.x returns status 500. (rjung)
fix Build: Fix Cygwin build. (rjung)
update Documentation: Add info to docs, that variables sent via JkEnvVar are not listed in request.getAttributeNames(). (rjung)
add Add watchdog background thread for Apache 2.x and IIS doing internal maintenance (idle connection checks, backend probing). See JkWatchdogInternal (Apache) and watchdog_interval (IIS). (mturk)
update Change log level of some messages from error to info. (mturk)
fix Documentation: Fix docs for worker attribute "secret". (rjung)
update Detect correct plugin name for various web servers via additional preprocessor defines. (rjung)
fix LB: Do not put loadbalancer node in error state if there is opened channel. This fixes the bug when new connection fails due to busyness, causing opened connections fail stickyness. This brings back per-node busy counter and private state array for each request. We can mark the state as error for failover to work while still operating and reporting node as OK if there are opened working connections. (mturk)
fix 44738: Fix merging of JkOption ForwardURI* between virtual hosts. Patch contributed by Toshihiro Sasajima. (rjung)
add URI Map: Add extension attributes to uri worker map. Allowed are reply_timeout, active/disabled/stopped and fail_on_status. Usage currently only implemented for httpd and IIS. (rjung+mturk)
fix URI Map: Make dynamic reloading atomic and free memory not needed any longer. (rjung)
add Configure: Don't use post httpd 2.2.0 API functions when building with new --enable-api-compatibility configure switch. (rjung)
fix Apache: JkAutoAlias does not work in combination with JkMountCopy if there are no JkMount in virtual host. (rjung)
update LB: Optimize state macros to improve performance. (rjung)
add Apache: Allow dynamic setting of reply timeout using the environment variable JK_REPLY_TIMEOUT. (rjung)
add Status: Add manageability for ajp parameters of ajp workers and ajp lb members. (rjung)
update Status: Change parameter names of update action to make them more easily distinguishable from other parameters. (rjung)
add Status: Add ajp worker statistics also for workers, that are not lb members. (rjung)
update AJP: Refactor factories, move ajp13/ajp14 common parts into ajp_factory. (rjung)
update Status: Only sync shm worker config values of the workers for which we changed values. (rjung)
fix Status: Set lb_factor instead of distance. (rjung)
update Status: Minor layout changes, use drop down instead of multiple text links. (rjung)
update SHM: Use local copies of read mostly attributes of lb sub workers in lb and status worker. (rjung)
update Status: Add "dump" action to dump our initial configuration. (rjung)
update Status: Use property table to decide which cmd action uses which output elements. (rjung)
update Common: Include original configuration map in worker_env to make it available for workers, e.g. the status worker. (rjung)
update LB: Refactor "route" return for httpd note. Don't use a member of the worker_record, because that's not thread safe. (rjung)
update Common: Refactor "retries", remove from service and jk_worker, move into ajp worker instead. (rjung)
update SHM: Use distinct structs for lb and ajp13 in shm. Improves type safety and saves a few bytes. (rjung)
update SHM: Remove unused attributes. (rjung)
update SHM: Automatically determine shm size for all web servers. (rjung)
update SHM: Make open/attach logging consistent for all web servers. (rjung)
update Status: Include server local time in output. (rjung)
fix 44116: Fix handling of multiple JSESSIONID cookies. (rjung)
fix 37850: Use thread safe localtime_r where appropriate. (rjung)
fix Use thread safe strtok_r on more platforms, especially AIX. (rjung)
update Status: Improve XSS hardening. (rjung)
update 35303: Move initialization of service members with defaults from web server specific code to our generic jk_init_ws_service() function. (rjung)
fix 36385: Add missing prepost CPing/CPong directly after connect in case prepost CPing is used, but no connect CPing. (rjung)
update 37322: Apache: Enhance robustness of message formating in jk_error_exit(). (rjung)
fix 44147: Multiple load balancing workers problem. (rjung)
Changes between 1.2.25 and 1.2.26

Native
fix 42003: Allocate memory instead using fixed size from the stack. (mturk)
fix 43229: Load balancer does not do fail over after reply timeouts. (rjung)
fix JKStatus: Repair detailed Apache httpd version display. This was broken for httpd version 2.2.4+. (rjung)
update LB/AJP: Refactoring of jk_connect.c, jk_ajp_common.c, jk_lb_worker.c (rjung)
fix Configure: Repair broken apxs auto-detection. (rjung)
update Configure: Remove trace logging from compiled code via new --disable-trace configure switch. (rjung)
update Common: Maintain idle connections in decreasing (LRU) slot order. (rjung)
update Apache: Create JK_WORKER_ROUTE and JK_REQUEST_DURATION notes for access log even if no JkRequestLogFormat is set. (rjung)
update JKStatus: Enhance URI to worker map listing for Apache httpd. We now list maps for all virtual servers and not only the one, in which JKStatus itself was called. (rjung)
update JKStatus: Enhance URI to worker map listing. Update stale uriworkermap.properties immediately. (rjung)
fix 43873: Fix small memory leak occuring during httpd restart. (rjung)
update Common: Allow '*' for the worker name in exclusion rules (resp. JkUnMount) which will override all workers. (rjung)
fix 42038: Correct overlay of mounts and unmounts for IIS. (rjung)
fix 43684: Replace JkMountFile by JkMountFileReload in uriworkermap.properties docs. (rjung)
update Apache: Add new value "All" for JkMountCopy. (rjung)
fix 43516: Memory leak for Apache httpd module of size 8KB for every virtual host without JK directive after each restart. (rjung)
update Apache: Cleanup init and destroy of server configuration. (rjung)
update Apache: Remove global configuration items from per server configuration. (rjung)
update Apache: Remove unused attributes secret_key and automount/JkAutoMount. (rjung)
update Cleanup of jk_uri_worker_map. (rjung)
update Documentation: Small additions to JkShmFile documentation. Contributed by Gerhardus Geldenhuis. (rjung)
fix AJP13: Ignore flush packets before we received the response headers. (rjung)
fix Fix crash during startup when using worker configuration inheritance (attribute "reference") and log level debug. (rjung)
fix AJP13: Match header names exactly against pre defined constants. Avoid possible confusion with custom header names using a standard header name as a prefix. (rjung)
fix jkstatus: Fix correct parameter validation at JkStatusUpdateTask and JkStatusUpdateLoadbalancerTask ant tasks. Reported by Christian Mittendorf. (pero)
Changes between 1.2.24 and 1.2.25

Native
update IIS: Fix shm shutdown behaviour. (rjung)
update General: fail_on_status used in a load balancer can optionally do fail over without putting the failed worker in error state. (rjung)
update NSAPI: Improve build description for Unix. (rjung)
update NSAPI: Add initialization startup message containing JK version. (rjung)
fix General: Declare static functions as static. (jim)
update Documentation: Clarify fail_on_status behaviour. (rjung)
fix General: Do fail_on_status before returning the response headers. (rjung)
update NSAPI: Fix shm shutdown behaviour. (rjung)
update NSAPI: Set return status even if request ended with an error. (rjung)
update NSAPI: Allow using without shm_file on WIN32 and Netware. (rjung)
fix NSAPI: Fix Crash of nsapi for log level debug and unset refect_unsafe. (rjung)
update NSAPI: Improve Solaris and Linux Makefiles for nsapi build. (rjung)
fix Build: Improve pid_t type detection during configure on Solaris. (rjung)
update Build: Experimental build support for gcc on WIN32 and Netware. (fuankg)
update Build: Makefile optimizations for Apache httpd 1.3/Netware . (fuankg)
fix General: Fix missing flush bug introduced in 1.2.24. (rjung)
Changes between 1.2.23 and 1.2.24

Native
update Documentation: Improved workers.properties description in the reference guide. (rjung)
update Documentation: Add a HowTo about the various timeouts. rjung)
update Logging: add milliseconds to the default timestamp format, if we have gettimeofday(). (rjung)
update Apache: add milliseconds (%Q) and microseconds (%q) as possible JkLogStampFormat conversion specifiers. This does not use strftime(), but needs gettimeofday(). (rjung)
update IIS & Sun: Log service failures also, if return code is negative. (rjung)
fix 42849: Abort startup of Apache httpd 1.3 in case mod_jk initialization failed. We already do the same for Apache httpd 2.x. (rjung)
fix 42849: Refuse to operate with IIS in case the initialization failed. Instead requesting isapi_redirect.dll 500 will be returned to the user. This is as closest as it can get to Apache Httpd where we refuse to start the server in case of fatal initialization errors. (mturk)
fix Load Balancer: Fix a deadlock in lb worker, which was exposed on Solaris for threaded Apache MPMs. (rjung)
update Logging: handle LWP IDs as 32 Bit unsigned. Try to make it work, although pthread IDs are opaque. (rjung)
update JkStatus: Added manipulation of max_reply_timeouts. (rjung)
update LB, Status: Add feature max_reply_timeouts, to make lb tolerant against occasional long running requests. (rjung)
update JkStatus: Added OK/IDLE as the successor of N/A. (rjung)
update Status worker: Renamed runtime states. All states have a major state (OK or ERR) and a substate. Changed the name N/A to OK/IDLE. Added docs about the meaning of the states to the status worker page in the reference guide. No new states have been added to code. (rjung)
update Common: Add recovery options for recovering idempotent http methods HEAD and GET. (rjung)
fix Correct documentation for worker attributes retries and recovery_options. (rjung)
fix Make writing log lines and line endings more atomic. (rjung)
update Common: Refactored and unified jk_map_read_prop* and jk_map_load_prop* for all use cases. (rjung)
update Common/Apache/IIS/Netscape: Add an option to check decoded URLs for potentially malicious constructions. (rjung)
update IIS: Document auth_complete and uri_select. (rjung)
update Apache/IIS/Netscape: Change the default forwarding encoding to the new proxy method. (jfclere, rjung)
update Common: Optionally reencode URIs before forwarding to the backend. Based on the URI reencoding done bei httpd mod_proxy. (jfclere, rjung)
update Common: auto-detect correct print format for pid_t. This fixes at least compiler warnings on Solaris. (rjung)
fix 42608: Handle Content-length as unsigned 64Bit to allow for huge up- and downloads. (rjung)
update Apache: Add forwarding uri to debug log. (rjung)
update Docs: Clarify relation between worker names and jvmRoute for load balancing. (rjung)
fix Use initial zero timeout for jk_is_socket_connected. The resulting detection is the same but offers a huge performance increase with mod_jk. In most cases the Operating System does not favor the 1 microsecond timeout, but it rather rounds that up to much higher value (frequency of interrupt timer which on most systems defaults to 100Hz). Patch provided by David McLaughlin. (mturk)
update NSAPI: Check correct log file and shm file configuration during startup. (rjung)
fix NSAPI: Add support for the general options concerning retries, flushing and connection persistance. (rjung)
fix NSAPI: fix crashes due to use of mount attribute in workers.properties. Changed initialization order. (rjung)
fix Improved handling of libtool and discrepancies between CC env variable and CC used during apache build by configure script. (rjung)
fix Always build with thread support, unless flag --enable-prefork is set during for configure. (rjung)
update Use snprintf/vsnprintf from ap_snprintf.c for platforms other than Windows, which might lack snprintf/vsnprintf implementations when NOT build for Apache httpd 2.x/APR (e.g. Sub Web Server) or without using configure. (fuankg)
update Imported ap_snprintf() from Apache 1.3. (fuankg)
fix Fix incorrect log object cleanup during statup, leading to crashes at least on iSeries. (rjung)
update Add jk_stat() and jk_file_exists() as wrapper functions. i5/OS V5R4 expects filename in ASCII for fopen but requires them in EBCDIC for stat(). (hgomez)
update i5/OS (AS/400) V5R4 port where Apache 2.0 modules should now use UTF8. (hgomez)
update Docs: Add comments on i5/OS build for V5R4 and previous releases. (hgomez)
Changes between 1.2.22 and 1.2.23

Native
update [CVE-2007-0450] and [CVE-2007-1860]: Change the default value of JkOptions to ForwardURICompatUnparsed. The old default value was ForwardURICompat. This should make URL interpretation between Apache httpd and Tomcat consistent (prevent double decoding problems). (rjung)
Changes between 1.2.21 and 1.2.22

Native
fix Refactor line endings logging to make it correct for all platforms and webservers. (mturk)
update Added command line windows make files. (mturk)
update Allow fail_on_status directive to be multi line. (mturk)
fix 42076: Fix name of new option from ForwardCertChain to ForwardSSLCertChain as documented. (rjung)
fix Docs: Fix a couple of typos, change format of a few tables, fix links to news pages. (rjung)
fix Fix correct URL for TC 6 examples in new IIS rewrite.properties configuration example file. (rjung)
fix Add svn properties to several files. (rjung)
update Add TC 6 examples to uriworkermap.properties in config examples. (rjung)
update Allow multiple status codes for fail_on_status directive. The status codes can be delimited by space or comma characters. (mturk)
update IIS. Added pcre like regular expressions for url rewrite rules. (mturk)
fix 41922: Apache 1.3. Enable JkEnvVar. (mturk)
update Apache. Add --enable-flock configure parameter for explicit compilation of faster flock() system calls for OS supporting those calls. By default the fcntl system call for locking will be used that is a little bit slower but it can work on NFS mounted volumes as well. (mturk)
fix 41562: Add Debug logging for read from client in ISAPI Redirector. Contributed by Tim Whittington. (mturk)
update Apache. Add ForwardSSLCertChain JkOption. Contributed by Patrik Schnellmann. (mturk)
fix IIS. Do not forbid access to web-inf or meta-inf if there is no mapped worker. This allows to have resource with those names that are outside mapped contexts. (mturk)
update Apache. Use process id for creating shared memory name and delete shared memory and shared memory lock files on exit. (mturk)
fix IIS. Fix Keep-Alive regression introduced in 1.2.21. (mturk)
update Delete unused check for empty init_map during startup. (rjung)
fix 41770: Fix startup error if no JkWorkersFile is used. (rjung)
update Use JK_TRUE/JK_FALSE instead of OK/!OK as return values in init_jk(). (rjung)
update Minor adjustments to apache startup log messages (when to use STDERR, remove deprecated NOERRNO flag, shm warning and warnings for usage of default files). (rjung)
update Replace APR precompiler directive by httpd mpm_query to detect MPM threading. Add a debug log message about auto-detected pool size. (rjung)
fix Make MMN check easier to understand and a little more precise (for new ap_get_server_banner()/ap_get_server_description()). We use the new API only for Apache httpd 2.3. This way our binaries are not tightly coupled to a minor 2.0 version, and we don't use ap_get_server_banner() any way. (rjung)
fix Use the full description string ap_get_server_description() instead of the truncated info from ap_get_server_banner(), because this info gets used internally (status worker display and ajp14 backend communication) and is not send back to the normal user. (rjung)
fix 41757: Document the "--enable-prefork" flag of configure. (rjung)
update Enhance log messages for failures when parsing attribute maps. (rjung)
fix Correct log message during worker initialization, in case remote host could not be resolved. We logged the default host name "localhost" instead of the configured one. (rjung)
fix 41770: Fix the second part of the bug: local_worker and local_worker_only is missing from the list of deprecated attributes (and not supported either), so prevents the web server from startup. (rjung)
Changes between 1.2.20 and 1.2.21

Native
fix [CVE-2007-0774]: A denial of service and critical remote code execution vulnerability. Caused by buffer overflow in map_uri_to_worker() when URL were longer that 4095 bytes. Reported by ZDI (www.zerodayintiative.com). Please note this issue only affected versions 1.2.19 and 1.2.20 of the Apache Tomcat JK Web Server Connector and not previous versions. Tomcat 5.5.20 and Tomcat 4.1.34 included a vulnerable version in their source packages. Other versions of Tomcat were not affected.
add Check the worker. parameters and don't start if the parameter is not a valid one. (jfclere)
add 41439: Allow session IDs to get stripped off URLs of static content in Apache by adding JkStripSession directive (configurable per vhost). (mturk)
add Change semantics of empty defaults for JkEnvVar variables. Until 1.2.19: not allowed. In 1.2.20: send variables as empty strings, if neither set to non empty in config, nor during runtime. Starting with 1.2.21: If config has no second argument only send variable if set (even when set to empty string) during runtime. Allows good combination with condition attribute in tomcat access log. (rjung)
fix 41610: Fix incorrect detection of missing Content-Length header leading to duplicate headers. Contributed by Boris Maras. (rjung)
fix Better build support for SunONE (Netscape/iPlanet) webservers. (jim)
add Add warning if duplicate map keys are read and are not allowed, e.g. when parsing uriworkermap.properties. (rjung)
fix Don't concat worker names, if uriworkermap.properties has a duplicate pattern, instead overwrite the worker. (rjung)
fix Log deprecation message even in duplication case. (rjung)
fix uriworkermap.properties: Fix off-by-one problem when deleting URL mapping during reloading of uriworkermap.properties. (rjung)
add 41439: Allow session IDs to get stripped off URLs of static content in IIS (configurable). (rjung)
add 41333: Refactoring isapi_plugin configuration reading. (rjung)
add 41332: Add some more errno logging and unify the format. (rjung)
add JkStatus: Improved logging by adding status worker name to messages. Added messages to the recover worker action. (rjung)
add JkStatus: Refactoring searching for workers and sub workers. (rjung)
add 41318: Add configuration to make status worker user name checks case insensitive. (rjung)
add JkStatus: Add estimated time until next global maintenance to other mime types and adopt jkstatus ant task. (rjung)
add JkStatus: Show estimated time until next global maintenance. Change displayed time until next recovery to a min/max pair. (rjung)
add JkStatus: Allow a user of a read/write status worker to switch it to and from read_only mode temporarily. (rjung)
fix JkStatus: Do not show read/write commands in a read_only status worker. (rjung)
add JkStatus: Allow lb sub workers in error state to be marked for recovery administratively from the status worker. (rjung)
add Load Balancer: Do not try to recover multiple times in parallel. Use additional runtime states "PROBE" and "FORCED". (rjung)
fix JkStatus: Improve data synchronization between different processes. (rjung)
fix 41381: Fix segfault in feature fail_on_status (wrong order of log arguments). Patch by Juri Haberland. (rjung)
fix Use correct windows line endings for log file on WIN32 platform. (rjung)
Changes between 1.2.19 and 1.2.20

Native
add JkStatus Ant Task documentation page. (pero/rjung)
add JkStatus Ant Tasks: Add new tasks for update and reset. (pero)
update JkStatus Ant Tasks: Update for new xml status format. (pero)
update Allow integer and string values when setting enumeration/boolean attributes via status worker update action. (rjung)
add Docs: New reference guide page for status worker. (rjung)
update Docs: Renaming the config dir to reference and using the title Reference Guide in the docs. (rjung)
update Added retry_on_status for workers directive. (mturk)
update Status Worker: Add directive to make property prefix and good/bad rule configurable. (rjung)
update Status Worker: Omit lb members when att=nosw. (rjung)
update Status Worker: New command cmd=version for a short version output. (rjung)
update Status Worker: New output stype mime=prop produces property lists. (rjung)
fix Apache: Fix incorrect handling of JkEnvVar when Vars are set multiple times. (rjung)
update Renamed jvm_route to route. Deprecated jvm_route, but still use it as fallback when parsing the worker configuration. (rjung)
update IIS: Make uriworkermap file reload check interval configurable. (mturk)
update Apache: Make uriworkermap file reload check interval configurable. (rjung)
update Status Worker: Add directives for customizing the XML output (ns, xmlns, doctype). (mturk)
add Docs: New page with description of uriworkermap. (rjung)
update Docs: Added short description of max_packet_size to worker reference. (rjung)
update Status Worker: All functions accessible also for xml and txt mime types (list, show, update, reset). (rjung)
update Status Worker: New global health indicators for load balancers named bad (error, recovering or stopped), degraded (busy or disabled) and good (the rest, active and OK or N/A). (rjung)
update Status Worker: New edit page, to change one attribute for all members of a load balancer. (rjung)
update Status Worker: Standard logging for status worker. (rjung)
update Status Worker: code refactoring. (rjung)
update Status Worker: New attribute user (list) denies access, if the request user in the sense of remote_user is not in this list. Empty list = no deny (rjung)
update Status Worker: New attribute read_only disables the parts of the status worker, that change states and configurations. (rjung)
fix 36121: Don't change main uri when mod_jk serves included uri. (markt)
update Apache VHosts: Merge JkOptions +base - -base + +vhost - -vhost. (rjung)
update Apache Docs: Adding requirements, context information, default values and inheritance rules to the Apache config documentation. (rjung)
update Status Worker: Add source type to status worker, remove the redundant "context" column in the map listing (context=uri). (rjung)
update uriworkermap: On reload of the file, all old entries from the previous file version get deleted, before the new ones are being read. (rjung)
fix Keep normal maps and exclusion maps internally separate. Don't treat them as the same when adding a rule. (rjung)
update Status Worker: Display mapping rules also for non-lb workers and in global view. (rjung)
update Apache VHosts: Use the vhost log files instead of the main log. (rjung)
update Apache VHosts: Allow individual timestamp formats by refactoring the formatting method. (rjung)
update Apache VHosts: Adding all missing config items to the virtual host level. Don't overwrite the settings from the global server, but inherit them in case they are not set in the virtual host. (rjung)
update Apache: remove unnecessary function names from log messages. (rjung)
update Apache: add a default log file location and a message, if the default gets used. (rjung)
update Apache: add missing JK_IS_DEBUG_LEVEL() (rjung)
update Apache VHosts: Allow JkWorkersFile, JKWorkerProperty, JkShmFile and JkShmFileSize only in global virtual server. (rjung)
update Add some more jk_close_socket() and reduce log level for some info messages. (rjung)
update Load Balancer: Added the Sessions strategy. Contributed by Takayuki Kaneko. (rjung)
update Docs: Minor enhancements and syncing with more recent versions. (rjung)
fix 40997: Separate uri mappings from their '!' counterpart when checking for duplicates in uriworkermap reloading. (rjung)
fix 40877: Make sure the shared memory is reset on attach for multiple web server child processes. (mturk)
update IIS: Added shm_size property to be able to deal with over 64 workers configurations. (mturk)
update IIS: Increase default thread count to 250, so its the same as Apache Httpd default configuration. (mturk)
fix 40966: Fix socket descriptor checks on windows. (mturk)
fix 40965: Initialize missing service parameters. (mturk)
fix 40938: Fix releasing of rewrite map. Thanks to Chris Adams for spotting that. (mturk)
update Apache: Added +FlushHeader JkOptions. (mturk)
update Added explicit flush when AJP body packet size is zero. (mturk)
fix 40856: Fixing case sensitivity bug in URL mapping. (rjung)
fix 40793: Documentation: Improvements to Apache HowTo provided by Paul Charles Leddy. (markt)
fix 40774: Fixing wrong recursion termination. This one restricted the "reference" feature unintentionally to 20 workers. (rjung)
fix 40716: Adding "reference" feature to IIS and Netscape. (rjung)
fix Documentation: Corrected SetEnvIf syntax in JK_WORKER_NAME example. (rjung)
fix Documentation: Added forgotten STATE and ACTIVATION notes for load balancer logging in Apache. (rjung)
update Apache: Use instdso.sh instead libtool: libtool does not work on HP-UX for example. (jfclere)
Changes between 1.2.18 and 1.2.19

Native
update Docs: Add SetHandler and new env var to Apache config docs. (rjung)
update Apache 1.3: Backport "no-jk" feature. (rjung)
update Apache: Add an environment variable to make SetHandler "jakarta-servlet" more useful. The variable is JK_WORKER_NAME, but can be changed by the new directive JkWorkerIndicator. (rjung)
fix LB: Don't use single worker shortcut, if the single worker is being diabled. (rjung)
fix Status worker: Add short explanation of activation and error states to legend. (rjung)
fix Docs: Add meaning of zero timeout values for various timeouts in workers.properties. (rjung)
fix LB: Cleanup of Mladens forced recovery. (rjung)
fix LB: Do not change lb_value for recovering workers to max, if we are using BUSYNESS method. (rjung)
fix Apache: Since 1.2.14 mod_jk failed to detect client abort. (rjung)
fix Docs: Corrected description of JkEnvVar. (rjung)
fix Solaris: Detect filio.h in configure to make the new connection detection build on solaris (r432825). (rjung)
update Add feature to force the recovery of workers that are member of loadbalancer if all the members are in error state. This fixes the time gap where 503 was returned caused by recovery_timeout although the backend was ready to handle the requests. (mturk)
update Docs: Seperate deprecated directives in their own table. (rjung)
update Docs: Allow "-" and "_" in worker names. (rjung)
update Allow multiple lines with attributes "balance_workers" and "mount". (rjung)
fix Make jk_is_some_property match more precisely. (rjung)
update JkStatus: Make refresh interval changeable. (rjung)
fix JkStatus: Adjust display of recover time wrt. global maintenance. (rjung)
update LB: Resetting worker state from OK to NA, if worker has been idle too long. (rjung)
fix Avoid compiler warnings concerning the use of lb_*_type arrays. Use functions instead. (rjung)
update Added %R JkRequestLogFormat option for Apache 1 and Apache 2. (mturk)
update Allow changing jvm Route from status manager. (mturk)
fix Do not retun 400 if Tomcat fails in the midle of the post request. Return 500 insted. (mturk)
update LB: Combine ok/error/recovering/busy runtime states into a single scalar. (rjung)
update LB: Combine active/disabled/stopped configuration states into a single scalar. (rjung)
update LB: Add several Apache notes to enable standard logging for load balancer results. (rjung)
update LB: Reorganisation of the main load balancer service loop. (rjung)
update Implement hierarchical worker configuration via attribute "reference". (rjung)
update Log deprecated properties. (rjung)
fix IIS: Fix simple_rewrite for the cases where the rewritten url is larger then the original one. (mturk)
update New JkOption "DisableReuse" to disable connection persistence. (jim)
update LB: Move sessionid retrieval out of get_most_suitable_worker into service. (rjung)
update Code cleanup for all service methods (use TRACE, JK_LOG_NULL_PARAMS, null pointer checks). (rjung)
update JKSTATUS: add refresh link. No refresh for updates. Redirect to list view after update. (rjung)
update Add new hook add_log_items into servers. (rjung)
update APACHE httpd: Rename apache logging notes. (rjung)
update LB: Rename lock and method constants. Add constants for defaults. (rjung)
fix Default log level should be INFO and not DEBUG. Default log level should be the same for all server types. (rjung)
fix Make rewrite_rule_map and log_level as non mandatory directives for isapi_redirect. (mturk)
fix 40107: Rewrite is_socket_connected function. Non blocking socket is not used any more. (mturk)
update Allow building with VS2005 without too many warnings. (mturk)
fix Decide by MMN, which piped log API we should use. mod_jk 1.2.18 broke compilation with Apache 1.3 pre 1.3.28. (rjung)
Changes between 1.2.17 and 1.2.18

Native
fix Using socklen_t in getsockopt. Also introducing jk_sock_t. (mturk)
update Allow recovery wait time below 60 seconds (new minimum is 1 second). (mturk)
Changes between 1.2.16 and JK 1.2.17

Native
fix Fix hanging jk status worker when certain attributes are being updated due to double locking. (rjung)
update Allow JkMount to behave like uriworkermap.properties by parsing pipe symbol as two directive marker. (mturk)
Changes between 1.2.15 and JK 1.2.16

Native
update Added simple rewrite capability for IIS. Although simple it will fulfill most needs. (mturk)
update Added RECOVER_ABORT_IF_CLIENTERROR recovery_option that closes the connection if client connection is broken during the request. (mturk)
update Renamed cache_timeout directive to connection_pool_timeout. (mturk)
update Added connection_pool_minsize directive. (mturk)
update Deprecate recycle_timeout directive. (mturk)
update Corrected some HTML syntax bugs in output of status worker. (rjung)
update Added the refresh=n parameter to the status worker. It will update the display every n seconds. (rjung)
update Balancer: Add attribute distance to balanced workers to express preferences between workers. (rjung)
update Balancer: Add attribute jvm_route to balanced workers to be able to use the same target in different balancers. (rjung)
update Status: Add lb_mult to status. (rjung)
update Balancer: Make different balancing strategies work in a similar way (use lb_value, use decay during global maintenance, use integer factors for weights. (rjung)
update Balancer: Improve locking. (rjung)
update Balancer: Workers start slower after recovering. (rjung)
update Balancer: Make different balancing strategies work in a similar way (use lb_value, use decay during global maintenance, use integer factors lb_mult for weights). (rjung)
update Balancer: Move recovery check to global maintenance. (rjung)
update Balancer: Add global maintenance method, that is called in only one process. (rjung)
update Extend our use of autoconf to find a 32Bit and a 64Bit unsigned type and their printf formats. (rjung)
update Logging: piped loggers for JkLogFile and Apache 1.3. (rjung)
update Logging: Add PID to log lines for each log level apart from REQUEST. (rjung)
update Logging: flush buffered logs to keep lines in correct order. Output final newline together with log message. (rjung)
update Reducing shm size. (rjung)
update Only log removing of old worker, when we actually do it. (rjung)
fix 37469: Fix shared memory close for forked childs. The shared memory will be closed by the parent process. (mturk)
fix 37332: Fix potential misuse of buffer length with snprintf functions. (mturk)
fix 38859: [CVE-2006-7197] Protect mod_jk against buggy or malicious AJP servers in the backend. Patch provided by Ruediger Pluem. (mturk)
fix 38889: Use worker map sorting depending on the path elements, to comply with Servlet spec. Patch provided by Steve Revilak. (mturk)
update 36138: Added Busyness lb method. Patch provided by Chris Lamprecht. (mturk)
fix Fix pessimistic locking mode. The patch correctly handles the burst load, by syncing the access to the shared memory data. (mturk)
fix 38806: Reclycle worker even if it is disabled. This fixes hot-standby workers in error state. (mturk)
fix 37167: Allow building with BSD-ish like make. (mturk)
fix ISAPI plugin (isapi_redirect.dll) did not provide correct request data for IIS to include in the IIS log. (markt)
Changes between 1.2.14 and 1.2.15

Native
fix Fix AJP13 Cookie2 parsing. Cookie2 was always send as Cookie. Patch provided by Andre Gebers. (mturk)
fix 35862: NSAPI plugin attempts to read freed memory and attempts to dereference a null pointer. Patch provided by Brian Kavanagh. (markt)
Changes between 1.2.13 and 1.2.14

Native
fix Fix lb for worker mpm's with cachesize set to lower number then ThreadsPerChild is. If retries is set to value larger then 3 sleep for 100 ms on each attempt. This enables to tune the connection cache, and serialize incoming connections instead returning busy if connection count is larger then cachesize. (mturk)
fix 36525: Solaris core dump. (mturk)
fix 36102: Worker actions do not persist. (mturk)
fix 35864: Status worker doesn't list workers. Patch provided by Martin Goldhahn. (mturk)
fix 35809: JkMountCopy don't work for Apache 2.0 Patch provided by Christophe Dubach. (mturk)
fix 35298: Multiple JK/ISAPI redirectors on a single IIS site are not supported Patch provided by Tim Whittington. (mturk)
Changes between 1.2.12 and 1.2.13

Native
fix 34397: Emergency was handled as Error. (jfclere)
fix 34474: // in URL were not handled correctly with Apache-1.3. (jfclere)
fix Use 64 bits int for transferred/read bytes.
update Added JkOptions +FlushPackets used to optimize memory usage when sending large data. (mturk)
update Added lock directive for load balancer that allows more acurate load balancing in case of burst load. (mturk)
update Added worker.maintain directive to allow customizing default 10 second timeout. On busy servers this value needs to be set on higher value. (mturk)
fix Fix for NetWare compiler to deal with different types between AP13 and AP2 SDKs. (fuankg)
update Emit much more legible user.dmp crash analysis output for WIN32. (wrowe)
fix 34558: Fix first failover request. (mturk)
Changes between 1.2.11 and 1.2.12

Native
update Added ForwardLocalAddress JkOptions flag for passing local instead remote address. Useful for remote addr valve. (mturk)
fixFix that worker does not get used, when stopped flag is set to true. (pero)
update Add loadbalance default worker secret attribute to the documentation (pero)
Changes between 1.2.10 and 1.2.11

Native
fixBackport SC_M_JK_STORED from JK2 for passing arbitrary methods instead failing the request. (mturk)
fixAdded missing SEARCH and ACL http methods. (mturk)
update Add worker secret attribute to the documentation (pero)
update Add a stopped flag to worker configuration. Set flag to true and the complete traffic to the worker will be stopped. Also update the Ant JkStatusUpdateTask at Tomcat 5.5.10 release. Only usefull in a replicated session cluster.(pero)
updateAdded worker maintain function that will maintain all the workers instead just the current one. This enables to recycle the connections on all workers. (mturk)
updateUse shutdown when recycling connections instead hard breaking the socket. (mturk)
updateAdd unique directives checking. The directives if unique are now overwritten instead concatenated. (mturk)
updateAllow multiple worker.list directives. (mturk)
fix 34577: For IIS log original request instead loging the request for ISAPI extension. (mturk)
fix 34558: Make sure the returned status codes are the same for ajp and lb workers. (mturk)
fix 34423: Use APR_USE_FLOCK_SERIALIZE for setting log lock on platforms like FreeBSD. Patch provided by Allan Saddi. (mturk)
fix 33843: Fix obtaining LDFLAGS that were used for building Apache HTTPD. Patch provided by Beat Kneubuehl. (mturk)
fix 34358: Enable load balancer method configuration. (glenn)
fix 34357: In some situations Apache 2 mod_jk could segfault when the JkAutoAlias directive is used. (glenn)
update Add --enable-prefork to the documentation (pero)
updateUpdate tomcat_trend.pl for new error log string formatting. (glenn)
Changes between 1.2.8 and 1.2.10

Native
updateSet default shared memory to 64K instead 1M. (mturk)
fixDo not mark the worker in error state if headers are larger then AJP13 limit. (mturk)
update On iSeries you should use the latest PTF for Apache 2.0 (which is now 2.0.52) and ad minima SI17402/SI17061 or cumulative including them. (hgomez)
update Change the xml status format to xml attribute syntax (pero)
fix 33248: Fix builds where apxs defines multiple directories for APR includes. (mturk)
fix 32696: Return 404 instead 403 when WEB-INF is requested to comply with Servlet spec. (mturk)
updateAdded ANT task for managing jkstatus. (pero)
update If socket_timeout is set, check if socket is alive before sending any request to Tomcat. (mturk)
update Added JkMountFile for Apache web servers. This file can contain uri mappings in the form (/url=worker), and is checked for updates at regular 60 second interval. (mturk)
update Added status worker for managing worker runtime data using web page. (mturk)
update Added load balancer method directive that is used for setting the algorithm used for balancing workers. Method can be either Request (default) or Traffic. (mturk)
update Added shared memory to allow dynamic configuration. Shared memory is needed only for unix platform and web servers having multiple child processes. For Apache web server two new directives has been added (JkShmFile and JkShmSize). (mturk)
update Added textupdate mode to status worker to handle remote updates from ant tasks.(pero)
fix 33562: Fix Reply_timeout when recovery_options is larger than 1. Patch provided by Takashi Satou. (mturk)
fix 33308: Fix segfaults when ForwardDirectories is enabled with Apache 1.3
Changes between 1.2.7 and 1.2.8

Native
update Allow anyone to debug and diagnose stack dumps using windbg or any other debugging tool, and (if they add the .pdb files to their installation) to make sense of dr watson logs. Patch provided by William A. Rowe (wrowe)
fix Fix in_addr_t usage by using the real struct ignoring typedef. Patch provided by William A. Rowe (wrowe)
fix Fix url rewriting by restoring the in place uri from which the jsessionid was removed. (mturk)
update Make load balancer algorithm thread safe by introducing mutex to the load balancer worker. (mturk)
fix Fix sending error pages for IIS to client by adding Content-Type header using correct api function call. (mturk)
fix 32696: Prevent IIS from crushing when web-inf url was requested. (mturk)
update Use default cachesize for servers that support discovering the number of threads per child process. (mturk).
fix Fix Apache content-length header parsing using case insensitive compare. (billbarker)
fix Fix parsing AJP headers using case insensitive compare. (mturk)
fix Use infinite socket timeout if socket_timeout is set to zero or less then zero. (mturk)
update Change balanced_workers to balance_workers but keep backward compatibility preserving the old directive. (mturk).
fix Fix ajp initialization for workers with cache_size set to zero. (mturk)
update 32317: Making mod_jk replication aware (Clustering Support). Patch provided by Rainer Jung. (mturk).
fix 31132: Core dump when JkLogFile is missing from conf. (mturk)
Changes between 1.2.6 and 1.2.7

Native
update Added new property named recover_time that can be used to change the default 60 second recover time. (mturk)
update Added custom retries for worker, so we don't depend on default setting. If set to a number grater then 3, it will sleep for 100ms on retry greater then 3 and then try again. (mturk)
update Added JkWorkerProperty directive that enables omiting workers.properties file. For example: JkWorkerProperty worker.ajp13a.port=8009. (mturk)
fix Check all JSESSIONID cookies for a valid jvmRoute. If you have multiple Tomcats with overlapping domains, then you can get multiple cookies without a defined order. This will route correctly as long as the different domains don't have any Tomcats in common. (billbarker)
update Added JkUnMount directive for negative mappings that works as opposite to JkMount directives. It is used for blocking of particular URL or content type. (mturk)
update Added wildchar match uri mappings. One can now use JkMount to map /app/*/servlet/* or /app?/*/*.jsp. (mturk)
update Rewrite the logging by adding Trace options. (mturk)
update Added socket_timeout property that sets the timeout for the socket itself. (mturk)
fix Changed socket_timeout property to recycle_timeout. This better explains what the directive actually does. (mturk)
fix Changed the load balancer algorithm. The idea behind this new scheduler is the following: lbfactor is how much we expect this worker to work, or the worker's work quota. lbstatus is how urgent this worker has to work to fulfill its quota of work. We distribute each worker's work quota to the worker, and then look which of them needs to work most urgently (biggest lbstatus). This worker is then selected for work, and its lbstatus reduced by the total work quota we distributed to all workers. Thus the sum of all lbstatus does not change.(*) If some workers are disabled, the others will still be scheduled correctly. (mturk)
fix Fix iis redirector that was figuring .properties file on each request. (mturk)
fix Start fixing 64/32 bit compatibility issues. (mturk)
Changes between 1.2.5 and 1.2.6

Native
fix Fix POST Recovery problems in LB mode. (hgomez)
add Add CPING/CPONG support to avoid problems with hang tomcats. (hgomez)
update Make POST recovery in LB configurable. (hgomez)
update Update to Apache License 2.0. (hgomez)
add For Apache 2.0, when the env var no-jk is present, mod_jk didn't handle request (declined) and as such dont forward requests to tomcats even if URL match. To be used with SetEnvIf or BrowserMatch directives for example to exclude some URL/URI or Browser (hgomez).
fix Add a fix for iSeries (AS/400) which use XOPEN/Unix98 APIs and need sa_len to be set when calling connect(), it will resolve the error EINVAL in jk_connect. (hgomez)
Changes between 1.2.4 and 1.2.5

Native
fix Fix a thread safe bug when mapping URI's. (billbarker)
fix Fix a thread safe bug when resolving worker host name when using mod_jk with Apache 2 and the worker MPM. (hgomez)
fix Remove an unnecessary error message when connections to all load balanced workers fail. (glenn)
fix When mod_jk cannot connect to a worker include the name of the worker in the error message. This is especially helpful when you are using load balanced workers. (glenn)
fix Fix problem with mod_jk.log getting opened multiple times for Apache 2. Only one mod_jk.log can be configured. (glenn)
fix Fix Apache 2 connector so that DirectoryIndex works for an index.jsp page if JkOptions ForwardDirectories was configured. (hgomez)
fix Fix exposure of JSP source if a //path/to.jsp URL was requested in Apache 1.3 and Apache 2.0 connector. (billbarker)
Changes between 1.2.3 and 1.2.4

Native
add Fix use of libtool for Apache mod_jk builds with more recent versions of Apache 2. (jfclere)
fix Use reentrant version of strtok() for web server's which use threads. This fixes a thread safe bug under Apache 2 and the worker MPM. (glenn)
fix Fix the Apache 2 mod_jk hook priority so that mod_jk works well with both mod_alias and mod_dir. (glenn)
Changes between 1.2.2 and 1.2.3

Native
add Add the ability to configure JkLog to pipe its log output to an executable such as Apache rotatelogs or cronolog. Apache 2.0 only. (glenn)
add Add JkAutoAlias to Apache 2.0. (glenn)
update Apache 2/1.3, if Tomcat returns an error but not content, let Apache handle processing the error returned by Tomcat. (glenn)
add Added the load balancer sticky_session property. If set to 0 requests with servlet SESSION ID's can be routed to any Tomcat worker. Default is 1, sessions are sticky. (glenn)
fix Cleaned up detection and reporting of aborted client connections. This cleanup also makes sure that mod_jk does not pass any requests on to Tomcat if the remote client aborted its connection. (glenn)
fix Fixed a bug in Apache 2.0 which caused a POST request forwarded to Tomcat to fail if it generated SSI directives which were post processed by mod_include. (glenn)
fix Fixed a bug in JkRequestLogFormat when printing the request URI that could cause a URI with hex escapes sequences to be formatted wrong. (glenn)
Changes between 1.2.1 and 1.2.2

Native
update tomcat_trend.pl updated script to support changed logging of aborted requests. (glenn)
fix jk set correctly the content-type in Apache 2.0, making it ready to works with mod_deflate and AddOutputFilterByType. (hgomez)
fix jk will check result of get_endpoint and handle a failure. This call can fail if the allocation for the endpoint fails because of low memory conditions causing a dereference of NULL when we try and access the endpoint. (mmanders)
Changes between 1.2.0 and 1.2.1

Native
fix 14282: Don't send initial chunk for chunked encoding. (costin)
add Add perl scripts for analyzing mod_jk logs and generating graphs/reports. (glenn)
fix Make JK honor the CanonicalHost directive. (hgomez)
fix Log cleanup. (costin)
fix Fix typos in jk xdocs/docs. (hgomez)
fix Add JkRequestLogFormat to Apache 2.0. (hgomez)
fix Final patches to make JK iSeries compliant. (hgomez)
JK 2

JK2 has been put in maintainer mode and no further development will take place. The reason for shutting down JK2 development was the lack of developers interest. Other reason was lack of users interest in adopting JK2, caused by configuration complexity when compared to JK.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/miscellaneous/printer/jkstatustasks.html0000644000000000000020000002340012555256556025414 0ustar rootbinThe Apache Tomcat Connectors - Miscellaneous Documentation - Status Worker Ant Tasks
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Miscellaneous Documentation

Status Worker Ant Tasks

Introduction

Since version 1.2.19 the JK release contains additional ant tasks. They can be used to manage the JK web server plugins via the special status worker.

Manage JK with remote Ant Tasks
Simple antlib integration

<?xml version="1.0" encoding="UTF-8"?>

<project name="modjk-status" 
         xmlns:jk="urn:org-apache-jk-status"
         default="status" basedir=".">

	<property name="profile" value=""/>
	<property file="jkstatus${profile}.properties"/>
	<property file="jkstatus.properties.default"/>

    <path id="jkstatus.classpath">
      <fileset dir="${catalina.home}/bin">
          <include name="commons-logging-api-*.jar"/>
      </fileset>
      <pathelement location="${catalina.home}/server/lib/catalina-ant.jar"/>
      <pathelement location="../dist/tomcat-jkstatus-ant.jar"/>
      <pathelement location="${catalina.home}/server/lib/tomcat-util.jar"/>
    </path>

    <typedef resource="org/apache/jk/status/antlib.xml"       
           uri="urn:org-apache-jk-status" classpathref="jkstatus.classpath"/> 
           
    <target name="status" >       
 	    <jk:status url="${jkstatus.url}" 
	                username="${jkstatus.username}"
	                password="${jkstatus.password}"
	                resultproperty="worker"
	      	        echo="off"
	                failOnError="off"/>
	    <echoproperties prefix="worker" />
    </target>
</project>    

Test Result

[echoproperties] #Ant properties
[echoproperties] #Sun Dec 10 20:40:21 CET 2006
[echoproperties] worker.node01.lbmult=1
[echoproperties] worker.loadbalancer.lock=Optimistic
[echoproperties] worker.node02.transferred=0
[echoproperties] worker.loadbalancer.sticky_session=false
[echoproperties] worker.node01.distance=0
[echoproperties] worker.node01.client_errors=0
[echoproperties] worker.node02.lbmult=1
[echoproperties] worker.node01.port=7309
[echoproperties] worker.node01.elected=0
[echoproperties] worker.loadbalancer.good=2
[echoproperties] worker.loadbalancer.method=Sessions
[echoproperties] worker.server.port=2090
[echoproperties] worker.loadbalancer.map.2.type=Wildchar
[echoproperties] worker.node02.route=node02
[echoproperties] worker.node01.route=node01
[echoproperties] worker.node01.lbvalue=0
[echoproperties] worker.node01.lbfactor=1
[echoproperties] worker.node01.max_busy=0
[echoproperties] worker.node01.busy=0
[echoproperties] worker.node01.redirect=
[echoproperties] worker.node02.distance=0
[echoproperties] worker.loadbalancer.name=loadbalancer
[echoproperties] worker.loadbalancer.sticky_session_force=false
[echoproperties] worker.node02.state=N/A
[echoproperties] worker.node01.state=N/A
[echoproperties] worker.node01.transferred=0
[echoproperties] worker.loadbalancer.map.length=2
[echoproperties] worker.node01.type=ajp13
[echoproperties] worker.node01.address=127.0.0.1\:7309
[echoproperties] worker.result.type=OK
[echoproperties] worker.loadbalancer.member_count=2
[echoproperties] worker.loadbalancer.map_count=2
[echoproperties] worker.loadbalancer.mtime_to_maintenance_min=12
[echoproperties] worker.loadbalancer.mtime_to_maintenance_max=75
[echoproperties] worker.node02.lbfactor=1
[echoproperties] worker.node02.max_busy=0
[echoproperties] worker.jk_version=mod_jk/1.2.21-dev
[echoproperties] worker.loadbalancer.bad=0
[echoproperties] worker.node02.redirect=
[echoproperties] worker.node01.host=localhost
[echoproperties] worker.node02.activation=ACT
[echoproperties] worker.loadbalancer.map.1.source=JkMount
[echoproperties] worker.loadbalancer.retries=2
[echoproperties] worker.node02.elected=0
[echoproperties] worker.loadbalancer.map.2.source=JkMount
[echoproperties] worker.node02.port=7409
[echoproperties] worker.loadbalancer.length=2
[echoproperties] worker.node02.lbvalue=0
[echoproperties] worker.loadbalancer.degraded=0
[echoproperties] worker.loadbalancer.map.1.type=Wildchar
[echoproperties] worker.loadbalancer.map.2.uri=/myapps*
[echoproperties] worker.node02.client_errors=0
[echoproperties] worker.length=1
[echoproperties] worker.node01.domain=d20
[echoproperties] worker.loadbalancer.recover_time=60
[echoproperties] worker.server.name=localhost
[echoproperties] worker.node02.domain=
[echoproperties] worker.result.message=Action finished
[echoproperties] worker.node02.busy=0
[echoproperties] worker.node01.readed=0
[echoproperties] worker.node01.errors=0
[echoproperties] worker.node02.address=127.0.0.1\:7409
[echoproperties] worker.node02.readed=0
[echoproperties] worker.loadbalancer.busy=0
[echoproperties] worker.web_server=Apache/2.0.59 (Unix) mod_jk/1.2.21-dev
[echoproperties] worker.node02.errors=0
[echoproperties] worker.node02.type=ajp13
[echoproperties] worker.loadbalancer.map.1.uri=/ClusterTest*
[echoproperties] worker.node01.activation=ACT
[echoproperties] worker.loadbalancer.max_busy=0
[echoproperties] worker.loadbalancer.type=lb
[echoproperties] worker.node02.host=localhost

Update Load Balancer

     <target name="updatelb" >       
 	    <jk:updateloadbalancer url="${jkstatus.url}" 
	                username="${jkstatus.username}"
	                password="${jkstatus.password}"
	                loadbalancer="loadbalancer"
	                method="Busyness"
	                retries="2"
	                recoverWaitTime="60"
	                lock="Optimistic"
	                forceStickySession="false"
	                stickySession="false"/>
     </target>

Update Worker

     <target name="updatew" >       
 	    <jk:updateworker url="${jkstatus.url}" 
	                username="${jkstatus.username}"
	                password="${jkstatus.password}"
	                loadbalancer="loadbalancer"
	      	        worker="node01"
	                lbfactor="2"
	                activation="Active"
	                redirect=""
	                domain=""
	                route="node01"
	                distance="0"/>
     </target>

Reset Worker

     <target name="reset" >       
 	    <jk:reset url="${jkstatus.url}" 
	                username="${jkstatus.username}"
	                password="${jkstatus.password}"
	                loadbalancer="loadbalancer"
	      	        worker="node01"
	                />
     </target>


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/miscellaneous/printer/faq.html0000644000000000000020000004474312555256556023262 0ustar rootbinThe Apache Tomcat Connectors - Miscellaneous Documentation - FAQ
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Miscellaneous Documentation

FAQ

General

General Informations and FAQ about JK

Where can I get help/support for JK ?

The primary mechanism for support is through the JK documentation included in the doc directory. Documentation is also available on the Apache Tomcat web site devoted to the Apache Tomcat Connectors Project For additional help, the best resource is the Tomcat Users Discussion list. You should start by searching the mail list archive before you post questions to the list. If you are unable to locate the answer to your question in the archive, you can post questions about JK to the user list for assistance. Make sure that you include the version of your Webserver, that you are using as well as the platform you are running on and go here to determine how to subscribe to tomcat mailing list.

I can't find JK anywhere. Where is it?

Now that JK moved to the tomcat-connectors repository, the source and the binaries for JK can be downloaded from a mirror at the Tomcat Connectors (mod_jk, mod_jk2) Downloads page.

What's the difference between JK and mod_jk ?

JK is a project covering web-servers to Tomcat connectors, whereas mod_jk is the Apache module developed in JK.

IIS webserversupport is implemented on JK, using a redirector called isapi redirector.

Netscape/SunONE/Sun webserverwebserver support is implemented on JK, using a redirector called nsapi redirector.

Where can I get more information ?

For JK 1.2.x, you should read :

For more detailed information, have a look at the Reference Guide. You could also try searching the mailing list archives for "JK" or look at the source.

Which protocol should I use? Ajp12 or Ajp13?

Ajp13 is a newer protocol, it's faster, and it works better with SSL. You almost certainly want to use it now that ajp12 is deprecated.

Also ajp13 is supported by all Apache Tomcat versions starting with Tomcat 3.2.

Others Servlet engines like jetty have support for Ajp13.

I've got a firewall between my web server and Tomcat which drops ajp13 connections after some time

Ajp13 uses persistant connections where the traffic could be null if there is no request to be sent to Tomcat. Firewalls use to drop inactive connections and will make your web server and Tomcat think the connection is valid.

Starting with JK 1.2.0, a socket_keepalive property as been added to ajp13 settings, and you should take a look at it in Workers HowTo and workers.properties reference. If nothing else helps, you can try JkOptions +DisableReuse, but this will have strong performance implications.

Under heavy load, I've got many threads in Tomcat even if my Apache Web Server handles much of the load

Under heavy load, Apache Web Server creates many children to handle the load, which will in turn create many connections to Tomcat to forward the requests they should handle. Apache Web Server will normally kill the children/threads when the load decreases. But if the load is still there and even if only Apache handles the requests, ie static contents, the children are kept and with them all the ajp13 connections, even if they are no more used.

To close connections after some time of inactivity you can use connection_pool_timeout, for more informations refer to workers.properties reference.

Apache

Informations and FAQ about mod_jk and Apache Web Servers.

Whenever I restart Tomcat, Apache locks up!

The Ajp13 protocol keeps an open socket between Tomcat and Apache. Release of mod_jk present in J-T-C handles the network failure. But with very ancient releases of mod_jk, you may have to restart Apache as well.

Why do there exist two files mod_jk.so (-eapi ad -noeapi) in download directories for Apache 1.3?

Many versions of Apache use a modified API, known at Extended API, developed for use with the mod_ssl module. Starting with Apache 2.0 there is no more difference.

For example, Apache 1.3 present in certains recent Linux distributions include the mod_ssl module.

So if you got such 'Extended Apache', you need to use mod_jk.so-eapi.

You should use mod_jk.so-noeapi only for 'Standard Apache' (ie without mod_ssl).

It's wise to avoid using EAPI modules on STD API Apache or to use standard API modules on EAPI Apache. Allways be sure to have the mod_jk.so witch match your version of Apache

What's that message about 'garbled DSO ?'

It's related to Apache EAPI, the message 'mod_jk.so is garbled - perhaps this is not an Apache module DSO ?' just told you, that your're trying to install a mod_jk.so DSO module that was compiled on an Apache using EAPI, like apache-mod_ssl or apache from Redhat distro 6.2/7.0 but your system use the standard apache with normal API.

And the message about 'module might crash under EAPI!

Also related to EAPI, the message '[warn] Loaded DSO /usr/lib/apache/mod_jk.so uses plain Apache 1.3 API, this module might crash under EAPI! (please recompile it with -DEAPI)', the mod_jk.so was compiled under normal Apache with standard API and you try to install the module on an Apache using EAPI.

APXS is getting an error during the build of mod_jk, like rc=0 or rc=255. I tried all of the steps in the build section, what do I do now ?

APXS is a Perl script that is created when you build the Apache web server from source. Chances are that if you are getting these errors and you obtained Apache as a binary distribution, that APXS is not configured correctly for your system. Your best bet is to get the Apache source from http://httpd.apache.org and build it yourself. Use the following for a basic build (read the Apache docs for other options):

[user@host] ~ $ cd /usr/local/src
[user@host] ~ $ gzip -dc apache_1.3.19.tar.gz|tar xvf -
[user@host] ~ $ cd apache_1.3.19
[user@host] ~ $ ./configure --prefix=/usr/local/apache \
[user@host] ~ $ --enable-module=most \
[user@host] ~ $ --enable-shared=max
[user@host] ~ $ make
[user@host] ~ $ make install

Note: The above steps assume that you downloaded the Apache source and placed it in your /usr/local/src directory.

Apache complains about incorrect module version

Since the Apache API can change between versions, any Apache module contains the Apache API version used to compile the module. This is called the Magic Module Number.

At start time Apache checks that the version in the module header is compatible with the Apache server. If not it will deny to start and log an error.

Note that minor versions are forward compatible. If the module was compiled using Apache 2.x.y the resulting binary should work with any other version 2.x.z where z is bigger or equals to y. If you also need compatibility for versions 2.x.z with z smaller than y, use the configure flag --enable-api-compatibility. Note that the module compiled with any 2.x will never be compatible with 2.y for x different from y.

Does it work for the latest Apache 2.x?

mod_jk works well with Apache 2.x from 2.0 to 2.4.

Important parts of the functionality of mod_jk have been reimplemented as Apache httpd modules mod_proxy_ajp and mod_proxy_balancer. These are part of the standard distributoin of Apache 2.2. The new modules do not contain all features of mod_jk, but you get them automatically with every Apache 2.2 and later.

JNI doesn't work with Apache 1.3

JNI workers have been deprecated. They will likely not work. Do not use them.

JNI support requires a multi-threaded environment which is not the general case for Apache 1.3. You should verify if Apache 1.3 has been build with thread support and if not you could add the the pthreads library to your httpd.conf file.

  # Add pthread to Apache in httpd.conf
  LoadModule "/usr/lib/libpthreads.so"

Also keep in mind that JNI is suited for multi-threaded servers and you should consider upgrading to Apache 2.x to support JNI.

JNI report that JVM couldn't be started under Linux

JNI workers have been deprecated. They will likely not work. Do not use them.

Under Linux, you should set some environment variables BEFORE launching your Apache server :

export LD_LIBRARY_PATH=$jre/bin:$jre/bin/classic:$LD_LIBRARY_PATH

Also some Linux distributions have enabled a GLIBC feature called 'floating stacks' which may not works with kernel less than 2.4.10 on SMP machines. You should disable floating stacks by exporting an environment variable :

export LD_ASSUME_KERNEL=2.2.5

You could have to update your service scripts, ie /etc/rc.d/init.d/httpd, to set these env vars before your httpd server starts.

Mixed errors when building via configure

configure assume you have some GNU tools already installed and configured for your system, and ad minima libtool.

Also some systems may have mixed cc and gcc setup which may make you puzzled when trying to link an Apache built with native c compiler with a jk/jk2 build with gcc.

In case the make processing doesn't work as expected, you should use a GNU make gmake.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/miscellaneous/printer/reporttools.html0000644000000000000020000001014312555256556025072 0ustar rootbinThe Apache Tomcat Connectors - Miscellaneous Documentation - Reporting Tools
Apache Tomcat :: Apache Software Foundation

The Apache Tomcat Connectors - Miscellaneous Documentation

Reporting Tools

Reporting Tools

The mod_jk source distribution contains two perl scripts in the tools/reports directory which can be used to analyze the mod_jk logs, save statistical data, and generate report graphs.

tomcat_trend.pl log_dir archive_dir

Script for analyzing mod_jk.log data when logging tomcat request data using the JkRequestLogFormat Apache mod_jk configuration. Generates statistics for request latency and errors. Archives the generated data to files for later use in long term trend graphs and reports.

tomcat_reports.pl archive_dir reports_dir

Script for generating reports and graphs using statistical data generated by the tomcat_trend.pl script. The following graphs are created:

  • tomcat_request.png - Long term trend graph of total number of tomcat requests handled.
  • tomcat_median.png - Long term overall trend graph of tomcat request latency median.
  • tomcat_deviation.png - Long term overall trend graph of tomcat request mean and standard deviation.
  • tomcat_error.png - Long term trend graph of requests rejected by tomcat. Shows requests rejected when tomcat has no request processors available. Can be an indicator that tomcat is overloaded or having other scaling problems.
  • tomcat_client.png - Long term trend graph of requests forward to tomcat which were aborted by the remote client (browser). You will normally see some aborted requests. High numbers of these can be an indicator that tomcat is overloaded or there are requests which have very high latency.

A great deal of statistical data is generated but at this time only long term trend graphs are being created and no reports. This is only a start. Many more graphs and reports could be generated from the data. Please consider contributing back any new reports or graphs you create. Thanks.

These perl scripts depend upon the following perl modules and libraries:

  • GD 1.8.x graphics library http://www.boutell.com/gd/
  • GD 1.4.x perl module
  • GD Graph perl module
  • GD TextUtil perl module
  • StatisticsDescriptive perl module


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/miscellaneous/faq.html0000644000000000000020000005314012555256556021566 0ustar rootbinThe Apache Tomcat Connectors - Miscellaneous Documentation - FAQ
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Miscellaneous Documentation

FAQ

Printer Friendly Version
print-friendly
version
General

General Informations and FAQ about JK

Where can I get help/support for JK ?

The primary mechanism for support is through the JK documentation included in the doc directory. Documentation is also available on the Apache Tomcat web site devoted to the Apache Tomcat Connectors Project For additional help, the best resource is the Tomcat Users Discussion list. You should start by searching the mail list archive before you post questions to the list. If you are unable to locate the answer to your question in the archive, you can post questions about JK to the user list for assistance. Make sure that you include the version of your Webserver, that you are using as well as the platform you are running on and go here to determine how to subscribe to tomcat mailing list.

I can't find JK anywhere. Where is it?

Now that JK moved to the tomcat-connectors repository, the source and the binaries for JK can be downloaded from a mirror at the Tomcat Connectors (mod_jk, mod_jk2) Downloads page.

What's the difference between JK and mod_jk ?

JK is a project covering web-servers to Tomcat connectors, whereas mod_jk is the Apache module developed in JK.

IIS webserversupport is implemented on JK, using a redirector called isapi redirector.

Netscape/SunONE/Sun webserverwebserver support is implemented on JK, using a redirector called nsapi redirector.

Where can I get more information ?

For JK 1.2.x, you should read :

For more detailed information, have a look at the Reference Guide. You could also try searching the mailing list archives for "JK" or look at the source.

Which protocol should I use? Ajp12 or Ajp13?

Ajp13 is a newer protocol, it's faster, and it works better with SSL. You almost certainly want to use it now that ajp12 is deprecated.

Also ajp13 is supported by all Apache Tomcat versions starting with Tomcat 3.2.

Others Servlet engines like jetty have support for Ajp13.

I've got a firewall between my web server and Tomcat which drops ajp13 connections after some time

Ajp13 uses persistant connections where the traffic could be null if there is no request to be sent to Tomcat. Firewalls use to drop inactive connections and will make your web server and Tomcat think the connection is valid.

Starting with JK 1.2.0, a socket_keepalive property as been added to ajp13 settings, and you should take a look at it in Workers HowTo and workers.properties reference. If nothing else helps, you can try JkOptions +DisableReuse, but this will have strong performance implications.

Under heavy load, I've got many threads in Tomcat even if my Apache Web Server handles much of the load

Under heavy load, Apache Web Server creates many children to handle the load, which will in turn create many connections to Tomcat to forward the requests they should handle. Apache Web Server will normally kill the children/threads when the load decreases. But if the load is still there and even if only Apache handles the requests, ie static contents, the children are kept and with them all the ajp13 connections, even if they are no more used.

To close connections after some time of inactivity you can use connection_pool_timeout, for more informations refer to workers.properties reference.

Apache

Informations and FAQ about mod_jk and Apache Web Servers.

Whenever I restart Tomcat, Apache locks up!

The Ajp13 protocol keeps an open socket between Tomcat and Apache. Release of mod_jk present in J-T-C handles the network failure. But with very ancient releases of mod_jk, you may have to restart Apache as well.

Why do there exist two files mod_jk.so (-eapi ad -noeapi) in download directories for Apache 1.3?

Many versions of Apache use a modified API, known at Extended API, developed for use with the mod_ssl module. Starting with Apache 2.0 there is no more difference.

For example, Apache 1.3 present in certains recent Linux distributions include the mod_ssl module.

So if you got such 'Extended Apache', you need to use mod_jk.so-eapi.

You should use mod_jk.so-noeapi only for 'Standard Apache' (ie without mod_ssl).

It's wise to avoid using EAPI modules on STD API Apache or to use standard API modules on EAPI Apache. Allways be sure to have the mod_jk.so witch match your version of Apache

What's that message about 'garbled DSO ?'

It's related to Apache EAPI, the message 'mod_jk.so is garbled - perhaps this is not an Apache module DSO ?' just told you, that your're trying to install a mod_jk.so DSO module that was compiled on an Apache using EAPI, like apache-mod_ssl or apache from Redhat distro 6.2/7.0 but your system use the standard apache with normal API.

And the message about 'module might crash under EAPI!

Also related to EAPI, the message '[warn] Loaded DSO /usr/lib/apache/mod_jk.so uses plain Apache 1.3 API, this module might crash under EAPI! (please recompile it with -DEAPI)', the mod_jk.so was compiled under normal Apache with standard API and you try to install the module on an Apache using EAPI.

APXS is getting an error during the build of mod_jk, like rc=0 or rc=255. I tried all of the steps in the build section, what do I do now ?

APXS is a Perl script that is created when you build the Apache web server from source. Chances are that if you are getting these errors and you obtained Apache as a binary distribution, that APXS is not configured correctly for your system. Your best bet is to get the Apache source from http://httpd.apache.org and build it yourself. Use the following for a basic build (read the Apache docs for other options):

[user@host] ~ $ cd /usr/local/src
[user@host] ~ $ gzip -dc apache_1.3.19.tar.gz|tar xvf -
[user@host] ~ $ cd apache_1.3.19
[user@host] ~ $ ./configure --prefix=/usr/local/apache \
[user@host] ~ $ --enable-module=most \
[user@host] ~ $ --enable-shared=max
[user@host] ~ $ make
[user@host] ~ $ make install

Note: The above steps assume that you downloaded the Apache source and placed it in your /usr/local/src directory.

Apache complains about incorrect module version

Since the Apache API can change between versions, any Apache module contains the Apache API version used to compile the module. This is called the Magic Module Number.

At start time Apache checks that the version in the module header is compatible with the Apache server. If not it will deny to start and log an error.

Note that minor versions are forward compatible. If the module was compiled using Apache 2.x.y the resulting binary should work with any other version 2.x.z where z is bigger or equals to y. If you also need compatibility for versions 2.x.z with z smaller than y, use the configure flag --enable-api-compatibility. Note that the module compiled with any 2.x will never be compatible with 2.y for x different from y.

Does it work for the latest Apache 2.x?

mod_jk works well with Apache 2.x from 2.0 to 2.4.

Important parts of the functionality of mod_jk have been reimplemented as Apache httpd modules mod_proxy_ajp and mod_proxy_balancer. These are part of the standard distributoin of Apache 2.2. The new modules do not contain all features of mod_jk, but you get them automatically with every Apache 2.2 and later.

JNI doesn't work with Apache 1.3

JNI workers have been deprecated. They will likely not work. Do not use them.

JNI support requires a multi-threaded environment which is not the general case for Apache 1.3. You should verify if Apache 1.3 has been build with thread support and if not you could add the the pthreads library to your httpd.conf file.

  # Add pthread to Apache in httpd.conf
  LoadModule "/usr/lib/libpthreads.so"

Also keep in mind that JNI is suited for multi-threaded servers and you should consider upgrading to Apache 2.x to support JNI.

JNI report that JVM couldn't be started under Linux

JNI workers have been deprecated. They will likely not work. Do not use them.

Under Linux, you should set some environment variables BEFORE launching your Apache server :

export LD_LIBRARY_PATH=$jre/bin:$jre/bin/classic:$LD_LIBRARY_PATH

Also some Linux distributions have enabled a GLIBC feature called 'floating stacks' which may not works with kernel less than 2.4.10 on SMP machines. You should disable floating stacks by exporting an environment variable :

export LD_ASSUME_KERNEL=2.2.5

You could have to update your service scripts, ie /etc/rc.d/init.d/httpd, to set these env vars before your httpd server starts.

Mixed errors when building via configure

configure assume you have some GNU tools already installed and configured for your system, and ad minima libtool.

Also some systems may have mixed cc and gcc setup which may make you puzzled when trying to link an Apache built with native c compiler with a jk/jk2 build with gcc.

In case the make processing doesn't work as expected, you should use a GNU make gmake.


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/miscellaneous/reporttools.html0000644000000000000020000001641412555256556023416 0ustar rootbinThe Apache Tomcat Connectors - Miscellaneous Documentation - Reporting Tools
Apache Tomcat :: Apache Software Foundation

Links

Common HowTo

Webserver HowTo

Reference Guide

AJP Protocol Reference

Miscellaneous Documentation

News

The Apache Tomcat Connectors - Miscellaneous Documentation

Reporting Tools

Printer Friendly Version
print-friendly
version
Reporting Tools

The mod_jk source distribution contains two perl scripts in the tools/reports directory which can be used to analyze the mod_jk logs, save statistical data, and generate report graphs.

tomcat_trend.pl log_dir archive_dir

Script for analyzing mod_jk.log data when logging tomcat request data using the JkRequestLogFormat Apache mod_jk configuration. Generates statistics for request latency and errors. Archives the generated data to files for later use in long term trend graphs and reports.

tomcat_reports.pl archive_dir reports_dir

Script for generating reports and graphs using statistical data generated by the tomcat_trend.pl script. The following graphs are created:

  • tomcat_request.png - Long term trend graph of total number of tomcat requests handled.
  • tomcat_median.png - Long term overall trend graph of tomcat request latency median.
  • tomcat_deviation.png - Long term overall trend graph of tomcat request mean and standard deviation.
  • tomcat_error.png - Long term trend graph of requests rejected by tomcat. Shows requests rejected when tomcat has no request processors available. Can be an indicator that tomcat is overloaded or having other scaling problems.
  • tomcat_client.png - Long term trend graph of requests forward to tomcat which were aborted by the remote client (browser). You will normally see some aborted requests. High numbers of these can be an indicator that tomcat is overloaded or there are requests which have very high latency.

A great deal of statistical data is generated but at this time only long term trend graphs are being created and no reports. This is only a start. Many more graphs and reports could be generated from the data. Please consider contributing back any new reports or graphs you create. Thanks.

These perl scripts depend upon the following perl modules and libraries:

  • GD 1.8.x graphics library http://www.boutell.com/gd/
  • GD 1.4.x perl module
  • GD Graph perl module
  • GD TextUtil perl module
  • StatisticsDescriptive perl module


Copyright © 1999-2015, Apache Software Foundation
tomcat-connectors-1.2.41-src/docs/style.css0000644000000000000020000000361112555256553017133 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ div.screen { margin: 10px 0px 10px 20px; font-size: smaller; color: #ffffff; } div.example { background-color: #e5ecf3; color: #000; padding: 0.5em; margin: 1em 2em 1em 1em; } pre { font-family: "Courier New", Courier, monospace; font-weight: normal; font-style: normal; font-size: smaller; } em.screen { font-weight: normal; font-style: normal; color: #c0c0c0; } p.screen { background-color: #000000; border-style: none; color: #c0c0c0; margin-left: 10px; margin-right: 0px; text-align: left; } b.screen { font-weight: normal; font-style: normal; color: #c0c0c0; } code.screen { background-color: #000000; border-style: none; color: #c0c0c0; margin-left: 10px; margin-right: 0px; text-align: left; } b.code { font-weight: normal; font-style: normal; color: #023264; } p.todo { background-color: #ffffff; border-style: none; color: #000000; margin-left: 20px; margin-right: 10px; text-align: justify; font-size: smaller; } tomcat-connectors-1.2.41-src/jkstatus/0000755000000000000020000000000012555256552016177 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/example/0000755000000000000020000000000012555256552017632 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/example/show.xml0000644000000000000020000000401110772307412021317 0ustar rootbin tomcat-connectors-1.2.41-src/jkstatus/example/show.txt0000644000000000000020000000177611111623220021337 0ustar rootbin Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. How to use the show example: ant -f show.xml Configure mod_jk (httpd.conf and workers.properties): JkMount /jkstatus jkstatus worker.list=jkstatus worker.jkstatus.type=status Adjust jkstatus.properties.default: jkstatus.port (for example). tomcat-connectors-1.2.41-src/jkstatus/example/jkstatus.properties.default0000644000000000000020000000201010666607673025241 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. jkstatus.host=localhost jkstatus.port=2090 jkstatus.username=manager jkstatus.password=tomcat jkstatus.url=http://${jkstatus.host}:${jkstatus.port}/jkstatus jkstatus.testlb=loadbalancer jkstatus.testworker=node01 catalina.home=../../../../build/buildtomcat-connectors-1.2.41-src/jkstatus/example/jkstatus.xml0000644000000000000020000001042110772307412022211 0ustar rootbin tomcat-connectors-1.2.41-src/jkstatus/src/0000755000000000000020000000000012555256552016766 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/src/share/0000755000000000000020000000000012555256552020070 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/src/share/org/0000755000000000000020000000000012555256552020657 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/0000755000000000000020000000000012555256552022100 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/0000755000000000000020000000000012555256552022504 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/0000755000000000000020000000000012555256552024027 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/mbeans-descriptors.xml0000644000000000000020000000330610666607673030364 0ustar rootbin tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/JkServer.java0000644000000000000020000000307110537061743026420 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.status; import java.io.Serializable; /** * @author Peter Rossbach * @version $Revision: 485242 $ $Date: 2006-12-10 19:45:39 +0000 (Sun, 10 Dec 2006) $ * @see org.apache.jk.status.JkStatusParser */ public class JkServer implements Serializable { String name ; String port; /** * @return Returns the name. */ public String getName() { return name; } /** * @param name The name to set. */ public void setName(String name) { this.name = name; } /** * @return Returns the port. */ public String getPort() { return port; } /** * @param port The port to set. */ public void setPort(String port) { this.port = port; } } tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/JkResult.java0000644000000000000020000000275411237120030026416 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.status; import java.io.Serializable; /** * @author Peter Rossbach * @version $Revision: 802231 $ $Date: 2009-08-07 22:43:52 +0100 (Fri, 07 Aug 2009) $ * @see org.apache.jk.status.JkStatusParser */ public class JkResult implements Serializable { String type ; String message; /** * @return the message */ public String getMessage() { return message; } /** * @param message the message to set */ public void setMessage(String message) { this.message = message; } /** * @return the type */ public String getType() { return type; } /** * @param type the type to set */ public void setType(String type) { this.type = type; } } tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/JkStatusParser.java0000644000000000000020000002010311156416545027607 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.status; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.tomcat.util.digester.Digester; /** * mod_jk 1.2.19 document:
* * * <?xml version="1.0" encoding="UTF-8" ?> * <jk:status xmlns:jk="http://tomcat.apache.org"> * <jk:server name="localhost" port="2010" software="Apache/2.0.58 (Unix) mod_jk/1.2.19-dev" version="1.2.19" /> * <jk:balancers> * <jk:balancer id="0" name="loadbalancer" type="lb" sticky="True" stickyforce="False" retries="2" recover="60" > * <jk:member id="0" name="node01" type="ajp13" host="localhost" port="20012" address="127.0.0.1:20012" activation="ACT" state="N/A" distance="0" lbfactor="1" lbmult="1" lbvalue="0" elected="0" errors="0" transferred="0" readed="0" busy="0" maxbusy="0" jvm_route="node01" /> * <jk:member id="1" name="node02" type="ajp13" host="localhost" port="20022" address="127.0.0.1:20022" activation="ACT" state="N/A" distance="0" lbfactor="1" lbmult="1" lbvalue="0" elected="0" errors="0" transferred="0" readed="0" busy="0" maxbusy="0" jvm_route="node02" /> * <jk:map type="Wildchar" uri="/ClusterSession*" context="/ClusterSession*" /> * <jk:map type="Wildchar" uri="/ClusterTest*" context="/ClusterTest*" /> * <jk:map type="Wildchar" uri="/test*" context="/test*" /> * </jk:balancer> * </jk:balancers> * </jk:status> * *
* mod_jk 1.2.20 document:
* * <?xml version="1.0" encoding="UTF-8" ?> * <jk:status xmlns:jk="http://tomcat.apache.org"> * <jk:server * name="127.0.0.1" * port="2080" * software="Apache/2.0.59 (Unix) mod_jk/1.2.20-dev" * version="1.2.20"/> * <jk:balancers> * <jk:balancer * name="loadbalancer" * type="lb" * sticky="True" * stickyforce="False" * retries="2" * recover="60" * method="Request" * lock="Optimistic" * good="2" * degraded="0" * bad="0" * busy="0" * max_busy="0"> * <jk:member * name="node01" * type="ajp13" * host="localhost" * port="7309" * address="127.0.0.1:7309" * activation="ACT" * lbfactor="1" * jvm_route="node01" * redirect="" * domain="" * distance="0" * state="N/A" * lbmult="1" * lbvalue="0" * elected="0" * errors="0" * clienterrors="0" * transferred="0" * readed="0" * busy="0" * maxbusy="0" * time-to-recover="0"/> * <jk:member * name="node02" * type="ajp13" * host="localhost" * port="7409" * address="127.0.0.1:7409" * activation="ACT" * lbfactor="1" * jvm_route="node02" * redirect="" * domain="" * distance="0" * state="N/A" * lbmult="1" * lbvalue="0" * elected="0" * errors="0" * clienterrors="0" * transferred="0" * readed="0" * busy="0" * maxbusy="0" * time-to-recover="0"/> * <jk:map * type="Wildchar" * uri="/ClusterTest*" * source="JkMount"/> * <jk:map * type="Wildchar" * uri="/myapps*" * source="JkMount"/> * <jk:map * type="Wildchar" * uri="/last*" * source="JkMount"/> * </jk:balancer> * </jk:balancers> * </jk:status> * * * *
* mod_jk 1.2.24 runtime state N/A changed to OK/IDLE:
* * state="OK/IDLE" * * @author Peter Rossbach * @version $Revision: 753168 $ $Date: 2009-03-13 08:46:29 +0000 (Fri, 13 Mar 2009) $ * @since 5.5.10 */ public class JkStatusParser { private static Log log = LogFactory.getLog(JkStatusParser.class); /** * The descriptive information about this implementation. */ private static final String info = "org.apache.jk.status.JkStatusParser/1.1"; /** * Return descriptive information about this implementation and the * corresponding version number, in the format * <description>/<version>. */ public String getInfo() { return (info); } /** * The Digester instance used to parse registry descriptors. */ public static final Digester digester = createDigester(); public static Digester getDigester() { return digester; } /** * Create and configure the Digester we will be using for setup mod_jk jk status page. */ public static Digester createDigester() { long t1 = System.currentTimeMillis(); // Initialize the digester Digester digester = new Digester(); digester.setValidating(false); digester.setClassLoader(JkStatus.class.getClassLoader()); // parse status digester.addObjectCreate("jk:status", "org.apache.jk.status.JkStatus", "className"); digester.addSetProperties("jk:status"); digester.addObjectCreate("jk:status/jk:server", "org.apache.jk.status.JkServer", "className"); digester.addSetProperties("jk:status/jk:server"); digester.addSetNext("jk:status/jk:server", "setServer", "org.apache.jk.status.JkServer"); digester.addObjectCreate("jk:status/jk:software", "org.apache.jk.status.JkSoftware", "className"); digester.addSetProperties("jk:status/jk:software"); digester.addSetNext("jk:status/jk:software", "setSoftware", "org.apache.jk.status.JkSoftware"); digester.addObjectCreate("jk:status/jk:result", "org.apache.jk.status.JkResult", "className"); digester.addSetProperties("jk:status/jk:result"); digester.addSetNext("jk:status/jk:result", "setResult", "org.apache.jk.status.JkResult"); digester.addObjectCreate("jk:status/jk:balancers/jk:balancer", "org.apache.jk.status.JkBalancer", "className"); digester.addSetProperties("jk:status/jk:balancers/jk:balancer"); digester.addSetNext("jk:status/jk:balancers/jk:balancer", "addBalancer", "org.apache.jk.status.JkBalancer"); digester.addObjectCreate( "jk:status/jk:balancers/jk:balancer/jk:member", "org.apache.jk.status.JkBalancerMember", "className"); digester .addSetProperties("jk:status/jk:balancers/jk:balancer/jk:member"); digester.addSetNext("jk:status/jk:balancers/jk:balancer/jk:member", "addBalancerMember", "org.apache.jk.status.JkBalancerMember"); digester.addObjectCreate("jk:status/jk:balancers/jk:balancer/jk:map", "org.apache.jk.status.JkBalancerMapping", "className"); digester.addSetProperties("jk:status/jk:balancers/jk:balancer/jk:map"); digester.addSetNext("jk:status/jk:balancers/jk:balancer/jk:map", "addBalancerMapping", "org.apache.jk.status.JkBalancerMapping"); long t2 = System.currentTimeMillis(); if (log.isDebugEnabled()) log.debug("Digester for apache mod_jk jkstatus page is created " + (t2 - t1)); return (digester); } } tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/JkStatusUpdateTask.java0000644000000000000020000003512410742535672030434 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.status; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import org.apache.catalina.ant.AbstractCatalinaTask; import org.apache.tools.ant.BuildException; /** * Ant task that implements the /status command, supported by the * mod_jk status (1.2.13) application. * * * @author Peter Rossbach * @version $Revision: 611693 $ * @since 5.5.10 * @deprecated */ public class JkStatusUpdateTask extends AbstractCatalinaTask { /** * The descriptive information about this implementation. */ private static final String info = "org.apache.jk.status.JkStatusUpdateTask/1.1"; private String worker = "lb"; private String workerType = "lb"; private int internalid = 0; private Integer lbRetries; private Integer lbRecovertime; private Boolean lbStickySession = Boolean.TRUE; private Boolean lbForceSession = Boolean.FALSE; private Integer workerLoadFactor; private String workerJvmRoute ; private int workerDistance = -1; private String workerRedirect; private String workerClusterDomain; private Boolean workerDisabled ; private Boolean workerStopped ; private int workerActivation = -1; private boolean isLBMode = true; private String workerLb; /** * Return descriptive information about this implementation and the * corresponding version number, in the format * <description>/<version>. */ public String getInfo() { return (info); } /** * */ public JkStatusUpdateTask() { super(); setUrl("http://localhost/jkstatus"); } /** * @return Returns the workerDistance. */ public int getWorkerDistance() { return workerDistance; } /** * @param workerDistance The workerDistance to set. */ public void setWorkerDistance(int workerDistance) { this.workerDistance = workerDistance; } /** * @return Returns the workerJvmRoute. */ public String getWorkerJvmRoute() { return workerJvmRoute; } /** * @param workerJvmRoute The workerJvmRoute to set. */ public void setWorkerJvmRoute(String workerJvmRoute) { this.workerJvmRoute = workerJvmRoute; } /** * @return Returns the internalid. */ public int getInternalid() { return internalid; } /** * @param internalid * The internalid to set. */ public void setInternalid(int internalid) { this.internalid = internalid; } /** * @return Returns the lbForceSession. */ public Boolean getLbForceSession() { return lbForceSession; } /** * @param lbForceSession * The lbForceSession to set. */ public void setLbForceSession(Boolean lbForceSession) { this.lbForceSession = lbForceSession; } /** * @return Returns the lbRecovertime. */ public Integer getLbRecovertime() { return lbRecovertime; } /** * @param lbRecovertime * The lbRecovertime to set. */ public void setLbRecovertime(Integer lbRecovertime) { this.lbRecovertime = lbRecovertime; } /** * @return Returns the lbRetries. */ public Integer getLbRetries() { return lbRetries; } /** * @param lbRetries * The lbRetries to set. */ public void setLbRetries(Integer lbRetries) { this.lbRetries = lbRetries; } /** * @return Returns the lbStickySession. */ public Boolean getLbStickySession() { return lbStickySession; } /** * @param lbStickySession * The lbStickySession to set. */ public void setLbStickySession(Boolean lbStickySession) { this.lbStickySession = lbStickySession; } /** * @return Returns the worker. */ public String getWorker() { return worker; } /** * @param worker * The worker to set. */ public void setWorker(String worker) { this.worker = worker; } /** * @return Returns the workerType. */ public String getWorkerType() { return workerType; } /** * @param workerType * The workerType to set. */ public void setWorkerType(String workerType) { this.workerType = workerType; } /** * @return Returns the workerLb. */ public String getWorkerLb() { return workerLb; } /** * @param workerLb * The workerLb to set. */ public void setWorkerLb(String workerLb) { this.workerLb = workerLb; } /** * @return Returns the workerClusterDomain. */ public String getWorkerClusterDomain() { return workerClusterDomain; } /** * @param workerClusterDomain * The workerClusterDomain to set. */ public void setWorkerClusterDomain(String workerClusterDomain) { this.workerClusterDomain = workerClusterDomain; } /** * @return Returns the workerDisabled. */ public Boolean getWorkerDisabled() { return workerDisabled; } /** * @param workerDisabled * The workerDisabled to set. */ public void setWorkerDisabled(Boolean workerDisabled) { this.workerDisabled = workerDisabled; } /** * @return Returns the workerActivation. */ public int getWorkerActivation() { return workerActivation; } /** *
    *
  • 0 active
  • *
  • 1 disabled
  • *
  • 2 stopped
  • *
* @param workerActivation The workerActivation to set. * */ public void setWorkerActivation(int workerActivation) { this.workerActivation = workerActivation; } /** * @return Returns the workerStopped. */ public Boolean getWorkerStopped() { return workerStopped; } /** * @param workerStopped The workerStopped to set. */ public void setWorkerStopped(Boolean workerStopped) { this.workerStopped = workerStopped; } /** * @return Returns the workerLoadFactor. */ public Integer getWorkerLoadFactor() { return workerLoadFactor; } /** * @param workerLoadFactor * The workerLoadFactor to set. */ public void setWorkerLoadFactor(Integer workerLoadFactor) { this.workerLoadFactor = workerLoadFactor; } /** * @return Returns the workerRedirect. */ public String getWorkerRedirect() { return workerRedirect; } /** * @param workerRedirect * The workerRedirect to set. */ public void setWorkerRedirect(String workerRedirect) { this.workerRedirect = workerRedirect; } /** * Execute the requested operation. * * @exception BuildException * if an error occurs */ public void execute() throws BuildException { super.execute(); checkParameter(); StringBuffer sb = createLink(); execute(sb.toString(), null, null, -1); } /** * Create JkStatus link *
    *
  • load balance example: * http://localhost/jkstatus?cmd=update&mime=txt&w=lb&vlf=false&vls=true
  • *
  • worker example: * http://localhost/jkstatus?cmd=update&mime=txt&w=lb&sw=node1&vwn=node01&vwf=1&vwa=2&vwx=0 *
    *
      *
    • vwa=0 active
    • *
    • vwa=1 disabled
    • *
    • vwa=2 stopped
    • *
    *
  • *
* *
Loadbalacing parameter: *
*
    *
  • w: name lb worker
  • *
  • vlr: Number of Retries
  • *
  • vlt: recover wait time
  • *
  • vlf: Force Sticky Session
  • *
  • vls: Sticky session
  • *
* *
Tcp worker parameter: *
*
    *
  • w: name worker
  • *
  • sw: name lb sub worker
  • *
  • vwf: load factor
  • *
  • vwn: jvm route
  • *
  • vwx: distance
  • *
  • vwa: activation state
  • *
  • vwr: redirect route
  • *
  • vwd: cluster domain
  • *
  • ws: stopped deprecated 1.2.16
  • *
  • wd: disabled deprecated 1.2.16
  • *
* * @return create jkstatus link */ private StringBuffer createLink() { // Building URL StringBuffer sb = new StringBuffer(); try { sb.append("?cmd=update&mime=txt"); sb.append("&w="); if (isLBMode) { sb.append(URLEncoder.encode(worker, getCharset())); //http://localhost/jkstatus?cmd=update&mime=txt&w=lb&vlf=false&vls=true if ((lbRetries != null)) { // > 0 sb.append("&vlr="); sb.append(lbRetries); } if ((lbRecovertime != null)) { // > 59 sb.append("&vlt="); sb.append(lbRecovertime); } if ((lbStickySession != null)) { sb.append("&vls="); sb.append(lbStickySession); } if ((lbForceSession != null)) { sb.append("&vlf="); sb.append(lbForceSession); } } else { //http://localhost/status?cmd=update&mime=txt&sw=node1&w=lb&vwf=1&wd=false&ws=false if (workerLb != null) { // must be configured sb.append(URLEncoder.encode(workerLb, getCharset())); } sb.append("&sw="); sb.append(URLEncoder.encode(worker, getCharset())); if (workerLoadFactor != null) { // >= 1 sb.append("&vwf="); sb.append(workerLoadFactor); } if (workerJvmRoute != null) { sb.append("&vwn="); sb.append(URLEncoder.encode(workerJvmRoute, getCharset())); } if (workerDisabled != null) { sb.append("&vwd="); sb.append(workerDisabled); } if (workerStopped != null) { sb.append("&vws="); sb.append(workerStopped); } if (workerActivation >= 0 && workerActivation < 3) { sb.append("&vwa="); sb.append(workerActivation); } if (workerDistance >= 0) { sb.append("&vwx="); sb.append(workerDistance); } if (workerRedirect != null) { // other worker conrecte lb's sb.append("&vwr="); sb.append(URLEncoder.encode(workerRedirect, getCharset())); } if (workerClusterDomain != null) { sb.append("&vwc="); sb.append(URLEncoder.encode(workerClusterDomain, getCharset())); } } } catch (UnsupportedEncodingException e) { throw new BuildException("Invalid 'charset' attribute: " + getCharset()); } return sb; } /** * check correct lb and worker pararmeter */ protected void checkParameter() { if (worker == null) { throw new BuildException("Must specify 'worker' attribute"); } if (workerType == null) { throw new BuildException("Must specify 'workerType' attribute"); } if ("lb".equals(workerType)) { if (lbRecovertime == null && lbRetries == null) { throw new BuildException( "Must specify at a lb worker either 'lbRecovertime' or" + "'lbRetries' attribute"); } if (lbStickySession == null || lbForceSession == null) { throw new BuildException("Must specify at a lb worker either" + "'lbStickySession' and 'lbForceSession' attribute"); } if (null != lbRecovertime && 60 < lbRecovertime.intValue()) { throw new BuildException( "The 'lbRecovertime' must be greater than 59"); } if (null != lbRetries && 1 < lbRetries.intValue()) { throw new BuildException( "The 'lbRetries' must be greater than 1"); } isLBMode = true; } else if ("worker".equals(workerType)) { if (workerLoadFactor == null ) { throw new BuildException( "Must specify at a node worker 'workerLoadFactor' attribute"); } if (workerClusterDomain == null) { throw new BuildException( "Must specify at a node worker 'workerClusterDomain' attribute"); } if (workerRedirect == null) { throw new BuildException( "Must specify at a node worker 'workerRedirect' attribute"); } if (workerLb == null) { throw new BuildException("Must specify 'workerLb' attribute"); } if (workerLoadFactor.intValue() < 1) { throw new BuildException( "The 'workerLoadFactor' must be greater or equal 1"); } isLBMode = false; } else { throw new BuildException( "Only 'lb' and 'worker' supported as workerType attribute"); } } } tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/JkStatus.java0000644000000000000020000000452510537061743026442 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.status; import java.io.Serializable; import java.util.ArrayList; import java.util.List; /** * @author Peter Rossbach * @version $Revision: 485242 $ $Date: 2006-12-10 19:45:39 +0000 (Sun, 10 Dec 2006) $ * @see org.apache.jk.status.JkStatusParser */ public class JkStatus implements Serializable { JkServer server ; JkSoftware software ; JkResult result ; List balancers = new ArrayList() ; /** * @return Returns the balancers. */ public List getBalancers() { return balancers; } /** * @param balancers The balancers to set. */ public void setBalancers(List balancers) { this.balancers = balancers; } public void addBalancer(JkBalancer balancer) { balancers.add(balancer); } public void removeBalancer(JkBalancer balancer) { balancers.remove(balancer); } /** * @return Returns the server. */ public JkServer getServer() { return server; } public void setServer(JkServer server) { this.server = server ; } /** * @return the result */ public JkResult getResult() { return result; } /** * @param result the result to set */ public void setResult(JkResult result) { this.result = result; } /** * @return Returns the software. */ public JkSoftware getSoftware() { return software; } /** * @param software The software to set. */ public void setSoftware(JkSoftware software) { this.software = software; } } ././@LongLink0000644000000000000000000000015100000000000011600 Lustar rootroottomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/JkStatusUpdateLoadbalancerTask.javatomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/JkStatusUpdateLoadbalancerTask.0000644000000000000020000001601310742535672032056 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.status; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import org.apache.tools.ant.BuildException; /** * Ant task that implements the /status update loadbalancer command, supported by the * mod_jk status (1.2.20) application. * * * @author Peter Rossbach * @version $Revision: 611693 $ * @since mod_jk 1.2.20 */ public class JkStatusUpdateLoadbalancerTask extends AbstractJkStatusTask { /** * The descriptive information about this implementation. */ private static final String info = "org.apache.jk.status.JkStatusUpdateLoadbalancerTask/1.0"; protected String loadbalancer ; protected int retries = -1; protected int recoverWaitTime = -1; protected int methodCode = -1; protected String method; protected Boolean stickySession ; protected Boolean forceStickySession ; protected int lockCode = -1; protected String lock; protected int maxReplyTimeouts = -1; /** * Return descriptive information about this implementation and the * corresponding version number, in the format * <description>/<version>. */ public String getInfo() { return (info); } /** * */ public JkStatusUpdateLoadbalancerTask() { super(); setUrl("http://localhost/jkstatus"); } /** * @return the forceStickySession */ public Boolean getForceStickySession() { return forceStickySession; } /** * @param forceStickySession the forceStickySession to set */ public void setForceStickySession(Boolean forceStickySession) { this.forceStickySession = forceStickySession; } /** * @return the loadbalancer */ public String getLoadbalancer() { return loadbalancer; } /** * @param loadbalancer the loadbalancer to set */ public void setLoadbalancer(String loadbalancer) { this.loadbalancer = loadbalancer; } /** * @return the locking */ public String getLock() { return lock; } /** * @param locking the locking to set */ public void setLock(String locking) { this.lock = locking; } /** * @return the lockingCode */ public int getLockCode() { return lockCode; } /** * @param lockingCode the lockingCode to set */ public void setLockCode(int lockingCode) { this.lockCode = lockingCode; } /** * @return the method */ public String getMethod() { return method; } /** * @param method the method to set */ public void setMethod(String method) { this.method = method; } /** * @return the methodCode */ public int getMethodCode() { return methodCode; } /** * @param methodCode the methodCode to set */ public void setMethodCode(int methodCode) { this.methodCode = methodCode; } /** * @return the recoverWaitTime */ public int getRecoverWaitTime() { return recoverWaitTime; } /** * @param recoverWaitTime the recoverWaitTime to set */ public void setRecoverWaitTime(int recoverWaitTime) { this.recoverWaitTime = recoverWaitTime; } /** * @return the retries */ public int getRetries() { return retries; } /** * @param retries the retries to set */ public void setRetries(int retries) { this.retries = retries; } /** * @return the stickySession */ public Boolean getStickySession() { return stickySession; } /** * @param stickySession the stickySession to set */ public void setStickySession(Boolean stickySession) { this.stickySession = stickySession; } /** * @return the maxReplyTimeouts */ public int getMaxReplyTimeouts() { return maxReplyTimeouts; } /** * @param maxReplyTimeouts the maxReplyTimeouts to set */ public void setMaxReplyTimeouts(int maxReplyTimeouts) { this.maxReplyTimeouts = maxReplyTimeouts; } /** * Create JkStatus worker update link *
    * http://localhost/jkstatus?cmd=update&mime=txt&w=loadbalancer&vlm=1&vll=1&vlr=2&vlt=60&vls=true&vlf=false&vlx=0 *
    * * *
    Tcp worker parameter: *
    *
      *
    • w: name loadbalancer
    • *
    • vlm: method (lb strategy)
    • *
    • vll: lock
    • *
    • vlr: retries
    • *
    • vlt: recover wait timeout
    • *
    • vls: sticky session
    • *
    • vlf: force sticky session
    • *
    • vlx: max reply timeouts
    • *
    *
      *
    • vlm=0 or Requests
    • *
    • vlm=1 or Traffic
    • *
    • vlm=2 or Busyness
    • *
    • vlm=3 or Sessions
    • *
    *
      *
    • vll=0 or Optimistic
    • *
    • vll=1 or Pessimistic
    • *
    * * @return create jkstatus update worker link */ protected StringBuffer createLink() { // Building URL StringBuffer sb = new StringBuffer(); try { sb.append("?cmd=update&mime=txt"); sb.append("&w="); sb.append(URLEncoder.encode(loadbalancer, getCharset())); if (stickySession != null) { sb.append("&vls="); sb.append(stickySession); } if (forceStickySession != null) { sb.append("&vlf="); sb.append(forceStickySession); } if (retries >= 0) { sb.append("&vlr="); sb.append(retries); } if (recoverWaitTime >= 0) { sb.append("&vlt="); sb.append(recoverWaitTime); } if (method == null && methodCode >= 0 && methodCode < 4) { sb.append("&vlm="); sb.append(methodCode); } if (method != null) { sb.append("&vlm="); sb.append(method); } if (lock == null && lockCode >= 0 && lockCode < 2) { sb.append("&vll="); sb.append(lockCode); } if (lock != null) { sb.append("&vll="); sb.append(lock); } if (maxReplyTimeouts >= 0) { sb.append("&vlx="); sb.append(maxReplyTimeouts); } } catch (UnsupportedEncodingException e) { throw new BuildException("Invalid 'charset' attribute: " + getCharset()); } return sb; } /** * check correct lb and worker pararmeter */ protected void checkParameter() { if (loadbalancer == null) { throw new BuildException("Must specify 'loadbalancer' attribute"); } } } tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/package.html0000644000000000000020000001313210666607673026315 0ustar rootbin

    This package contains a set of Task implementations for Ant (version 1.6.x or later) that can be used to interact with the Apaache mod_jk status page to show, update, disable and stop mod_jk worker. For more information, see JK Documenation.

    The attributes of each task element correspond exactly to the request parameters that are included with an HTTP request sent directly to jk status page. They are summarized as follows:

    General parameter
    Attribute Description
    url The URL of the jk status page you will use to perform the requested operations. If not specified, defaults to http://localhost:80/jkstatus (which corresponds to a standard installation of Apache mod_jk).
    username The username of a mod_jk status user that has been configured with the Allow user Apache Location constraint. This attribute is optional.
    password The password of a mod_jk status user that has been configured with the Allow user Apache Location constraint. This attribute is optional.
    resultProperty Bind all show results with this prefix property name. This attribute is optional.
    echo show result at ant console. (default false)
    errorProperty set this property, as a failure detected. This attribute is optional.
    Command show parameter
    Attribute Description
    worker only bind properties from this balancer tcp worker (node)
    loadbalancer only bind properties from this loadbalancer worker
    Command reset parameter
    Attribute Description
    workerLb name of loadbalancer worker.
    Command update loadbalancer parameter
    Attribute Description
    workerType=loadbalancer type of update
    workerLb name of loadbalancer worker.
    lbForceSession Force Sticky Session. (true/false)
    lbStickySession Sticky Session. (true/false)
    lbRetries loadbalancer retries after worker connection failure (int)
    lbRecovertime Recover timeout after a worker set to "error" state (int sec's)
    Command update worker parameter
    Attribute Description
    workerType=worker type of update
    worker name of tcp worker.
    workerActivation (>=1.2.19 set worker activation (1 Active, 2 Disabled, 3 Stopped)
    workerDisabled (< 1.2.19) set disable state. (true/false)
    workerStoppend (< 1.2.19) set stopped state. (true/false)
    workerJvmRoute set jvm route
    workerLaodFactor set load factor (int)
    workerDistance set worker distance (int)
    workerRedirect other worker name to redirect after failure
    workerClusterDomain cluster domain name, group of worker at a repliation cluster.
    tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/JkSoftware.java0000644000000000000020000000322511237120030026724 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.status; import java.io.Serializable; /** * @author Peter Rossbach * @version $Revision: 802231 $ $Date: 2009-08-07 22:43:52 +0100 (Fri, 07 Aug 2009) $ * @see org.apache.jk.status.JkStatusParser */ public class JkSoftware implements Serializable { String web_server; String jk_version ; /** * @return Returns the software. */ public String getWeb_server() { return web_server; } /** * @param software The software to set. */ public void setWeb_server(String software) { this.web_server = software; } /** * @return Returns the version. */ public String getJk_version() { return jk_version; } /** * @param version The version to set. */ public void setJk_version(String version) { this.jk_version = version; } } tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/JkBalancer.java0000644000000000000020000001732110556673355026675 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.status; import java.io.Serializable; import java.util.ArrayList; import java.util.List; /** * @author Peter Rossbach * @version $Revision: 500555 $ $Date: 2007-01-27 15:59:41 +0000 (Sat, 27 Jan 2007) $ * @see org.apache.jk.status.JkStatusParser */ public class JkBalancer implements Serializable { int id =-1; String name ; String type ; boolean sticky ; boolean stickyforce; int retries ; int recover ; String method ; String lock ; int good = -1 ; int degraded = -1; int bad = -1 ; int busy = -1; int max_busy = -1 ; int member_count = -1 ; int map_count = -1 ; int time_to_maintenance_min = -1 ; int time_to_maintenance_max = -1 ; List members = new ArrayList() ; List mappings = new ArrayList() ; /** * @return Returns the id. */ public int getId() { return id; } /** * @param id The id to set. */ public void setId(int id) { this.id = id; } /** * @return Returns the mappings. */ public List getBalancerMappings() { return mappings; } /** * @param mappings The mappings to set. */ public void setBalancerMappings(List mappings) { this.mappings = mappings; } public void addBalancerMapping(JkBalancerMapping mapping) { mappings.add(mapping); } public void removeBalancerMapping(JkBalancerMapping mapping) { mappings.remove(mapping); } /** * @return Returns the members. */ public List getBalancerMembers() { return members; } /** * @param members The members to set. */ public void setBalancerMembers(List members) { this.members = members; } public void addBalancerMember(JkBalancerMember member) { members.add(member); } public void removeBalancerMember(JkBalancerMember member) { members.remove(member); } /** * @return Returns the name. */ public String getName() { return name; } /** * @param name The name to set. */ public void setName(String name) { this.name = name; } /** * @return Returns the recover. */ public int getRecover_time() { return recover; } /** * @param recover The recover to set. */ public void setRecover_time(int recover) { this.recover = recover; } /** * @return Returns the retries. */ public int getRetries() { return retries; } /** * @param retries The retries to set. */ public void setRetries(int retries) { this.retries = retries; } /** * @return Returns the sticky. */ public boolean isSticky_session() { return sticky; } /** * @param sticky The sticky to set. */ public void setSticky_session(boolean sticky) { this.sticky = sticky; } /** * @return Returns the stickyforce. */ public boolean isSticky_session_force() { return stickyforce; } /** * @param stickyforce The stickyforce to set. */ public void setSticky_session_force(boolean stickyforce) { this.stickyforce = stickyforce; } /** * @return Returns the type. */ public String getType() { return type; } /** * @param type The type to set. */ public void setType(String type) { this.type = type; } /** * @return the bad * @since mod_jk 1.2.20 */ public int getBad() { return bad; } /** * @param bad the bad to set * @since mod_jk 1.2.20 */ public void setBad(int bad) { this.bad = bad; } /** * @return the busy * @since mod_jk 1.2.20 */ public int getBusy() { return busy; } /** * @param busy the busy to set * @since mod_jk 1.2.20 */ public void setBusy(int busy) { this.busy = busy; } /** * @return the degraded * @since mod_jk 1.2.20 */ public int getDegraded() { return degraded; } /** * @param degraded the degraded to set * @since mod_jk 1.2.20 */ public void setDegraded(int degraded) { this.degraded = degraded; } /** * @return the good * @since mod_jk 1.2.20 */ public int getGood() { return good; } /** * @param good the good to set * @since mod_jk 1.2.20 */ public void setGood(int good) { this.good = good; } /** * @return the lock * @since mod_jk 1.2.20 */ public String getLock() { return lock; } /** * @param lock the lock to set * @since mod_jk 1.2.20 */ public void setLock(String lock) { this.lock = lock; } /** * @return the max_busy * @since mod_jk 1.2.20 */ public int getMax_busy() { return max_busy; } /** * @param max_busy the max_busy to set * @since mod_jk 1.2.20 */ public void setMax_busy(int max_busy) { this.max_busy = max_busy; } /** * @return the method * @since mod_jk 1.2.20 */ public String getMethod() { return method; } /** * @param method the method to set * @since mod_jk 1.2.20 */ public void setMethod(String method) { this.method = method; } /** * @return the member_count * @since mod_jk 1.2.20 */ public int getMember_count() { return member_count; } /** * @param member_count the member_count to set * @since mod_jk 1.2.20 */ public void setMember_count(int member_count) { this.member_count = member_count; } /** * @return the map_count * @since mod_jk 1.2.20 */ public int getMap_count() { return map_count; } /** * @param map_count the map_count to set * @since mod_jk 1.2.20 */ public void setMap_count(int map_count) { this.map_count = map_count; } /** * @return the time_to_maintenance_min * @since mod_jk 1.2.21 */ public int getTime_to_maintenance_min() { return time_to_maintenance_min; } /** * @param time_to_maintenance_min the time_to_maintenance_min to set * @since mod_jk 1.2.21 */ public void setTime_to_maintenance_min(int time_to_maintenance_min) { this.time_to_maintenance_min = time_to_maintenance_min; } /** * @return the time_to_maintenance_max * @since mod_jk 1.2.21 */ public int getTime_to_maintenance_max() { return time_to_maintenance_max; } /** * @param time_to_maintenance_max the time_to_maintenance_max to set * @since mod_jk 1.2.21 */ public void setTime_to_maintenance_max(int time_to_maintenance_max) { this.time_to_maintenance_max = time_to_maintenance_max; } } tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/JkBalancerMapping.java0000644000000000000020000000450610537061743030201 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.status; import java.io.Serializable; /** * @author Peter Rossbach * @version $Revision: 485242 $ $Date: 2006-12-10 19:45:39 +0000 (Sun, 10 Dec 2006) $ * @see org.apache.jk.status.JkStatusParser */ public class JkBalancerMapping implements Serializable { int id =-1 ; String type ; String uri; String context ; String source ; /** * @return the id */ public int getId() { return id; } /** * @param id the id to set */ public void setId(int id) { this.id = id; } /** * @return Returns the context. * @deprecated mod_jk 1.2.20 */ public String getContext() { return context; } /** * @param context The context to set. * @deprecated mod_jk 1.2.20 */ public void setContext(String context) { this.context = context; } /** * @return Returns the type. */ public String getType() { return type; } /** * @param type The type to set. */ public void setType(String type) { this.type = type; } /** * @return Returns the uri. */ public String getUri() { return uri; } /** * @param uri The uri to set. */ public void setUri(String uri) { this.uri = uri; } /** * @return the source * @since mod_jk 1.2.20 */ public String getSource() { return source; } /** * @param source the source to set * @since mod_jk 1.2.20 */ public void setSource(String source) { this.source = source; } } tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/JkStatusResetTask.java0000644000000000000020000000675210537061743030274 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.status; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import org.apache.tools.ant.BuildException; /** * Ant task that implements the /jkstatus?cmd=reset&w=loadbalancer command, supported by the * mod_jk status (1.2.20) application. * * @author Peter Rossbach * @version $Revision: 485242 $ * @since mod_jk 1.2.20 */ public class JkStatusResetTask extends AbstractJkStatusTask { /** * The descriptive information about this implementation. */ private static final String info = "org.apache.jk.status.JkStatusResetTask/1.1"; private String worker; private String loadbalancer; /** * */ public JkStatusResetTask() { super(); setUrl("http://localhost/jkstatus"); } /** * Return descriptive information about this implementation and the * corresponding version number, in the format * <description>/<version>. */ public String getInfo() { return (info); } /** * @return the loadbalancer */ public String getLoadbalancer() { return loadbalancer; } /** * @param loadbalancer the loadbalancer to set */ public void setLoadbalancer(String loadbalancer) { this.loadbalancer = loadbalancer; } /** * @return the worker */ public String getWorker() { return worker; } /** * @param worker the worker to set */ public void setWorker(String worker) { this.worker = worker; } /** * Create jkstatus reset link *
      *
    • loadbalancer example: * http://localhost/jkstatus?cmd=reset&mime=txt&w=loadbalancer
    • *
    • loadbalancer + sub worker example: * http://localhost/jkstatus?cmd=reset&mime=txt&w=loadbalancer&sw=node01
    • *
    * * @return create jkstatus reset link */ protected StringBuffer createLink() { // Building URL StringBuffer sb = new StringBuffer(); try { sb.append("?cmd=reset"); sb.append("&mime=txt"); sb.append("&w="); sb.append(URLEncoder.encode(loadbalancer, getCharset())); if(worker != null) { sb.append("&sw="); sb.append(URLEncoder.encode(worker, getCharset())); } } catch (UnsupportedEncodingException e) { throw new BuildException("Invalid 'charset' attribute: " + getCharset()); } return sb; } /** * check correct pararmeter */ protected void checkParameter() { if (loadbalancer == null) { throw new BuildException("Must specify 'loadbalanacer' attribute"); } } }tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/jkstatus.tasks0000644000000000000020000000210010666607673026744 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Apache mod_jk jk status tasks jkUpdateWorker=org.apache.jk.status.JkStatusUpdateWorkerTask jkUpdateLoadbalancer=org.apache.jk.status.JkStatusUpdateLoadbalancerTask jkUpdate=org.apache.jk.status.JkStatusUpdateTask jkReset=org.apache.jk.status.JkStatusResetTask jkStatus=org.apache.jk.status.JkStatusTask tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/JkStatusTask.java0000644000000000000020000007134111156031227027255 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.status; import java.util.Iterator; import java.util.List; import org.apache.catalina.ant.BaseRedirectorHelperTask; import org.apache.tomcat.util.IntrospectionUtils; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; /** * Ant task that implements the show /jkstatus command, supported * by the mod_jk status (1.2.13) application. * * @author Peter Rossbach * @version $Revision: 752644 $ * @since 5.5.10 */ public class JkStatusTask extends BaseRedirectorHelperTask { /** * The descriptive information about this implementation. */ private static final String info = "org.apache.jk.status.JkStatusTask/1.2"; /** * Store status as resultProperty prefix. */ protected String resultproperty; /** * Echo status at ant console */ protected boolean echo = false; /** * The login password for the mod_jk status page. */ protected String password = null; /** * The URL of the mod_jk status page to be used. */ protected String url = "http://localhost:80/jkstatus"; /** * The login username for the mod_jk status page. */ protected String username = null; private String errorProperty; private String worker; private String loadbalancer; /** * Return descriptive information about this implementation and the * corresponding version number, in the format * <description>/<version>. */ public String getInfo() { return (info); } public String getPassword() { return (this.password); } public void setPassword(String password) { this.password = password; } public String getUrl() { return (this.url); } public void setUrl(String url) { this.url = url; } public String getUsername() { return (this.username); } public void setUsername(String username) { this.username = username; } /** * @return Returns the echo. */ public boolean isEcho() { return echo; } /** * @param echo * The echo to set. */ public void setEcho(boolean echo) { this.echo = echo; } /** * @return Returns the resultproperty. */ public String getResultproperty() { return resultproperty; } /** * @param resultproperty * The resultproperty to set. */ public void setResultproperty(String resultproperty) { this.resultproperty = resultproperty; } /** * @return Returns the loadbalancer. */ public String getLoadbalancer() { return loadbalancer; } /** * @param loadbalancer The loadbalancer to set. */ public void setLoadbalancer(String loadbalancer) { this.loadbalancer = loadbalancer; } /** * @return Returns the worker. */ public String getWorker() { return worker; } /** * @param worker The worker to set. */ public void setWorker(String worker) { this.worker = worker; } // --------------------------------------------------------- Public Methods /** * Get jkstatus from server. * * @exception BuildException * if a validation error occurs */ public void execute() throws BuildException { if (url == null) { throw new BuildException("Must specify an 'url'"); } boolean isWorkerOnly = worker != null && !"".equals(worker); boolean isLoadbalancerOnly = loadbalancer != null && !"".equals(loadbalancer); StringBuffer error = new StringBuffer(); try { JkStatusAccessor accessor = new JkStatusAccessor(); JkStatus status = accessor.status(url, username, password); if (status.result != null && !"OK".equals(status.result.type) ) { if (getErrorProperty() != null) { getProject().setNewProperty(errorProperty, status.result.message); } if (isFailOnError()) { throw new BuildException(status.result.message); } else { handleErrorOutput(status.result.message); return; } } if (!isWorkerOnly && !isLoadbalancerOnly) { JkServer server = status.getServer(); JkSoftware software = status.getSoftware(); JkResult result = status.getResult(); if (resultproperty != null) { createProperty(server, "server", "name"); createProperty(server, "server", "port"); createProperty(software, "web_server"); createProperty(software, "jk_version"); createProperty(result, "result", "type"); createProperty(result, "result", "message"); } if (isEcho()) { handleOutput("server name=" + server.getName() + ":" + server.getPort() + " - " + software.getWeb_server() + " - " + software.getJk_version()); } } List balancers = status.getBalancers(); for (Iterator iter = balancers.iterator(); iter.hasNext();) { JkBalancer balancer = (JkBalancer) iter.next(); String balancerIndex = null; if (isLoadbalancerOnly) { if (loadbalancer.equals(balancer.getName())) { if (resultproperty != null) { setPropertyBalancerOnly(balancer); } echoBalancer(balancer); return; } } else { if (!isWorkerOnly) { if (resultproperty != null) { if ( balancer.getId() >= 0) balancerIndex = Integer.toString(balancer.getId()); else balancerIndex = balancer.getName() ; setPropertyBalancer(balancer,balancerIndex); } echoBalancer(balancer); } List members = balancer.getBalancerMembers(); for (Iterator iterator = members.iterator(); iterator .hasNext();) { JkBalancerMember member = (JkBalancerMember) iterator .next(); if (isWorkerOnly) { if (worker.equals(member.getName())) { if (resultproperty != null) { setPropertyWorkerOnly(balancer, member); } echoWorker(member); return; } } else { if (resultproperty != null) { setPropertyWorker(null, member); } echoWorker(member); if (member.getStatus() != null && !"OK".equals(member.getStatus())) { error.append(" worker name=" + member.getName() + " status=" + member.getStatus() + " host=" + member.getAddress()); } if (member.getState() != null && !("OK".equals(member.getState()) || "N/A".equals(member.getState()) || "OK/IDLE".equals(member.getState())) ){ error.append(" worker name=" + member.getName() + " state=" + member.getState() + " host=" + member.getAddress()); } } } if (!isWorkerOnly) { if (resultproperty != null && members.size() > 0) { getProject().setNewProperty( resultproperty + "." + balancer.getName() + ".length", Integer.toString(members.size())); } List mappings = balancer.getBalancerMappings(); int j = 0; String mapIndex ; if( balancerIndex != null ) mapIndex = balancerIndex + ".map" ; else mapIndex = "map" ; for (Iterator iterator = mappings.iterator(); iterator .hasNext(); j++) { JkBalancerMapping mapping = (JkBalancerMapping) iterator .next(); if (resultproperty != null) { String stringIndex2 ; if( mapping.getId() >= 0) { stringIndex2 = Integer.toString(mapping.getId()) ; } else { stringIndex2 = Integer.toString(j); } createProperty(mapping, mapIndex, stringIndex2, "type"); createProperty(mapping, mapIndex, stringIndex2, "uri"); createProperty(mapping, mapIndex, stringIndex2, "context"); createProperty(mapping, mapIndex, stringIndex2, "source"); } if (isEcho()) { String mappingOut ; if(mapping.source != null) { mappingOut = "balancer name=" + balancer.getName() + " mappingtype=" + mapping.getType() + " uri=" + mapping.getUri() + " source=" + mapping.getSource() ; } else { mappingOut = "balancer name=" + balancer.getName() + " mappingtype=" + mapping.getType() + " uri=" + mapping.getUri() + " context=" + mapping.getContext() ; } handleOutput(mappingOut); } } if (resultproperty != null && mappings.size() > 0) { getProject().setNewProperty( resultproperty + "." + mapIndex + ".length", Integer.toString(mappings.size())); } } } } if (!isWorkerOnly && !isLoadbalancerOnly) { if (resultproperty != null && balancers.size() > 0) { getProject().setNewProperty( resultproperty + ".length", Integer.toString(balancers.size())); } } } catch (Throwable t) { error.append(t.getMessage()); if (getErrorProperty() != null) { getProject().setNewProperty(errorProperty, error.toString()); } if (isFailOnError()) { throw new BuildException(t); } else { handleErrorOutput(t.getMessage()); return; } } if (error.length() != 0) { if (getErrorProperty() != null) { getProject().setNewProperty(errorProperty, error.toString()); } if (isFailOnError()) { // exception should be thrown only if failOnError == true // or error line will be logged twice throw new BuildException(error.toString()); } } } /** * @param member */ private void echoWorker(JkBalancerMember member) { if (isEcho()) { StringBuffer state = new StringBuffer("worker name=") ; state.append( member.getName()) ; if(member.getStatus() != null) { state.append(" status="); state.append(member.getStatus()); } if(member.getState() != null) { state.append(" state="); state.append(member.getState()) ; } state.append(" host="); state.append(member.getAddress()); handleOutput(state.toString()); } } /** * @param balancer */ private void echoBalancer(JkBalancer balancer) { if (isEcho()) { handleOutput("balancer name=" + balancer.getName() + " type=" + balancer.getType()); } } /** * @param balancer */ private void setPropertyBalancerOnly(JkBalancer balancer) { String prefix = resultproperty + "." + balancer.getName(); if(balancer.getId() >= 0 ) { getProject().setNewProperty(prefix + ".id", Integer.toString(balancer.getId())); } getProject().setNewProperty(prefix + ".type", balancer.getType()); getProject().setNewProperty(prefix + ".stick_session", Boolean.toString(balancer.isSticky_session())); getProject().setNewProperty(prefix + ".sticky_session_force", Boolean.toString(balancer.isSticky_session_force())); getProject().setNewProperty(prefix + ".retries", Integer.toString(balancer.getRetries())); getProject().setNewProperty(prefix + ".recover_time", Integer.toString(balancer.getRecover_time())); getProject().setNewProperty(prefix + ".method", balancer.getMethod()); getProject().setNewProperty(prefix + ".good", Integer.toString(balancer.getGood())); getProject().setNewProperty(prefix + ".degraded", Integer.toString(balancer.getDegraded())); getProject().setNewProperty(prefix + ".bad", Integer.toString(balancer.getBad())); getProject().setNewProperty(prefix + ".busy", Integer.toString(balancer.getBusy())); getProject().setNewProperty(prefix + ".map_count", Integer.toString(balancer.getMap_count())); getProject().setNewProperty(prefix + ".member_count", Integer.toString(balancer.getMember_count())); getProject().setNewProperty(prefix + ".max_busy", Integer.toString(balancer.getMax_busy())); getProject().setNewProperty(prefix + ".time_to_maintenance_min", Integer.toString(balancer.getTime_to_maintenance_min())); getProject().setNewProperty(prefix + ".time_to_maintenance_max", Integer.toString(balancer.getTime_to_maintenance_max())); getProject().setNewProperty(prefix + ".lock", balancer.getLock()); } /** * @param balancer * @param balancerIndex */ private void setPropertyBalancer(JkBalancer balancer,String balancerIndex) { if(balancer.id >= 0) { createProperty(balancer, balancerIndex, "id"); } createProperty(balancer, balancerIndex, "name"); createProperty(balancer, balancerIndex, "type"); createProperty(balancer, balancerIndex, "sticky_session"); createProperty(balancer, balancerIndex, "sticky_session_force"); createProperty(balancer, balancerIndex, "retries"); createProperty(balancer, balancerIndex, "recover_time"); if(balancer.getMethod() != null) { createProperty(balancer, balancerIndex, "method"); } if(balancer.getLock() != null) { createProperty(balancer, balancerIndex, "lock"); } if(balancer.getGood() >= 0) { createProperty(balancer, balancerIndex, "good"); } if(balancer.getDegraded() >= 0) { createProperty(balancer, balancerIndex, "degraded"); } if(balancer.getBad() >= 0) { createProperty(balancer, balancerIndex, "bad"); } if(balancer.getBusy() >= 0) { createProperty(balancer, balancerIndex, "busy"); } if(balancer.getMax_busy() >= 0) { createProperty(balancer, balancerIndex, "max_busy"); } if(balancer.getMember_count() >=0) { createProperty(balancer, balancerIndex, "member_count"); } if(balancer.getMap_count() >=0) { createProperty(balancer, balancerIndex, "map_count"); } if(balancer.getTime_to_maintenance_min() >=0) { createProperty(balancer, balancerIndex, "time_to_maintenance_min"); } if(balancer.getTime_to_maintenance_max() >=0) { createProperty(balancer, balancerIndex, "time_to_maintenance_max"); } } /** * @param balancerIndex * @param member */ private void setPropertyWorker(String balancerIndex, JkBalancerMember member) { String workerIndex ; if(member.getId() >= 0) { workerIndex = Integer.toString(member.getId()); createProperty(member, balancerIndex, workerIndex, "id"); createProperty(member, balancerIndex, workerIndex, "name"); } else { workerIndex = member.getName(); } createProperty(member, balancerIndex, workerIndex, "type"); createProperty(member, balancerIndex, workerIndex, "host"); createProperty(member, balancerIndex, workerIndex, "port"); createProperty(member, balancerIndex, workerIndex, "address"); if(member.getJvm_route() != null) { createProperty(member, balancerIndex, workerIndex, "jvm_route"); } if(member.getRoute() != null) { createProperty(member, balancerIndex, workerIndex, "route"); } if(member.getStatus() != null) { createProperty(member, balancerIndex, workerIndex, "status"); } if(member.getActivation() != null) { createProperty(member, balancerIndex, workerIndex, "activation"); } if(member.getState() != null) { createProperty(member, balancerIndex, workerIndex, "state"); } createProperty(member, balancerIndex, workerIndex, "lbfactor"); createProperty(member, balancerIndex, workerIndex, "lbvalue"); if(member.getLbmult() >= 0) { createProperty(member, balancerIndex, workerIndex, "lbmult"); } createProperty(member, balancerIndex, workerIndex, "elected"); createProperty(member, balancerIndex, workerIndex, "readed"); createProperty(member, balancerIndex, workerIndex, "busy"); if(member.getMax_busy() >= 0) { createProperty(member, balancerIndex, workerIndex, "max_busy"); } createProperty(member, balancerIndex, workerIndex, "transferred"); createProperty(member, balancerIndex, workerIndex, "errors"); if(member.getClient_errors() >= 0) { createProperty(member, balancerIndex, workerIndex, "client_errors"); } if(member.getDistance() >= 0) { createProperty(member, balancerIndex, workerIndex, "distance"); } if (member.getDomain() != null) { createProperty(member, balancerIndex, workerIndex, "domain"); } else { getProject().setNewProperty(resultproperty + "." + balancerIndex + "." + workerIndex + ".domain", ""); } if (member.getRedirect() != null) { createProperty(member, balancerIndex, workerIndex, "redirect"); } else { getProject().setNewProperty(resultproperty + "." + balancerIndex + "." + workerIndex + ".redirect", ""); } } /** * @param balancer * @param member */ private void setPropertyWorkerOnly(JkBalancer balancer, JkBalancerMember member) { //String prefix = resultproperty + "." + balancer.getName() + "." + member.getName(); String prefix = resultproperty + "." + member.getName(); Project currentProject = getProject(); if ( balancer.getId() >= 0) { currentProject.setNewProperty(prefix + ".lb.id", Integer.toString(balancer.getId())); } //currentProject.setNewProperty(prefix + ".lb.name", balancer.getName()); if( member.getId() >= 0) { currentProject.setNewProperty(prefix + ".id", Integer.toString(member.getId())); } currentProject.setNewProperty(prefix + ".type", member.getType()); if (member.getJvm_route() != null) { currentProject.setNewProperty(prefix + ".jvm_route", member.getJvm_route()); } if (member.getRoute() != null) { currentProject.setNewProperty(prefix + ".route", member.getRoute()); } if (member.getStatus() != null) { currentProject.setNewProperty(prefix + ".status", member.getStatus()); } if (member.getActivation() != null) { currentProject.setNewProperty(prefix + ".activation", member.getActivation()); } if (member.getState() != null) { currentProject.setNewProperty(prefix + ".state", member.getState()); } currentProject.setNewProperty(prefix + ".host", member.getHost()); currentProject.setNewProperty(prefix + ".address", member.getAddress()); currentProject.setNewProperty(prefix + ".port", Integer.toString(member.getPort())); currentProject.setNewProperty(prefix + ".lbfactor", Integer.toString(member.getLbfactor())); currentProject.setNewProperty(prefix + ".lbvalue", Long.toString(member.getLbvalue())); if(member.getLbmult() >= 0) { currentProject.setNewProperty(prefix + ".lbmult", Long.toString(member.getLbmult())); } currentProject.setNewProperty(prefix + ".elected", Long.toString(member.getElected())); currentProject.setNewProperty(prefix + ".readed", Long.toString(member.getReaded())); currentProject.setNewProperty(prefix + ".transferred", Long.toString(member.getTransferred())); currentProject.setNewProperty(prefix + ".busy", Integer.toString(member.getBusy())); if(member.getMax_busy() >= 0) { currentProject.setNewProperty(prefix + ".max_busy", Long.toString(member.getMax_busy())); } currentProject.setNewProperty(prefix + ".errors", Long.toString(member.getErrors())); if(member.getClient_errors() >= 0) { currentProject.setNewProperty(prefix + ".client_errors", Long.toString(member.getClient_errors())); } if(member.getDistance() >= 0) { currentProject.setNewProperty(prefix + ".distance", Integer.toString(member.getDistance())); } if (member.getDomain() != null) { currentProject.setNewProperty(prefix + ".domain", member.getDomain()); } else { currentProject.setNewProperty(prefix + ".domain", ""); } if (member.getRedirect() != null) { currentProject.setNewProperty(prefix + ".redirect", member.getRedirect()); } else { currentProject.setNewProperty(prefix + ".redirect", ""); } if(member.getTime_to_recover() >= 0) { currentProject.setNewProperty(prefix + ".time_to_recover", Integer.toString(member.getTime_to_recover())); } if(member.getTime_to_recover_min() >= 0) { currentProject.setNewProperty(prefix + ".time_to_recover_min", Integer.toString(member.getTime_to_recover_min())); } if(member.getTime_to_recover_max() >= 0) { currentProject.setNewProperty(prefix + ".time_to_recover_max", Integer.toString(member.getTime_to_recover_max())); currentProject.setNewProperty(prefix + ".time_to_recover", (Integer.toString((member.getTime_to_recover_min() + member.getTime_to_recover_max()) / 2))); } } /* * Set ant property for save error state * * @see org.apache.catalina.ant.BaseRedirectorHelperTask#setErrorProperty(java.lang.String) */ public void setErrorProperty(String arg0) { errorProperty = arg0; super.setErrorProperty(arg0); } /** * @return Returns the errorProperty. */ public String getErrorProperty() { return errorProperty; } protected void createProperty(Object result, String attribute) { createProperty(result, null, null, attribute); } protected void createProperty(Object result, String arraymark, String attribute) { createProperty(result, arraymark, null, attribute); } /** * create result as property with name from attribute resultproperty */ protected void createProperty(Object result, String arraymark, String arraymark2, String attribute) { if (resultproperty != null) { Object value = IntrospectionUtils.getProperty(result, attribute); if (value != null ) { StringBuffer propertyname = new StringBuffer(resultproperty); if (result instanceof JkBalancer) { if (arraymark != null) { propertyname.append("."); propertyname.append(arraymark); } } else if (result instanceof JkServer) { if (arraymark != null) { propertyname.append("."); propertyname.append(arraymark); } } else if (result instanceof JkSoftware) { if (arraymark != null) { propertyname.append("."); propertyname.append(arraymark); } } else if (result instanceof JkResult) { if (arraymark != null) { propertyname.append("."); propertyname.append(arraymark); } } else if (result instanceof JkBalancerMember) { if (arraymark != null) { propertyname.append("."); propertyname.append(arraymark); } if (arraymark2 != null) { propertyname.append("."); propertyname.append(arraymark2); } } else if (result instanceof JkBalancerMapping) { if (arraymark != null) { propertyname.append("."); propertyname.append(arraymark); } if (arraymark2 != null) { propertyname.append("."); propertyname.append(arraymark2); } } propertyname.append("."); propertyname.append(attribute); getProject().setNewProperty(propertyname.toString(), value.toString()); } } } } tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/LocalStrings.properties0000644000000000000020000000141610666607673030560 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/JkStatusAccessor.java0000644000000000000020000001057410537061743030126 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.status; import java.io.IOException; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.URL; import java.net.URLConnection; import org.apache.catalina.util.Base64; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.tomcat.util.digester.Digester; /** * Create connection to mod_jk jkstatus page. * Optional you can use Http basic auth user and password. * @author Peter Rossbach * @version $Revision: 485242 $ $Date: 2006-12-10 19:45:39 +0000 (Sun, 10 Dec 2006) $ * @see org.apache.jk.status.JkStatusParser * @since 5.5.10 */ public class JkStatusAccessor { private static Log log = LogFactory.getLog(JkStatusAccessor.class); /** * The descriptive information about this implementation. */ protected static final String info = "org.apache.jk.status.JkStatusAccessor/1.0"; /** * Parse Apache mod_jk Status from base url http://host:port/jkstatus) * @param url * @param username * @param password * */ public JkStatus status(String url, String username, String password) throws Exception { if(url == null || "".equals(url)) return null ; HttpURLConnection hconn = null; JkStatus status = null; try { // FIXME: use cmd show for older mod_jk versions hconn = openConnection(url + "?cmd=list&mime=xml", username, password); Digester digester = JkStatusParser.getDigester(); synchronized (digester) { status = (JkStatus) digester.parse(hconn.getInputStream()); } } catch (Throwable t) { throw new Exception(t); } finally { if (hconn != null) { try { hconn.disconnect(); } catch (Throwable u) { ; } hconn = null; } } return status; } /** * Create a auth http connection for this url * * @param url * @param username * @param password * @return HttpConnection * @throws IOException * @throws MalformedURLException * @throws ProtocolException */ protected HttpURLConnection openConnection(String url, String username, String password) throws IOException, MalformedURLException, ProtocolException { URLConnection conn; conn = (new URL(url)).openConnection(); HttpURLConnection hconn = (HttpURLConnection) conn; // Set up standard connection characteristics hconn.setAllowUserInteraction(false); hconn.setDoInput(true); hconn.setUseCaches(false); hconn.setDoOutput(false); hconn.setRequestMethod("GET"); hconn.setRequestProperty("User-Agent", "JkStatus-Client/1.0"); if(username != null && password != null ) { setAuthHeader(hconn, username, password); } // Establish the connection with the server hconn.connect(); return hconn; } /** * Set Basic Auth Header * * @param hconn * @param username * @param password */ protected void setAuthHeader(HttpURLConnection hconn, String username, String password) { // Set up an authorization header with our credentials String input = username + ":" + password; String output = new String(Base64.encode(input.getBytes())); hconn.setRequestProperty("Authorization", "Basic " + output); } }tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/antlib.xml0000644000000000000020000000251110666607673026026 0ustar rootbin tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/JkBalancerMember.java0000644000000000000020000002364410556671260030023 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.status; import java.io.Serializable; /** * @author Peter Rossbach * @version $Revision: 500550 $ $Date: 2007-01-27 15:41:36 +0000 (Sat, 27 Jan 2007) $ * @see org.apache.jk.status.JkStatusParser */ /** * @author peter * */ public class JkBalancerMember implements Serializable { int id = -1; String name; /* possible with >= 1.2.16 */ String jvm_route; /* possible with >= 1.2.20 */ String route; String type; String host; int port; String address; /* deprecated with mod_jk 1.2.16*/ String status; /* possible with > 1.2.16 */ String activation; /* possible with > 1.2.16 */ String state; int lbfactor; long lbvalue; /* possible with > 1.2.16 */ long lbmult = -1 ; int elected; long readed; long transferred; long errors; long clienterrors = -1; int busy; /* possible with > 1.2.16 */ int maxbusy = -1; String redirect; String domain; /* possible with > 1.2.16 */ int distance = -1; /* possible with > 1.2.20 */ int time_to_recover = -1 ; /* possible with > 1.2.21 */ int time_to_recover_max = -1 ; /* possible with > 1.2.21 */ int time_to_recover_min = -1 ; /** * @return Returns the jvm_route. * @since mod_jk 1.2.16 * @deprecated */ public String getJvm_route() { return jvm_route; } /** * @param jvm_route The jvm_route to set. * @since mod_jk 1.2.16 * @deprecated */ public void setJvm_route(String jvm_route) { this.jvm_route = jvm_route; } /** * @return the route * @since mod_jk 1.2.20 */ public String getRoute() { return route; } /** * @param route the route to set * @since mod_jk 1.2.20 */ public void setRoute(String route) { this.route = route; } /** * @return Returns the address. */ public String getAddress() { return address; } /** * @param address * The address to set. */ public void setAddress(String address) { this.address = address; } /** * @return Returns the busy. */ public int getBusy() { return busy; } /** * @param busy * The busy to set. */ public void setBusy(int busy) { this.busy = busy; } /** * @return Returns the maxbusy. * @since mod_jk 1.2.18 */ public int getMax_busy() { return maxbusy; } /** * @param maxbusy The maxbusy to set. * @since mod_jk 1.2.18 */ public void setMax_busy(int maxbusy) { this.maxbusy = maxbusy; } /** * @return Returns the elected. */ public int getElected() { return elected; } /** * @param elected * The elected to set. */ public void setElected(int elected) { this.elected = elected; } /** * @return Returns the clienterrors. * @since mod_jk 1.2.19 */ public long getClient_errors() { return clienterrors; } /** * @param clienterrors The clienterrors to set. * @since mod_jk 1.2.19 */ public void setClient_errors(long clienterrors) { this.clienterrors = clienterrors; } /** * @return Returns the errors. */ public long getErrors() { return errors; } /** * @param errors * The errors to set. */ public void setErrors(long errors) { this.errors = errors; } /** * @return Returns the host. */ public String getHost() { return host; } /** * @param host * The host to set. */ public void setHost(String host) { this.host = host; } /** * @return Returns the id. */ public int getId() { return id; } /** * @param id * The id to set. */ public void setId(int id) { this.id = id; } /** * @return Returns the lbfactor. */ public int getLbfactor() { return lbfactor; } /** * @param lbfactor * The lbfactor to set. */ public void setLbfactor(int lbfactor) { this.lbfactor = lbfactor; } /** * @return Returns the lbvalue. */ public long getLbvalue() { return lbvalue; } /** * @param lbvalue * The lbvalue to set. */ public void setLbvalue(long lbvalue) { this.lbvalue = lbvalue; } /** * @return Returns the lbmult. * @since mod_jk 1.2.19 */ public long getLbmult() { return lbmult; } /** * @param lbmult The lbmult to set. * @since mod_jk 1.2.19 */ public void setLbmult(long lbmult) { this.lbmult = lbmult; } /** * @return Returns the name. */ public String getName() { return name; } /** * @param name * The name to set. */ public void setName(String name) { this.name = name; } /** * @return Returns the port. */ public int getPort() { return port; } /** * @param port * The port to set. */ public void setPort(int port) { this.port = port; } /** * @return Returns the readed. */ public long getReaded() { return readed; } /** * @param readed * The readed to set. */ public void setReaded(long readed) { this.readed = readed; } /** * @return Returns the status. * @deprecated since 1.2.16 */ public String getStatus() { return status; } /** * @param status * The status to set. * @deprecated since 1.2.16 */ public void setStatus(String status) { this.status = status; } /** * @return Returns the activation. * @since mod_jk 1.2.19 */ public String getActivation() { return activation; } /** * @param activation The activation to set. * @since mod_jk 1.2.19 */ public void setActivation(String activation) { this.activation = activation; } /** * @return Returns the state. * @since mod_jk 1.2.19 */ public String getState() { return state; } /** * @param state The state to set. * @since mod_jk 1.2.19 */ public void setState(String state) { this.state = state; } /** * @return Returns the transferred. */ public long getTransferred() { return transferred; } /** * @param transferred * The transferred to set. */ public void setTransferred(long transferred) { this.transferred = transferred; } /** * @return Returns the type. */ public String getType() { return type; } /** * @param type * The type to set. */ public void setType(String type) { this.type = type; } /** * @return Returns the domain. */ public String getDomain() { return domain; } /** * @param domain The domain to set. */ public void setDomain(String domain) { this.domain = domain; } /** * @return Returns the redirect. */ public String getRedirect() { return redirect; } /** * @param redirect The redirect to set. */ public void setRedirect(String redirect) { this.redirect = redirect; } /** * @return Returns the distance. * @since mod_jk 1.2.18 */ public int getDistance() { return distance; } /** * @param distance The distance to set. * @since mod_jk 1.2.18 */ public void setDistance(int distance) { this.distance = distance; } /** * @return the time_to_recover * @since mod_jk 1.2.20 */ public int getTime_to_recover() { return time_to_recover; } /** * @param time_to_recover the time_to_recover to set * @since mod_jk 1.2.20 */ public void setTime_to_recover(int time_to_recover) { this.time_to_recover = time_to_recover; } /** * @return the time_to_recover_min * @since mod_jk 1.2.21 */ public int getTime_to_recover_min() { return time_to_recover_min; } /** * @param time_to_recover_min the time_to_recover_min to set * @since mod_jk 1.2.21 */ public void setTime_to_recover_min(int time_to_recover_min) { this.time_to_recover_min = time_to_recover_min; } /** * @return the time_to_recover_max * @since mod_jk 1.2.21 */ public int getTime_to_recover_max() { return time_to_recover_max; } /** * @param time_to_recover_max the time_to_recover_max to set * @since mod_jk 1.2.21 */ public void setTime_to_recover_max(int time_to_recover_max) { this.time_to_recover_max = time_to_recover_max; } } tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/JkStatusUpdateWorkerTask.java0000644000000000000020000001473711613737613031632 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.status; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import org.apache.tools.ant.BuildException; /** * Ant task that implements the /status update worker command, supported by the * mod_jk status (1.2.20) application. * * * @author Peter Rossbach * @version $Revision: 1151368 $ * @since mod_jk 1.2.20 */ public class JkStatusUpdateWorkerTask extends AbstractJkStatusTask { /** * The descriptive information about this implementation. */ private static final String info = "org.apache.jk.status.JkStatusUpdateWorkerTask/1.0"; protected String loadbalancer ; protected String worker ; protected int loadfactor =-1; protected String route ; protected int distance = -1; protected String redirect; protected String domain; protected int activationCode = -1; protected String activation ; /** * Return descriptive information about this implementation and the * corresponding version number, in the format * <description>/<version>. */ public String getInfo() { return (info); } /** * */ public JkStatusUpdateWorkerTask() { super(); setUrl("http://localhost/jkstatus"); } /** * @return the activation */ public String getActivation() { return activation; } /** * @param activation the activation to set */ public void setActivation(String activation) { this.activation = activation; } /** * @return the activationCode */ public int getActivationCode() { return activationCode; } /** * @param activationCode the activationCode to set */ public void setActivationCode(int activationCode) { this.activationCode = activationCode; } /** * @return the distance */ public int getDistance() { return distance; } /** * @param distance the distance to set */ public void setDistance(int distance) { this.distance = distance; } /** * @return the domain */ public String getDomain() { return domain; } /** * @param domain the domain to set */ public void setDomain(String domain) { this.domain = domain; } /** * @return the loadbalancer */ public String getLoadbalancer() { return loadbalancer; } /** * @param loadbalancer the loadbalaner to set */ public void setLoadbalancer(String loadbalancer) { this.loadbalancer = loadbalancer; } /** * @return the loadfactor */ public int getLoadfactor() { return loadfactor; } /** * @param loadfactor the loadfactor to set */ public void setLoadfactor(int loadfactor) { this.loadfactor = loadfactor; } /** * @return the redirect */ public String getRedirect() { return redirect; } /** * @param redirect the redirect to set */ public void setRedirect(String redirect) { this.redirect = redirect; } /** * @return the route */ public String getRoute() { return route; } /** * @param route the route to set */ public void setRoute(String route) { this.route = route; } /** * @return the worker */ public String getWorker() { return worker; } /** * @param worker the worker to set */ public void setWorker(String worker) { this.worker = worker; } /** * Create JkStatus worker update link *
      * http://localhost/jkstatus?cmd=update&mime=txt&w=loadbalancer&sw=node01&wn=node01&l=lb&wf=1&wa=1&wd=0 *
      * * *
      Tcp worker parameter: *
      *
        *
      • w: name loadbalancer
      • *
      • sw: name tcp worker node
      • *
      • wf: load factor
      • *
      • wn: route
      • *
      • wd: distance
      • *
      • wa: activation state
      • *
      • wr: redirect route
      • *
      • wc: cluster domain
      • *
      *
        *
      • wa=1 active
      • *
      • wa=2 disabled
      • *
      • wa=3 stopped
      • *
      * *
    * * @return create jkstatus update worker link */ protected StringBuffer createLink() { // Building URL StringBuffer sb = new StringBuffer(); try { sb.append("?cmd=update&mime=txt"); sb.append("&w="); sb.append(URLEncoder.encode(loadbalancer, getCharset())); sb.append("&sw="); sb.append(URLEncoder.encode(worker, getCharset())); if (loadfactor >= 0) { sb.append("&vwf="); sb.append(loadfactor); } if (route != null) { sb.append("&vwn="); sb.append(URLEncoder.encode(route, getCharset())); } if (activation == null && activationCode > 0 && activationCode < 4) { sb.append("&vwa="); sb.append(activation); } if (activation != null) { sb.append("&vwa="); sb.append(URLEncoder.encode(activation, getCharset())); } if (distance >= 0) { sb.append("&vwd="); sb.append(distance); } if (redirect != null) { // other worker conrecte lb's sb.append("&vwr="); sb.append(URLEncoder.encode(redirect, getCharset())); } if (domain != null) { sb.append("&vwc="); sb.append(URLEncoder.encode(domain, getCharset())); } } catch (UnsupportedEncodingException e) { throw new BuildException("Invalid 'charset' attribute: " + getCharset()); } return sb; } /** * check correct lb and worker pararmeter */ protected void checkParameter() { if (worker == null) { throw new BuildException("Must specify 'worker' attribute"); } if (loadbalancer == null) { throw new BuildException("Must specify 'loadbalancer' attribute"); } } } tomcat-connectors-1.2.41-src/jkstatus/src/share/org/apache/jk/status/AbstractJkStatusTask.java0000644000000000000020000001542311237120030030727 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.status; import java.io.BufferedOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.ProtocolException; import java.net.URL; import java.net.URLConnection; import org.apache.catalina.ant.AbstractCatalinaTask; import org.apache.catalina.util.Base64; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; /** * Ant task that implements mod_jk 1.2.20 result message string * * @author Peter Rossbach * @version $Revision: 802231 $ * @since mod_jk 1.2.20 */ public abstract class AbstractJkStatusTask extends AbstractCatalinaTask { /** * Execute the requested operation. * * @exception BuildException * if an error occurs */ public void execute() throws BuildException { super.execute(); checkParameter(); StringBuffer sb = createLink(); execute(sb.toString(), null, null, -1); } protected abstract void checkParameter() ; protected abstract StringBuffer createLink() ; /** * Execute the specified command, based on the configured properties. * The input stream will be closed upon completion of this task, whether * it was executed successfully or not. * * @param command Command to be executed * @param istream InputStream to include in an HTTP PUT, if any * @param contentType Content type to specify for the input, if any * @param contentLength Content length to specify for the input, if any * * @exception BuildException if an error occurs */ public void execute(String command, InputStream istream, String contentType, int contentLength) throws BuildException { InputStreamReader reader = null; try { HttpURLConnection hconn = send(command, istream, contentType, contentLength); // Process the response message reader = new InputStreamReader(hconn.getInputStream(), "UTF-8"); String error = null; error = handleResult(reader, error); if (error != null && isFailOnError()) { // exception should be thrown only if failOnError == true // or error line will be logged twice throw new BuildException(error); } } catch (Throwable t) { if (isFailOnError()) { throw new BuildException(t); } else { handleErrorOutput(t.getMessage()); } } finally { closeRedirector(); if (reader != null) { try { reader.close(); } catch (Throwable u) { ; } reader = null; } if (istream != null) { try { istream.close(); } catch (Throwable u) { ; } istream = null; } } } private String handleResult(InputStreamReader reader, String error) throws IOException { StringBuffer buff = new StringBuffer(); int msgPriority = Project.MSG_INFO; boolean first = true; while (true) { int ch = reader.read(); if (ch < 0) { break; } else if ((ch == '\r') || (ch == '\n')) { // in Win \r\n would cause handleOutput() to be called // twice, the second time with an empty string, // producing blank lines if (buff.length() > 0) { String line = buff.toString(); buff.setLength(0); if (first) { if (!line.startsWith("Result: type=OK")) { error = line; msgPriority = Project.MSG_ERR; } first = false; } handleOutput(line, msgPriority); } } else { buff.append((char) ch); } } if (buff.length() > 0) { handleOutput(buff.toString(), msgPriority); } return error; } protected HttpURLConnection send(String command, InputStream istream, String contentType, int contentLength) throws IOException, MalformedURLException, ProtocolException { URLConnection conn; // Create a connection for this command conn = (new URL(url + command)).openConnection(); HttpURLConnection hconn = (HttpURLConnection) conn; // Set up standard connection characteristics hconn.setAllowUserInteraction(false); hconn.setDoInput(true); hconn.setUseCaches(false); if (istream != null) { hconn.setDoOutput(true); hconn.setRequestMethod("PUT"); if (contentType != null) { hconn.setRequestProperty("Content-Type", contentType); } if (contentLength >= 0) { hconn.setRequestProperty("Content-Length", "" + contentLength); } } else { hconn.setDoOutput(false); hconn.setRequestMethod("GET"); } hconn.setRequestProperty("User-Agent", "JkStatus-Ant-Task/1.1"); // Set up an authorization header with our credentials String input = username + ":" + password; String output = new String(Base64.encode(input.getBytes())); hconn.setRequestProperty("Authorization", "Basic " + output); // Establish the connection with the server hconn.connect(); // Send the request data (if any) if (istream != null) { BufferedOutputStream ostream = new BufferedOutputStream(hconn.getOutputStream(), 1024); byte buffer[] = new byte[1024]; while (true) { int n = istream.read(buffer); if (n < 0) { break; } ostream.write(buffer, 0, n); } ostream.flush(); ostream.close(); istream.close(); } return hconn; } } tomcat-connectors-1.2.41-src/jkstatus/test/0000755000000000000020000000000012555256552017156 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/test/src/0000755000000000000020000000000012555256552017745 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/test/src/share/0000755000000000000020000000000012555256552021047 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/test/src/share/org/0000755000000000000020000000000012555256552021636 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/test/src/share/org/apache/0000755000000000000020000000000012555256552023057 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/test/src/share/org/apache/jk/0000755000000000000020000000000012555256552023463 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/test/src/share/org/apache/jk/status/0000755000000000000020000000000012555256552025006 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/test/src/share/org/apache/jk/status/JkStatusParserTest.java0000644000000000000020000000644710666607673031456 0ustar rootbin/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jk.status; import java.io.IOException; import java.io.StringReader; import junit.framework.TestCase; import org.apache.tomcat.util.digester.Digester; import org.xml.sax.SAXException; /** * @author Peter Rossbach * */ public class JkStatusParserTest extends TestCase { public void testDigester() throws IOException, SAXException { Digester digester = JkStatusParser.createDigester(); String example = "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" ; StringReader reader = new StringReader(example); JkStatus status = (JkStatus) digester .parse(reader); assertNotNull(status); assertNotNull(status.getServer()); assertEquals(1,status.getBalancers().size()); JkBalancer balancer = (JkBalancer)status.getBalancers().get(0); assertEquals(2,balancer.getBalancerMembers().size()); assertEquals("node1",((JkBalancerMember)balancer.getBalancerMembers().get(0)).getName()); assertEquals("node2",((JkBalancerMember)balancer.getBalancerMembers().get(1)).getName()); assertEquals(4,balancer.getBalancerMappings().size()); } } tomcat-connectors-1.2.41-src/jkstatus/test/conf/0000755000000000000020000000000012555256552020103 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/test/conf/jkstatus.xml0000644000000000000020000000350710666607673022507 0ustar rootbin tomcat-connectors-1.2.41-src/jkstatus/test/conf/log4j.xml0000644000000000000020000000506110666607673021653 0ustar rootbin tomcat-connectors-1.2.41-src/jkstatus/test/build.xml0000644000000000000020000001072410666607673021010 0ustar rootbin This ant script implements some testcases to verify the key functions of tomcat apache mod_jk jkstatus module. You find this script at: ${ant.file} tomcat-connectors-1.2.41-src/jkstatus/build.properties.default0000644000000000000020000000156111721761544023036 0ustar rootbin# ----------------------------------------------------------------------------- # build.properties.default # # This is an example "build.properties" file, used to customize building Tomcat # for your local environment. It defines the location of all external # modules that Tomcat depends on. Copy this file to "build.properties" # in the top-level source directory, and customize it as needed. # # $Id: build.properties.default 892628 2009-12-20 18:01:53Z markt $ # ----------------------------------------------------------------------------- # ----- Compile Control Flags ----- compile.debug=on compile.deprecation=off compile.optimize=off # ----- Path to Tomcat installation ----- catalina.build=/usr/local/share/tomcat-5.5 # ----- Some version dependent jar file names ----- commons-modeler.jar=commons-modeler-2.0.1.jar commons-logging.jar=commons-logging-api-1.1.1.jar tomcat-connectors-1.2.41-src/jkstatus/conf/0000755000000000000020000000000012555256552017124 5ustar rootbintomcat-connectors-1.2.41-src/jkstatus/conf/jkstatus-tasks.xml0000644000000000000020000000331610772307412022633 0ustar rootbin Apache mod_jk ant jkstatus Tasks tomcat-connectors-1.2.41-src/jkstatus/build.xml0000644000000000000020000001405412451224326020011 0ustar rootbin tomcat-connectors-1.2.41-src/conf/0000755000000000000020000000000012555256556015260 5ustar rootbintomcat-connectors-1.2.41-src/conf/workers.properties0000644000000000000020000001351312446266173021070 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Note that the distributed version of this file requires modification # before it is usable. # # Reference documentation: http://tomcat.apache.org/connectors-doc/reference/workers.html # # As a general note, the characters $( and ) are used to reference # property values in other properties. # # Whenever you see a set of lines such as: # x=value # y=$(x)othervalue # # the final value for y will be "valueothervalue" # Define two status worker: # - jk-status for read-only use # - jk-manager for read/write use worker.list=jk-status worker.jk-status.type=status worker.jk-status.read_only=true worker.list=jk-manager worker.jk-manager.type=status # We define a load balancer worker # with name "balancer" worker.list=balancer worker.balancer.type=lb # error_escalation_time: seconds, default = recover_time/2 (=30) # Determines, how fast a detected error should switch from # local error state to global error state # Since: 1.2.28 worker.balancer.error_escalation_time=0 # - max_reply_timeouts: number, default=0 # If there are to many reply timeouts, a worker # is put into the error state, i.e. it will become # unavailable for all sessions residing on the respective # Tomcat. The number of tolerated reply timeouts is # configured with max_reply_timeouts. The number of # timeouts occuring is divided by 2 once a minute and the # resulting counter is compared against max_reply_timeouts. # If you set max_reply_timeouts to N and the errors are # occuring equally distributed over time, you will # tolerate N/2 errors per minute. If they occur in a burst # you will tolerate N errors. # Since: 1.2.24 worker.balancer.max_reply_timeouts=10 # Now we add members to the load balancer # First member is "node1", most # attributes are inherited from the # template "worker.template". worker.balancer.balance_workers=node1 worker.node1.reference=worker.template worker.node1.host=localhost worker.node1.port=8109 # Activation allows to configure # whether this node should actually be used # A: active (use node fully) # D: disabled (only use, if sticky session needs this node) # S: stopped (do not use) # Since: 1.2.19 worker.node1.activation=A # Second member is "node2", most # attributes are inherited from the # template "worker.template". worker.balancer.balance_workers=node2 worker.node2.reference=worker.template worker.node2.host=localhost worker.node2.port=8209 # Activation allows to configure # whether this node should actually be used # A: active (use node fully) # D: disabled (only use, if sticky session needs this node) # S: stopped (do not use) # Since: 1.2.19 worker.node2.activation=A # Finally we put the parameters # which should apply to all our ajp13 # workers into the referenced template # - Type is ajp13 worker.template.type=ajp13 # - socket_connect_timeout: milliseconds, default=0 # Since: 1.2.27 worker.template.socket_connect_timeout=5000 # - socket_keepalive: boolean, default=false # Should we send TCP keepalive packets # when connection is idle (socket option)? worker.template.socket_keepalive=true # - ping_mode: Character, default=none # When should we use cping/cpong connection probing? # C = directly after establishing a new connection # P = directly before sending each request # I = in regular intervals for idle connections # using the watchdog thread # A = all of the above # Since: 1.2.27 worker.template.ping_mode=A # - ping_timeout: milliseconds, default=10000 # Wait timeout for cpong after cping # Can be overwritten for modes C and P # Using connect_timeout and prepost_timeout. # Since: 1.2.27 worker.template.ping_timeout=10000 # - connection_pool_minsize: number, default=connection_pool_size # Lower pool size when shrinking pool due # to idle connections # We want all connections to be closed when # idle for a long time in order to prevent # firewall problems. # Since: 1.2.16 worker.template.connection_pool_minsize=0 # - connection_pool_timeout: seconds, default=0 # Idle time, before a connection is eligible # for being closed (pool shrinking). # This should be the same value as keepAliveTimeout # (if it is set explicitly) or connectionTimeout # in the Tomcat AJP connector, but there it is # milliseconds, here seconds. worker.template.connection_pool_timeout=600 # - reply_timeout: milliseconds, default=0 # Any pause longer than this timeout during waiting # for a part of the reply will abort handling the request # in mod_jk. The request will proceed running in # Tomcat, but the web server resources will be freed # and an error is send to the client. # For individual requests, the timeout can be overwritten # by the Apache environment variable JK_REPLY_TIMEOUT. # JK_REPLY_TIMEOUT since: 1.2.27 worker.template.reply_timeout=300000 # - recovery_options: number, default=0 # Bit mask to configure, if a request, which was send # to a backend successfully, should be retried on another backend # in case there's a problem with the response. # Value "3" disables retries, whenever a part of the request was # successfully send to the backend. worker.template.recovery_options=3 tomcat-connectors-1.2.41-src/conf/uriworkermap.properties0000644000000000000020000000266512446106064022121 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # uriworkermap.properties # # Use for IIS or with the Apache web server as an alternative # to JkMount and JkUnmount # # This file provides sample mappings for the example # worker "balancer" defined in workermap.properties. # The general syntax for this file is: # [URL]=[Worker name] /admin/*=balancer /manager/*=balancer /examples/*=balancer # Optionally filter out all .jpg files inside that context # For no mapping the url has to start with exclamation mark (!) !/examples/*.jpg=balancer # # Mount jk status and manager # For production servers you will need to # secure the access to the /jk-manager and # /jk-status urls # /jk-manager=jk-manager /jk-status=jk-status tomcat-connectors-1.2.41-src/conf/httpd-jk.conf0000644000000000000020000001212612445353114017640 0ustar rootbin# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Configuration Example for mod_jk # used in combination with Apache 2.2.x # Change the path and file name of the module, in case # you have installed it outside of httpd, or using # a versioned file name. LoadModule jk_module modules/mod_jk.so # We need a workers file exactly once # and in the global server JkWorkersFile conf/workers.properties # Our JK error log # You can (and should) use rotatelogs here JkLogFile logs/mod_jk.log # Our JK log level (trace,debug,info,warn,error) JkLogLevel info # Our JK shared memory file JkShmFile logs/mod_jk.shm # Define a new log format you can use in any CustomLog in order # to add mod_jk specific information to your access log. # LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" \"%{Cookie}i\" \"%{Set-Cookie}o\" %{pid}P %{tid}P %{JK_LB_FIRST_NAME}n %{JK_LB_LAST_NAME}n ACC %{JK_LB_LAST_ACCESSED}n ERR %{JK_LB_LAST_ERRORS}n BSY %{JK_LB_LAST_BUSY}n %{JK_LB_LAST_STATE}n %D" extended_jk # This option will reject all requests, which contain an # encoded percent sign (%25) or backslash (%5C) in the URL # If you are sure, that your webapp doesn't use such # URLs, enable the option to prevent double encoding attacks. # Since: 1.2.24 # JkOptions +RejectUnsafeURI # This option will collapse multiple adjacent slashes # in request URLs before looking for mount or unmount # matches. # Since: 1.2.41 # JkOptions +CollapseSlashesAll # After setting JkStripSession to "On", mod_jk will # strip all ";jsessionid=..." from request URLs it # does *not* forward to a backend. # This is useful, if all links in a webapp use # URLencoded session IDs and parts of the static # content should be delivered directly by Apache. # Of course you can also do it with mod_rewrite. # Since: 1.2.21 # JkStripSession On # Start a separate thread for internal tasks like # idle connection probing, connection pool resizing # and load value decay. # Run these tasks every JkWatchdogInterval seconds. # Since: 1.2.27 JkWatchdogInterval 60 # Configure access to jk-status and jk-manager # If you want to make this available in a virtual host, # either move this block into the virtual host # or copy it logically there by including "JkMountCopy On" # in the virtual host. # Add an appropriate authentication method here! # Inside Location we can omit the URL in JkMount JkMount jk-status Order deny,allow Deny from all Allow from 127.0.0.1 # Inside Location we can omit the URL in JkMount JkMount jk-manager Order deny,allow Deny from all Allow from 127.0.0.1 # If you want to put all mounts into an external file # that gets reloaded automatically after changes # (with a default latency of 1 minute), # you can define the name of the file here. # JkMountFile conf/extra/uriworkermap.properties # Example for Mounting a context to the worker "balancer" # The URL syntax "a|b" instantiates two mounts at once, # the first one is "a", the second one is "ab". # JkMount /myapp|/* balancer # Example for UnMounting requests for all workers # using a simple URL pattern # Since: 1.2.26 # JkUnMount /myapp/static/* * # Example for UnMounting requests for a named worker # JkUnMount /myapp/images/* balancer # Example for UnMounting requests using regexps # SetEnvIf REQUEST_URI "\.(htm|html|css|gif|jpg|js)$" no-jk # Example for setting a reply timeout depending on the request URL # Since: 1.2.27 # SetEnvIf Request_URI "/transactions/" JK_REPLY_TIMEOUT=600000 # Example for disabling reply timeouts for certain request URLs # Since: 1.2.27 # SetEnvIf Request_URI "/reports/" JK_REPLY_TIMEOUT=0 # IMPORTANT: Mounts and virtual hosts # If you are using VirtualHost elements, you # - can put mounts only used in some virtual host into its VirtualHost element # - can copy all global mounts to it using "JkMountCopy On" inside the VirtualHost # - can copy all global mounts to all virtual hosts by putting # "JkMountCopy All" into the global server # Since: 1.2.26 tomcat-connectors-1.2.41-src/LICENSE0000644000000000000020000003243511007303570015323 0ustar rootbin Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. TOMCAT CONNECTORS SUBCOMPONENTS: The Tomcat Connectors includes a number of subcomponents with separate copyright notices and license terms. Your use of the source code for the these subcomponents is subject to the terms and conditions of the following licenses. From native/common/ap_snprintf.c: * * cvt - IEEE floating point formatting routines. * Derived from UNIX V7, Copyright(C) Caldera International Inc. * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code and documentation must retain the above copyright notice, this list of conditions and the following disclaimer. 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. All advertising materials mentioning features or use of this software must display the following acknowledgement: This product includes software developed or owned by Caldera International, Inc. Neither the name of Caldera International, Inc. nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission. USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 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 CALDERA INTERNATIONAL, INC. 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. tomcat-connectors-1.2.41-src/tools/0000755000000000000020000000000012555256551015466 5ustar rootbintomcat-connectors-1.2.41-src/tools/signfile.sh0000755000000000000020000000331112303411111017573 0ustar rootbin#!/bin/bash # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. gpgopts="-ba" for o do case "$o" in *=*) a=`echo "$o" | sed 's/^[-_a-zA-Z0-9]*=//'` ;; *) a='' ;; esac case "$o" in --default-key=* ) gpgopts="$gpgopts --default-key $a" shift ;; --passphrase=* ) gpgopts="$gpgopts --passphrase $a" shift ;; * ) break ;; esac done # Try to locate a MD5 binary md5_bin="`which md5sum 2>/dev/null || type md5sum 2>&1`" if [ -x "$md5_bin" ]; then MD5SUM="$md5_bin --binary " else MD5SUM="echo 00000000000000000000000000000000 " fi # Try to locate a SHA1 binary sha1_bin="`which sha1sum 2>/dev/null || type sha1sum 2>&1`" if [ -x "$sha1_bin" ]; then SHA1SUM="$sha1_bin --binary " else SHA1SUM="echo 0000000000000000000000000000000000000000 " fi for o do echo "Signing $o" gpg $gpgopts $o $MD5SUM $o > $o.md5 $SHA1SUM $o > $o.sha1 done tomcat-connectors-1.2.41-src/tools/jkbindist.sh0000755000000000000020000000617712322735555020017 0ustar rootbin#!/bin/bash # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Create windows binary distribution archive # prefix="tomcat-connectors" tools="`pwd`" sign="" #################### NO CHANGE BELOW THIS LINE ############## #################### FUNCTIONS ############## usage() { echo "Usage:: $0 -v VERSION -w WEBSERVER -o OS -a ARCH " echo " -v: version to package" echo " -w: package for web server" echo " -o: Operating System" echo " -a: Architecture" echo " -p: GNU PG passphrrase used for signing" echo " -k: ID of GNU PG key to use for signing" } while getopts :v:w:o:a:p:k: c do case $c in v) version=$OPTARG;; w) websrv=$OPTARG;; k) sign="--default-key=$OPTARG $sign";; p) sign="--passphrase=$OPTARG $sign";; o) opsys=$OPTARG;; a) arch=$OPTARG;; \:) usage exit 2;; \?) usage exit 2;; esac done shift `expr $OPTIND - 1` if [ -z "$version" -o -z "$websrv" ] then usage exit 2 fi if [ -z "$opsys" ] then opsys="`uname -s | tr [A-Z] [a-z]`" case "$opsys" in cygwin*) opsys=windows ;; esac fi if [ -z "$arch" ] then arch="`uname -m`" fi if [ ! -f "$1" ] then usage exit 2 fi case "$websrv" in httpd*) webdesc="Apache HTTP Server" ;; iis*) webdesc="Microsoft IIS Web Server" ;; netscape*|nsapi*) webdesc="Oracle iPlanet Web Server" ;; *) echo "Unknown web server: $webserv" echo " Supported are: httpd, iis, nsapi" ;; esac dist=${prefix}-${version}-${opsys}-${arch}-${websrv} dtop=${tools}/.. copy="LICENSE NOTICE" rm -f ${copy} 2>/dev/null rm -f ${dist} 2>/dev/null rm -f ${dist}.* 2>/dev/null cat << EOF > README Apache Tomcat Connectors - $version Here you'll find module binaries for $webdesc. Check the online documentation at http://tomcat.apache.org/connectors-doc/ for installation instructions. The Apache Tomcat Project http://tomcat.apache.org EOF umask 022 for i in ${copy} do if [ -f ${dtop}/$i ] then cp ${dtop}/$i . else cp ${dtop}/native/$i . fi unix2dos $i done unix2dos README #chmod 755 $1 # Pack archive=${dist}.zip zip -9 -j ${archive} $@ README ${copy} # Sign . ${tools}/signfile.sh ${sign} ${archive} # Cleanup rm -f README ${copy} 2>/dev/null tomcat-connectors-1.2.41-src/tools/lineends.pl0000755000000000000020000001047210666607673017641 0ustar rootbin#!/usr/bin/perl # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # Heuristically converts line endings to the current OS's preferred format # # All existing line endings must be identical (e.g. lf's only, or even # the accedental cr.cr.lf sequence.) If some lines end lf, and others as # cr.lf, the file is presumed binary. If the cr character appears anywhere # except prefixed to an lf, the file is presumed binary. If there is no # change in the resulting file size, or the file is binary, the conversion # is discarded. # # Todo: Handle NULL stdin characters gracefully. # use IO::File; use File::Find; # The ignore list is '-' seperated, with this leading hyphen and # trailing hyphens in ever concatinated list below. $ignore = "-"; # Image formats $ignore .= "gif-jpg-jpeg-png-ico-bmp-"; # Archive formats $ignore .= "tar-gz-z-zip-jar-war-bz2-tgz-"; # Many document formats $ignore .= "eps-psd-pdf-ai-"; # Some encodings $ignore .= "ucs2-ucs4-"; # Some binary objects $ignore .= "class-so-dll-exe-obj-a-o-lo-slo-sl-dylib-"; # Some build env files $ignore .= "mcp-xdc-ncb-opt-pdb-ilk-sbr-"; $preservedate = 1; $forceending = 0; $givenpaths = 0; $notnative = 0; while (defined @ARGV[0]) { if (@ARGV[0] eq '--touch') { $preservedate = 0; } elsif (@ARGV[0] eq '--nocr') { $notnative = -1; } elsif (@ARGV[0] eq '--cr') { $notnative = 1; } elsif (@ARGV[0] eq '--force') { $forceending = 1; } elsif (@ARGV[0] eq '--FORCE') { $forceending = 2; } elsif (@ARGV[0] =~ m/^-/) { die "What is " . @ARGV[0] . " supposed to mean?\n\n" . "Syntax:\t$0 [option()s] [path(s)]\n\n" . <<'OUTCH' Where: paths specifies the top level directory to convert (default of '.') options are; --cr keep/add one ^M --nocr remove ^M's --touch the datestamp (default: keeps date/attribs) --force mismatched corrections (unbalanced ^M's) --FORCE all files regardless of file name! OUTCH } else { find(\&totxt, @ARGV[0]); print "scanned " . @ARGV[0] . "\n"; $givenpaths = 1; } shift @ARGV; } if (!$givenpaths) { find(\&totxt, '.'); print "did .\n"; } sub totxt { $oname = $_; $tname = '.#' . $_; if (!-f) { return; } @exts = split /\./; if ($forceending < 2) { while ($#exts && ($ext = pop(@exts))) { if ($ignore =~ m|-$ext-|i) { return; } } } @ostat = stat($oname); $srcfl = new IO::File $oname, "r" or die; $dstfl = new IO::File $tname, "w" or die; binmode $srcfl; if ($notnative) { binmode $dstfl; } undef $t; while (<$srcfl>) { if (s/(\r*)\n$/\n/) { $n = length $1; if (!defined $t) { $t = $n; } if (!$forceending && (($n != $t) || m/\r/)) { print "mismatch in " .$oname. ":" .$n. " expected " .$t. "\n"; undef $t; last; } elsif ($notnative > 0) { s/\n$/\r\n/; } } print $dstfl $_; } if (defined $t && (tell $srcfl == tell $dstfl)) { undef $t; } undef $srcfl; undef $dstfl; if (defined $t) { unlink $oname or die; rename $tname, $oname or die; @anames = ($oname); if ($preservedate) { utime $ostat[9], $ostat[9], @anames; } chmod $ostat[2] & 07777, @anames; chown $ostat[5], $ostat[6], @anames; print "Converted file " . $oname . " to text in " . $File::Find::dir . "\n"; } else { unlink $tname or die; } } tomcat-connectors-1.2.41-src/tools/reports/0000755000000000000020000000000012555256551017164 5ustar rootbintomcat-connectors-1.2.41-src/tools/reports/tomcat_trend.pl0000755000000000000020000003273710516516102022205 0ustar rootbin#!/usr/local/bin/perl # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # $Id: tomcat_trend.pl 466585 2006-10-21 22:16:34Z markt $ # Author: Glenn Nielsen # Script for analyzing mod_jk.log data when logging tomcat request data using # the JkRequestLogFormat Apache mod_jk configuration. # # Generates statistics for request latency and errors. Archives the generated # data to files for later use in long term trend graphs and reports. # # tomcat_trend.pl use FileHandle; use Statistics::Descriptive; use Time::Local; # Constants %MON = ('JAN' => 0, 'Jan' => 0, 'FEB' => 1, 'Feb' => 1, 'MAR' => 2, 'Mar' => 2, 'APR' => 3, 'Apr' => 3, 'MAY' => 4, 'May' => 4, 'JUN' => 5, 'Jun' => 5, 'JUL' => 6, 'Jul' => 6, 'AUG' => 7, 'Aug' => 7, 'SEP' => 8, 'Sep' => 8, 'OCT' => 9, 'Oct' => 9, 'NOV' => 10, 'Nov' => 10, 'DEC' => 11, 'Dec' => 11,); @Months = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); # Check the args $logdir= $ARGV[0]; $archivedir = $ARGV[1]; die "Usage: $0 logdir archivedir" unless( length($logdir) && length($archivedir) ); die "Log Directory $logdir doesn't exist" unless( -d $logdir); die "Archive Directory $archivedir doesn't exist" unless( -d $archivedir); # Get start date from global.data if it exists if( -e "$archivedir/global.data" ) { # Get the start date from the last entry in global.data @tail = `tail -1 $archivedir/global.data`; $startdate = (split /\s+/,$tail[0])[0]; ($day, $mon, $year) = (localtime($startdate))[3..5]; if ($day == 31) { $day=1; $month++; if ($month > 11) { $month=0; $year++; } } $startdate = timelocal(0,0,0,$day+1,$mon,$year); } ($day, $mon, $year) = (localtime(time))[3..5]; $curdate = timelocal(0,0,0,$day,$mon,$year); print "Today: " . scalar(localtime($curdate)) . "\n"; # Get the log files names and date they start @logs = `ls -1 $logdir/mod_jk.log*`; foreach( @logs ) { $logfile = $_; chomp($logfile); next if ( $logfile =~ /\.(bz2|gz|zip)$/ ); @head = `head -1 $logfile`; ($mon, $day, $time, $year) = (split /\s+/,$head[0])[1..4]; ($hour, $min, $sec) = split /:/,$time; $year =~ s/\]$//; $logtime = timelocal($sec,$min,$hour,$day,$MON{$mon},$year-1900); $modjklog{$logtime} = $logfile; } # Set the startdate if this is the first time processing the logs # If we have a startdate, remove log files we con't need to process foreach $logtime ( sort {$a <=> $b} keys %modjklog ) { # If logs haven't been processed before, set startdate to time of # first log entry if( $startdate !~ /^\d+$/ ) { $startdate = $logtime; ($day, $mon, $year) = (localtime($startdate))[3..5]; $startdate = timelocal(0,0,0,$day,$mon,$year); last; } if( $logtime > $startdate ) { last; } # Save the previous log file since start date may start here $prevlogfile = $modjklog{$logtime}; $prevlogtime = $logtime; # Remove log files we don't need to process delete $modjklog{$logtime}; } # Add back in the previous log file where we need to start processing if( defined $prevlogtime ) { $modjklog{$prevlogtime} = $prevlogfile; } print "StartDate: " . scalar(localtime($startdate)) . "\n"; $processdate = $startdate; foreach $key ( sort {$a <=> $b} keys %modjklog ) { $logtime = $processdate; $logfile = $modjklog{$key}; print "Processing log: $logfile\n"; last if( $key >= $curdate ); $fh = new FileHandle "<$logfile"; die "Open of logfile $logfile failed: $!" unless defined $fh; while( $line = $fh->getline) { chomp($line); ($mon, $day, $time, $year) = (split /\s+/,$line)[1..4]; ($hour, $min, $sec) = split /:/,$time; $year =~ s/\]$//; if( $day !~ /^\d+/ || $hour !~ /^\d+/ || $min!~ /^\d+/ || $sec !~ /^\d+/ ) { print "Unknown log entry: $origline\n" unless $origline =~ /\.c /; next; } $logtime = timelocal($sec,$min,$hour,$day,$MON{$mon},$year-1900); if( $logtime > $processdate ) { $origline = $line; # Strip off the leading date and time $line =~ s/^\[.*\] //; # See if this is a new 5 minute period $interval = int($logtime/300); if( $interval != $previnterval ) { if( defined $previnterval ) { &IntervalStats(\%Global,\%Interval,$previnterval*300); } undef %Interval; undef @IntervalLatency; undef %IntervalWorkers; $Interval{tomcat_full} = 0; $Interval{client_gone} = 0; $Interval{latency} = \@IntervalLatency; $Interval{workers} = \%IntervalWorkers; $previnterval = $interval; } # See if this is a new day if( $day != $prevday ) { if( defined $prevday ) { &DailyStats($processdate,\%Global); } undef %Global; undef %GlobalWorkers; undef @GlobalLatency; $Global{tomcat_full} = 0; $Global{client_gone} = 0; $Global{interval} = ""; $Global{latency} = \@GlobalLatency; $Global{workers} = \%GlobalWorkers; $Global{errors} = ""; $prevday = $day; $processdate = $logtime; } # Stop processing if logtime is today last if( $logtime >= $curdate ); if( $line =~ /\d\)\]{0,1}: / ) { # Handle a mod_jk error if( $line =~ /(jk_tcp_socket_recvfull failed|ERROR: Receiving from tomcat failed)/ ) { $Global{tomcat_full}++; $Interval{tomcat_full}++; } elsif( $line =~ /(ajp_process_callback - write failed|ERROR sending data to client. Connection aborted or network problems|Client connection aborted or network problems)/ ) { $Global{client_gone}++; $Interval{client_gone}++; } next; } else { # Handle a mod_jk request log entry $line =~ s/^\[.*\] //; $line =~ s/\"(GET|POST|OPTIONS|HEAD)[^\"]*\" //; $line =~ s/[\?\;].*\"//; $line =~ s/\"//g; ($work, $host, $page, $status, $latency) = split /\s+/,$line; $page =~ s/\/\//\//g; $page =~ s/\.\//\//g; if( length($work) <= 0 || length($host) <= 0 || length($page) <= 0 || $status !~ /^\d+$/ || $latency !~ /^\d+\.\d+$/ ) { print "Unknown log entry: $origline\n" unless $origline =~ /\.c /; next; } # Throw out abnormally long requests and log them as an error if( $latency >= 1800 ) { $Global{errors} .= "Error: $page has an HTTP status of $status and an "; $Global{errors} .= "abnormally long request latency of $latency seconds\n"; next; } # Save the data by day for Global, Worker, and Host push @{$Global{latency}},$latency; $workers = $Global{workers}; if( !defined $$workers{$work} ) { undef @{"$work"}; undef %{"$work"}; undef %{"$work-hosts"}; ${"$work"}{latency} = \@{"$work"}; ${"$work"}{hosts} = \%{"$work-hosts"}; ${"$work"}{interval} = ""; $$workers{$work} = \%{"$work"}; } $worker = $$workers{$work}; push @{$$worker{latency}},$latency; if( !defined $$worker{hosts}{$host} ) { undef @{"$work-$host"}; undef %{"$work-$host"}; undef %{"$work-$host-pages"}; ${"$work-$host"}{latency} = \@{"$work-$host"}; ${"$work-$host"}{pages} = \%{"$work-$host-pages"}; ${"$work-$host"}{interval} = ""; $$worker{hosts}{$host} = \%{"$work-$host"}; } $hoster = $$worker{hosts}{$host}; push @{$$hoster{latency}},$latency; if( !defined $$hoster{pages}{$page} ) { undef @{"$work-$host-$page"}; $$hoster{pages}{$page} = \@{"$work-$host-$page"}; } push @{$$hoster{pages}{$page}},$latency; # Save the data by 5 minute interval for Global, Worker, and Host push @{$Interval{latency}},$latency; $workers = $Interval{workers}; if( !defined $$workers{"$work"} ) { undef @{"int-$work"}; undef %{"int-$work"}; undef %{"int-$work-hosts"}; ${"int-$work"}{latency} = \@{"int-$work"}; ${"int-$work"}{hosts} = \%{"int-$work-hosts"}; $$workers{$work} = \%{"int-$work"}; } $worker = $$workers{$work}; push @{$$worker{latency}},$latency; if( !defined $$worker{hosts}{$host} ) { undef @{"int-$work-$host"}; undef %{"int-$work-$host"}; ${"int-$work-$host"}{latency} = \@{"int-$work-$host"}; $$worker{hosts}{$host} = \%{"int-$work-$host"}; } $hoster = $$worker{hosts}{$host}; push @{$$hoster{latency}},$latency; } } } undef $fh; } # If the last log file ends before switch to the current day, # output the last days data if( $logtime < $curdate ) { &IntervalStats(\%Global,\%Interval,$previnterval*300); &DailyStats($processdate,\%Global); } exit; sub IntervalStats($$$) { my $global = $_[0]; my $data = $_[1]; my $interval = $_[2]; ($count,$median,$mean,$stddev,$min,$max) = &CalcStats($$data{latency}); $$global{interval} .= "$interval $count $median $mean $stddev $min $max $$data{client_gone} $$data{tomcat_full}\n"; foreach $work ( keys %{$$data{workers}} ) { $worker = $$data{workers}{$work}; $gworker = $$global{workers}{$work}; ($count,$median,$mean,$stddev,$min,$max) = &CalcStats($$worker{latency}); $$gworker{interval} .= "$interval $count $median $mean $stddev $min $max\n"; foreach $host ( keys %{$$worker{hosts}} ) { $hoster = $$worker{hosts}{$host}; $ghoster = $$gworker{hosts}{$host}; ($count,$median,$mean,$stddev,$min,$max) = &CalcStats($$hoster{latency}); $$ghoster{interval} .= "$interval $count $median $mean $stddev $min $max\n"; } } } sub DailyStats($$) { my $date = $_[0]; my $data = $_[1]; &SaveStats($data,$date,"","global"); &SaveFile($$data{interval},$date,"","daily"); foreach $work ( keys %{$$data{workers}} ) { $worker = $$data{workers}{$work}; &SaveStats($worker,$date,$work,"global"); &SaveFile($$worker{interval},$date,$work,"daily"); foreach $host ( keys %{$$worker{hosts}} ) { $hoster = $$worker{hosts}{$host}; &SaveStats($hoster,$date,"$work/$host","global"); &SaveFile($$hoster{interval},$date,"$work/$host","daily"); $pagedata = ""; foreach $page ( sort keys %{$$hoster{pages}} ) { $pager = $$hoster{pages}{$page}; ($count,$median,$mean,$stddev,$min,$max) = &CalcStats($pager); $pagedata .= "$page $count $median $mean $stddev $min $max\n"; } $pagedata .= $$data{errors}; &SaveFile($pagedata,$date,"$work/$host","request"); } } } sub CalcStats($) { my $data = $_[0]; $stats = Statistics::Descriptive::Full->new(); $stats->add_data(@{$data}); $median = $stats->median(); $mean = $stats->mean(); $stddev = $stats->standard_deviation(); $max = $stats->max(); $min = $stats->min(); $count = $stats->count(); return ($count,$median,$mean,$stddev,$min,$max); } sub SaveStats($$$$) { my $data = $_[0]; my $date = $_[1]; my $dir = $_[2]; my $file = $_[3]; if( length($dir) > 0 ) { $dir = "$archivedir/$dir"; } else { $dir = $archivedir; } mkdir "$dir",0755; $outfile = "$dir/${file}.data"; ($count,$median,$mean,$stddev,$min,$max) = &CalcStats($$data{latency}); open DATA, ">>$outfile" or die $!; print DATA "$date $count $median $mean $stddev $min $max"; print DATA " $$data{client_gone} $$data{tomcat_full}" if defined $$data{tomcat_full}; print DATA "\n"; close DATA; } sub SaveFile($$$$) { my $data = $_[0]; my $date = $_[1]; my $dir = $_[2]; my $file = $_[3]; my ($day, $mon, $year); ($day, $mon, $year) = (localtime($date))[3..5]; $year += 1900; $mon++; $mon = "0$mon" if $mon < 10; $day = "0$day" if $day < 10; $file = "$year-$mon-$day-$file"; if( length($dir) > 0 ) { $dir = "$archivedir/$dir"; } else { $dir = $archivedir; } mkdir "$dir",0755; $outfile = "$dir/${file}.data"; open DATA, ">>$outfile" or die $!; print DATA $data; close DATA; } tomcat-connectors-1.2.41-src/tools/reports/tomcat_reports.pl0000755000000000000020000003020210516516102022550 0ustar rootbin#!/usr/local/bin/perl # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # $Id: tomcat_reports.pl 466585 2006-10-21 22:16:34Z markt $ # Author: Glenn Nielsen # Script for generating reports and graphs using statistical data generated # by the tomcat_trend.pl script. # # The following graphs are created: # # tomcat_request.png # Long term trend graph of total number of tomcat requests handled # # tomcat_median.png # Long term overall trend graph of tomcat request latency median # # tomcat_deviation.png # Long term overall trend graph of tomcat request mean and standard deviation # # tomcat_error.png # Long term trend graph of requests rejected by tomcat. Shows requests rejected # when tomcat has no request processors available. Can be an indicator that tomcat # is overloaded or having other scaling problems. # # tomcat_client.png # Long term trend graph of requests forward to tomcat which were aborted by the remote # client (browser). You will normally see some aborted requests. High numbers of these # can be an indicator that tomcat is overloaded or there are requests which have very high # latency. # # tomcat_reports.pl use GD; use GD::Graph; use GD::Graph::Data; use GD::Graph::lines; use GD::Graph::linespoints; use Statistics::Descriptive; use Time::Local; # Constants %MON = ('JAN' => 0, 'Jan' => 0, 'FEB' => 1, 'Feb' => 1, 'MAR' => 2, 'Mar' => 2, 'APR' => 3, 'Apr' => 3, 'MAY' => 4, 'May' => 4, 'JUN' => 5, 'Jun' => 5, 'JUL' => 6, 'Jul' => 6, 'AUG' => 7, 'Aug' => 7, 'SEP' => 8, 'Sep' => 8, 'OCT' => 9, 'Oct' => 9, 'NOV' => 10, 'Nov' => 10, 'DEC' => 11, 'Dec' => 11,); @Months = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); # Check the args $archivedir = $ARGV[0]; $reportdir = $ARGV[1]; die "Usage: $0 archivedir reportdir" unless( length($archivedir) && ($reportdir) ); die "Archive Directory $archivedir doesn't exist" unless( -d $archivedir); die "Report Directory $reportdir doesn't exist" unless( -d $reportdir); # Read in data from file die "Archive Directory $archivedir has no global.data file" unless( -e "$archivedir/global.data" ); @Data = `tail -365 $archivedir/global.data`; $numdays = $#Data; $daycounter = $numdays; foreach( @Data ) { $line = $_; chomp($line); ($date,$count,$median,$mean,$stddev,$min,$max,$client_gone,$tomcat_full) = split /\s+/,$line; # print "$daycounter $date $count $median $mean $stdev $min $max $client_gone $tomcat_full\n"; $start_time = $date unless $start_time>0; $end_time = $date; push @days,int($daycounter/7); push @count,$count; push @median,$median; push @mean,$mean; push @stddev,$mean+$stddev; push @min,$min; push @max,$max; push @client_gone,$client_gone; push @tomcat_full,$tomcat_full; $daycounter--; } ($day,$mon,$year) = (localtime($start_time))[3..5]; $year += 1900; $startdate = "$Months[$mon] $day, $year"; ($day,$mon,$year) = (localtime($end_time))[3..5]; $year += 1900; $enddate = "$Months[$mon] $day, $year"; # Output request trend graph $outfile = "$reportdir/tomcat_request.png"; unlink $outfile; $stats = Statistics::Descriptive::Sparse->new(); $stats->add_data(@count); $max = $stats->max(); $min = $stats->min(); &RequestGraph(); # Output median latency trend graph $outfile = "$reportdir/tomcat_median.png"; unlink $outfile; $stats = Statistics::Descriptive::Sparse->new(); $stats->add_data(@median); $max = $stats->max(); $min = $stats->min(); &MedianGraph(); # Output latency deviation trend graph $outfile = "$reportdir/tomcat_deviation.png"; unlink $outfile; $stats = Statistics::Descriptive::Sparse->new(); $stats->add_data(@stddev); $stats->add_data(@mean); $max = $stats->max(); $min = $stats->min(); &DeviationGraph(); # Output request error trend graph $outfile = "$reportdir/tomcat_error.png"; unlink $outfile; $stats = Statistics::Descriptive::Sparse->new(); $stats->add_data(@tomcat_full); $max = $stats->max(); $min = $stats->min(); &ErrorGraph(); # Output request error trend graph $outfile = "$reportdir/tomcat_client.png"; unlink $outfile; $stats = Statistics::Descriptive::Sparse->new(); $stats->add_data(@client_gone); $max = $stats->max(); $min = $stats->min(); &ClientGraph(); exit; sub RequestGraph { $graph = GD::Graph::lines->new(800,600); @data = (\@days,\@count); $div = 100; $div = 500 if $max >= 2000; $div = 1000 if $max >= 5000; $div = 5000 if $max >= 20000; $div = 10000 if $max >= 50000; $div = 50000 if $max >= 200000; $div = 100000 if $max >= 500000; $div = 500000 if $max >= 2000000; $div = 1000000 if $max >= 5000000; $ymax = (int($max/$div) + 1)*$div; $ymin = int($min/$div)*$div; $ytick = ($ymax - $ymin)/$div; $graph->set( y_label => 'Requests', title => "Tomcat Requests by Day from $startdate to $enddate", y_min_value => $ymin, y_max_value => $ymax, y_tick_number => $ytick, y_number_format => \&val_format, x_label => 'Weeks Ago', x_label_skip => 7, x_tick_offset => $numdays%7, dclrs => [ qw(green) ], legend_placement => 'BC' ) or warn $graph->error; $graph->set_legend( 'Requests' ); $graph->set_title_font(GD::gdGiantFont); $graph->set_x_axis_font(GD::gdSmallFont); $graph->set_y_axis_font(GD::gdSmallFont); $graph->set_legend_font(GD::gdSmallFont); $gd = $graph->plot(\@data); die "Graph Plot Failed: " . $graph->error unless defined $gd; open IMG, ">$outfile" or die $!; print IMG $gd->png or die $gd->error; close IMG; } sub MedianGraph { $graph = GD::Graph::lines->new(800,600); @data = (\@days,\@median); $div = .05; $div = .1 if $max >= .5; $div = .5 if $max >= 2; $div = 1 if $max >= 5; $div = 5 if $max >= 20; $div = 10 if $max >= 50; $div = 50 if $max >= 200; $div = 100 if $max >= 500; $ymax = (int($max/$div) + 1)*$div; $ytick = $ymax/$div; $graph->set( y_label => 'Latency (Seconds)', title => "Tomcat Request Median Latency by Day from $startdate to $enddate", y_min_value => 0, y_max_value => $ymax, y_tick_number => $ytick, y_number_format => \&val_format, x_label => 'Weeks Ago', x_label_skip => 7, x_tick_offset => $numdays%7, dclrs => [ qw(green) ], legend_placement => 'BC' ) or warn $graph->error; $graph->set_legend( 'Median' ); $graph->set_title_font(GD::gdGiantFont); $graph->set_x_axis_font(GD::gdSmallFont); $graph->set_y_axis_font(GD::gdSmallFont); $graph->set_legend_font(GD::gdSmallFont); $gd = $graph->plot(\@data); die "Graph Plot Failed: " . $graph->error unless defined $gd; open IMG, ">$outfile" or die $!; print IMG $gd->png or die $gd->error; close IMG; } sub DeviationGraph { $graph = GD::Graph::lines->new(800,600); @data = (\@days,\@mean,\@stddev); $div = .1; $div = .5 if $max >= 2; $div = 1 if $max >= 5; $div = 5 if $max >= 20; $div = 10 if $max >= 50; $div = 50 if $max >= 200; $div = 100 if $max >= 500; $ymax = (int($max/$div) + 1)*$div; $ytick = $ymax/$div; $graph->set( y_label => 'Latency (Seconds)', title => "Tomcat Request Latency Mean and Deviation by Day from $startdate to $enddate", y_max_value => $ymax, y_tick_number => $ytick, x_label => 'Weeks Ago', x_label_skip => 7, x_tick_offset => $numdays%7, dclrs => [ qw(green yellow) ], legend_placement => 'BC' ) or warn $graph->error; $graph->set_legend( 'Mean', 'Mean plus Standard Deviation' ); $graph->set_title_font(GD::gdGiantFont); $graph->set_x_axis_font(GD::gdSmallFont); $graph->set_y_axis_font(GD::gdSmallFont); $graph->set_legend_font(GD::gdSmallFont); $gd = $graph->plot(\@data); die "Graph Plot Failed: " . $graph->error unless defined $gd; open IMG, ">$outfile" or die $!; print IMG $gd->png or die $gd->error; close IMG; } sub ErrorGraph { $graph = GD::Graph::lines->new(800,600); @data = (\@days,\@tomcat_full); $div = 5; $div = 10 if $max >=100; $div = 50 if $max >= 200; $div = 100 if $max >= 1000; $div = 500 if $max >= 2000; $div = 1000 if $max >= 5000; $div = 5000 if $max >= 20000; $div = 10000 if $max >= 50000; $div = 50000 if $max >= 200000; $div = 100000 if $max >= 500000; $div = 500000 if $max >= 2000000; $div = 1000000 if $max >= 5000000; $ymax = (int($max/$div) + 1)*$div; $ymin = int($min/$div)*$div; $ytick = ($ymax - $ymin)/$div; $graph->set( y_label => 'Requests', title => "Tomcat Rejected Request by Day from $startdate to $enddate", y_min_value => $ymin, y_max_value => $ymax, y_tick_number => $ytick, y_number_format => \&val_format, x_label => 'Weeks Ago', x_label_skip => 7, x_tick_offset => $numdays%7, dclrs => [ qw(green) ], legend_placement => 'BC' ) or warn $graph->error; $graph->set_legend( 'Tomcat Rejected Requests' ); $graph->set_title_font(GD::gdGiantFont); $graph->set_x_axis_font(GD::gdSmallFont); $graph->set_y_axis_font(GD::gdSmallFont); $graph->set_legend_font(GD::gdSmallFont); $gd = $graph->plot(\@data); die "Graph Plot Failed: " . $graph->error unless defined $gd; open IMG, ">$outfile" or die $!; print IMG $gd->png or die $gd->error; close IMG; } sub ClientGraph { $graph = GD::Graph::lines->new(800,600); @data = (\@days,\@client_gone); $div = 5; $div = 10 if $max >=100; $div = 50 if $max >= 200; $div = 100 if $max >= 1000; $div = 500 if $max >= 2000; $div = 1000 if $max >= 5000; $div = 5000 if $max >= 20000; $div = 10000 if $max >= 50000; $div = 50000 if $max >= 200000; $div = 100000 if $max >= 500000; $div = 500000 if $max >= 2000000; $div = 1000000 if $max >= 5000000; $ymax = (int($max/$div) + 1)*$div; $ymin = int($min/$div)*$div; $ytick = ($ymax - $ymin)/$div; $graph->set( y_label => 'Requests', title => "Tomcat Client Aborted Requests by Day from $startdate to $enddate", y_min_value => $ymin, y_max_value => $ymax, y_tick_number => $ytick, y_number_format => \&val_format, x_label => 'Weeks Ago', x_label_skip => 7, x_tick_offset => $numdays%7, dclrs => [ qw(green) ], legend_placement => 'BC' ) or warn $graph->error; $graph->set_legend( 'Tomcat Client Aborted Requests' ); $graph->set_title_font(GD::gdGiantFont); $graph->set_x_axis_font(GD::gdSmallFont); $graph->set_y_axis_font(GD::gdSmallFont); $graph->set_legend_font(GD::gdSmallFont); $gd = $graph->plot(\@data); die "Graph Plot Failed: " . $graph->error unless defined $gd; open IMG, ">$outfile" or die $!; print IMG $gd->png or die $gd->error; close IMG; } sub val_format { my $value = shift; my $ret; $ret = $value; if( $ret =~ /\./ ) { $ret =~ s/\.(\d\d\d).*/\.$1/; } else { $ret =~ s/(\d+)(\d\d\d)$/$1,$2/; $ret =~ s/(\d+)(\d\d\d),(\d\d\d)$/$1,$2,$3/; } return $ret; } sub size_format { my $value = shift; my $ret; if( $max >= 5000 ) { $value = int(($value/1024)+.5); } $ret = $value; $ret =~ s/(\d+)(\d\d\d)$/$1,$2/; $ret =~ s/(\d+)(\d\d\d),(\d\d\d)$/$1,$2,$3/; return $ret; } tomcat-connectors-1.2.41-src/tools/reports/README.txt0000644000000000000020000000266610666607673020702 0ustar rootbin Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. This directory contains perl scripts which can be used to generate statistics for tomcat requests and errors logged by mod_jk. See the comments in the scripts for more details. A great deal of statistical data is generated but at this time only long term trend graphs are being created and no reports. This is only a start. Many more graphs and reports could be generated from the data. Please consider contributing back any new reports or graphs you create. Thanks. Requires the following perl modules and libraries: GD 1.8.x graphics library http://www.boutell.com/gd/. GD 1.4.x perl module. GD Graph perl module. GD TextUtil perl module. StatisticsDescriptive perl module. tomcat-connectors-1.2.41-src/tools/dist/0000755000000000000020000000000012555256551016431 5ustar rootbintomcat-connectors-1.2.41-src/tools/dist/binaries/0000755000000000000020000000000012555256550020224 5ustar rootbintomcat-connectors-1.2.41-src/tools/dist/binaries/windows/0000755000000000000020000000000012555256551021717 5ustar rootbintomcat-connectors-1.2.41-src/tools/dist/binaries/windows/symbols/0000755000000000000020000000000012555256551023407 5ustar rootbintomcat-connectors-1.2.41-src/tools/dist/binaries/windows/symbols/README.html0000644000000000000020000000242011603351453025216 0ustar rootbin

    Download from your nearest mirror site!

    Binary Diagnostic Symbol Downloads

    We now distribute a -symbols.zip file containing the precise debugging symbols corresponding to each released binary distribution. For the typical user, there is no need to download these archives.

    These -symbols.zip packages contain the .pdb diagnostic symbol files (which correpsond to the distributed binary release) and can be used by nearly all modern Windows debugging tools, including the freely available WinDbg utility. They are most useful for the core developers to review crash dumps generated by Dr. Watson if Apache experiences a General Protection Fault. They also provide additional backtrace details in Dr. Watson crash log files, if they are installed into the Apache directory which is experiencing General Protection Fault or other crash issues.

    If you don't understand a word of this, and a developer did not personally ask you to install them to help troubleshoot a problem, please trust that you do not need these files to install or run Apache Tomcat Connectors.

    tomcat-connectors-1.2.41-src/tools/dist/binaries/windows/symbols/HEADER.html0000644000000000000020000000063211603351120025203 0ustar rootbin

    Index of /dist/tomcat/tomcat-connectors/jk/binaries/windows/symbols

    Important Notices

    Download from your nearest mirror site!

    tomcat-connectors-1.2.41-src/tools/dist/binaries/windows/README.html0000644000000000000020000000467412555244250023546 0ustar rootbin

    Download from your nearest mirror site!

    Please do not download from www.apache.org. Use a mirror site to help us save apache.org bandwidth and to speed up your download. Click here to find your nearest mirror.

    Windows Users, Read These First...

    Warning: TCP/IP networking must be installed

    TCP/IP must be correctly installed, configured and running in order to install and use Apache Tomcat Connectors on Windows.

    Warning about the Quality of Service driver

    We suggest disabling the "Quality of Service" (or QoS) network driver from Microsoft if you primarily use the machine as an Web Server, as connector does not support the QoS extensions to the WinSock API.

    Warning about Firewall and similar software

    Most Firewall programs, Web Spam filters and other TCP/IP driver-based products (including spyware!) do not correctly implement the entire WinSock API. The shortcuts taken by the developers of such products could cause connector to fail.

    The current stable release is 1.2.41

    See the Apache Tomcat Connectors changelog for the complete list of features and bugs fixed in this release.

    Debugging and Source Code

    You can find a corresponding -symbols.zip archive of the debugging databases in the symbols/ directory, these are typically not needed. This -symbols.zip archive can be unpacked into the web server installation directory, providing all of the .pdb diagnostic files allowing most Windows debugging tools (and the Dr. Watson utility) to produce useful crash analysis.

    You will find the source code package in the /dist/tomcat-connectors/jk/ source tree. The -src.zip file contains only source and build files, and contains no binary executable files.

    This binary release was created with Microsoft Windows DDK 7.1, using a more recent Platform SDK.

    tomcat-connectors-1.2.41-src/tools/dist/binaries/windows/HEADER.html0000644000000000000020000000070511603351120023514 0ustar rootbin

    Index of /dist/tomcat/tomcat-connectors/jk/binaries/windows

    Important Notices

    Download from your nearest mirror site!

    tomcat-connectors-1.2.41-src/tools/dist/binaries/netware/0000755000000000000020000000000012555256551021672 5ustar rootbintomcat-connectors-1.2.41-src/tools/dist/binaries/netware/HEADER.html0000644000000000000020000000033111721761544023502 0ustar rootbin

    Index of /dist/tomcat/tomcat-connectors/jk/binaries/netware

    Download from your nearest mirror site!

    tomcat-connectors-1.2.41-src/tools/dist/.htaccess0000644000000000000020000000145611603350163020220 0ustar rootbin# Directives controlling the display of server-generated directory listings. IndexOptions DescriptionWidth=34 AddDescription "OpenPGP ASCII armored signature" .asc AddDescription "MD5 checksum file" .md5 AddDescription "SHA1 checksum file" .sha1 AddDescription "SHA256 checksum file" .sha256 AddDescription "ZIP compressed archive" .zip AddDescription "GZIP compressed document" .gz AddDescription "Unix tar archive" .tar AddDescription "GZIP compressed tar archive" .tgz AddDescription "plain text document" .txt AddDescription "Unified diff patch" .diff AddDescription "shared object file" .so AddDescription "dynamically linked library" .dll AddIcon /icons/generic.sec.gif .asc .key AddIcon /icons/patch.gif .diff AddIcon /icons/screw2.gif .md5 AddIcon /icons/screw2.gif .sha1 AddIcon /icons/screw2.gif .sha256 tomcat-connectors-1.2.41-src/tools/dist/README.html0000644000000000000020000000401611765443116020252 0ustar rootbin

    Download from your nearest mirror site!

    Do not download from www.apache.org. Please use a mirror site to help us save apache.org bandwidth. Go here to find your nearest mirror.

    Binary Releases

    Are available in the binaries/ directory. Every binary distribution contains an install script. See README for details.

    Current Releases

    For details on current releases, please see the Apache Tomcat Connectors Download Page.

    Note; the -src.zip versions of Apache Tomcat Connectors are nearly identical to the .tar.gz versions. However, they offer the source files in DOS/Windows CR/LF text format, and include the Winows build files. These -src.zip files do NOT contain binaries! See the binaries/windows/ directory for the Windows binary distributions.

    Older Releases

    Only current, recommended releases are available on www.apache.org and the mirror sites. Older releases can be obtained from the archive site.

    PGP Signatures

    You must verify the integrity of the downloaded files. We provide OpenPGP signatures for every release file. This signature should be matched against the KEYS file which contains the OpenPGP keys of the Release Managers. We also provide an MD5 checksum for every release file. After you download the file, you should calculate a checksum for your download, and make sure it is the same as ours.

    tomcat-connectors-1.2.41-src/tools/dist/HEADER.html0000644000000000000020000000125011603351120020222 0ustar rootbin

    Index of /dist/tomcat/tomcat-connectors/jk

    Apache Tomcat Connectors Source Code Distributions

    This download page includes only the sources to compile and build Apache Tomcat Connectors yourself with the proper tools. Download the precompiled distribution for your platform from binaries/.

    Important Notices

    tomcat-connectors-1.2.41-src/tools/jkrelease.sh0000755000000000000020000002133012446103243017755 0ustar rootbin#!/bin/bash # # Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Make sure to set your path so that we can find # the following binaries: # cd, mkdir, cp, rm, find # svn # ant # libtoolize, aclocal, autoheader, automake, autoconf # tar, zip, gzip # gpg # And any one of: w3m, elinks, links (links2) SVNROOT="http://svn.apache.org/repos/asf" SVNPROJ="tomcat/jk" JK_CVST="tomcat-connectors" JK_OWNER="root" JK_GROUP="bin" JK_TOOLS="`pwd`" COPY_JK="README.txt HOWTO-RELEASE.txt native jkstatus support tools xdocs" COPY_NATIVE="LICENSE NOTICE" COPY_BUILD="docs" COPY_CONF="httpd-jk.conf uriworkermap.properties workers.properties" SIGN_OPTS="" #################### NO CHANGE BELOW THIS LINE ############## #################### FUNCTIONS ############## usage() { echo "Usage:: $0 -v VERSION [-f] [-r revision] [-t tag | -b BRANCH | -T | -d DIR]" echo " -v: version to package" echo " -f: force, do not validate tag against version" echo " -h: create text documentation for html" echo " -t: tag to use if different from version" echo " -r: revision to package" echo " -b: package from branch BRANCH" echo " -T: package from trunk" echo " -d: package from local directory" echo " -o: owner used for creating tar archive" echo " -g: group used for creating tar archive" echo " -p: GNU PG passphrrase used for signing" echo " -k: ID of GNU PG key to use for signing" } copy_files() { src=$1 target=$2 list="$3" mkdir -p $target for item in $list do echo "Copying $item from $src ..." cp -pr $src/$item $target/ done } #################### MAIN ############## txtgen=n conflict=0 while getopts :v:t:r:b:d:p:k:o:g:Tfh c do case $c in v) version=$OPTARG;; t) tag=$OPTARG conflict=$(($conflict+1));; r) revision=$OPTARG;; k) SIGN_OPTS="--default-key=$OPTARG $SIGN_OPTS";; p) SIGN_OPTS="--passphrase=$OPTARG $SIGN_OPTS";; o) JK_OWNER=$OPTARG;; g) JK_GROUP=$OPTARG;; b) branch=$OPTARG conflict=$(($conflict+1));; T) trunk=trunk conflict=$(($conflict+1));; d) local_dir=$OPTARG conflict=$(($conflict+1));; f) force='y';; h) txtgen='y';; \:) usage exit 2;; \?) usage exit 2;; esac done shift `expr $OPTIND - 1` if [ $conflict -gt 1 ] then usage echo "Only one of the options '-t', '-b', '-T' and '-d' is allowed." exit 2 fi if [ -n "$local_dir" ] then echo "Caution: Packaging from directory!" echo "Make sure the directory is committed." answer="x" while [ "$answer" != "y" -a "$answer" != "n" ] do echo "Do you want to proceed? [y/n]" read answer done if [ "$answer" != "y" ] then echo "Aborting." exit 4 fi fi if [ -z "$version" ] then usage exit 2 fi if [ -n "$revision" ] then revision="-r $revision" fi if [ -n "$trunk" ] then JK_SVN_URL="${SVNROOT}/${SVNPROJ}/trunk" svn_url_info="`svn help info | grep URL`" if [ -n "$svn_url_info" ] then JK_SVN_INFO="${JK_SVN_URL}" else JK_SVN_INFO=. fi JK_REV=`svn info $revision $JK_SVN_INFO | awk '$1 == "Revision:" {print $2}'` if [ -z "$JK_REV" ] then echo "No Revision found at '$JK_SVN_URL'" exit 3 fi JK_SUFFIX=-${JK_REV} JK_DIST=${JK_CVST}-${version}-dev${JK_SUFFIX}-src elif [ -n "$branch" ] then JK_BRANCH=`echo $branch | sed -e 's#/#__#g'` JK_SVN_URL="${SVNROOT}/${SVNPROJ}/branches/$branch" JK_REV=`svn info $revision ${JK_SVN_URL} | awk '$1 == "Revision:" {print $2}'` if [ -z "$JK_REV" ] then echo "No Revision found at '$JK_SVN_URL'" exit 3 fi JK_SUFFIX=-${JK_BRANCH}-${JK_REV} JK_DIST=${JK_CVST}-${version}-dev${JK_SUFFIX}-src elif [ -n "$local_dir" ] then JK_SVN_URL="$local_dir" JK_REV=`svn info $revision ${JK_SVN_URL} | awk '$1 == "Revision:" {print $2}'` if [ -z "$JK_REV" ] then echo "No Revision found at '$JK_SVN_URL'" exit 3 fi JK_SUFFIX=-local-`date +%Y%m%d%H%M%S`-${JK_REV} JK_DIST=${JK_CVST}-${version}-dev${JK_SUFFIX}-src else JK_VER=$version JK_TAG=`echo $version | sed -e 's#^#JK_#' -e 's#\.#_#g'` if [ -n $tag ] then if [ -z $force ] then echo $tag | grep "^$JK_TAG" > /dev/null 2>&1 if [ $? -gt 0 ] then echo "Tag '$tag' doesn't belong to version '$version'." echo "Force using '-f' if you are sure." exit 5 fi fi JK_TAG=$tag fi JK_SVN_URL="${SVNROOT}/${SVNPROJ}/tags/${JK_TAG}" JK_REV=`svn info $revision ${JK_SVN_URL} | awk '$1 == "Revision:" {print $2}'` JK_SUFFIX=" ($JK_REV)" JK_DIST=${JK_CVST}-${JK_VER}-src fi echo "Using subversion URL: $JK_SVN_URL" echo "Rolling into file $JK_DIST.*" sleep 2 umask 022 rm -rf ${JK_DIST} 2>/dev/null || true rm -rf ${JK_DIST}.* 2>/dev/null || true mkdir -p ${JK_DIST}.tmp svn export $revision "${JK_SVN_URL}" ${JK_DIST}.tmp/jk if [ $? -ne 0 ]; then echo "svn export failed" exit 1 fi # Build documentation. cd ${JK_DIST}.tmp/jk/xdocs ant cd ../../.. # Copying things into the source distribution copy_files ${JK_DIST}.tmp/jk $JK_DIST "$COPY_JK" copy_files ${JK_DIST}.tmp/jk/native $JK_DIST "$COPY_NATIVE" copy_files ${JK_DIST}.tmp/jk/build $JK_DIST "$COPY_BUILD" copy_files ${JK_DIST}.tmp/jk/conf $JK_DIST/conf "$COPY_CONF" # Remove extra directories and files targetdir=${JK_DIST} rm -rf ${targetdir}/xdocs/jk2 rm -f ${targetdir}/native/build.xml rm -f ${targetdir}/native/NOTICE rm -f ${targetdir}/native/LICENSE find ${JK_DIST} -name .cvsignore -exec rm -rf \{\} \; find ${JK_DIST} -name CVS -exec rm -rf \{\} \; find ${JK_DIST} -name .svn -exec rm -rf \{\} \; cd ${JK_DIST}/native if [ $txtgen = y ] then # Check for links, elinks or w3m W3MOPTS="-dump -cols 80 -t 4 -S -O iso-8859-1 -T text/html" ELNKOPTS="-dump -dump-width 80 -dump-charset iso-8859-1 -no-numbering -no-home -no-references" LNKOPTS="-dump -width 80 -codepage iso-8859-1 -no-g -html-numbered-links 0" LYXOPTS="-dump -width=80 -nolist -nostatus -noprint -assume_local_charset=iso-8859-1" failed=true for tool in `echo "w3m elinks links lynx"` do found=false for dir in `echo ${PATH} | sed 's!^:!.:!;s!:$!:.!;s!::!:.:!g;s!:! !g'` do if [ -x ${dir}/${tool} ] then found=true break fi done # Try to run it if ${found} then case ${tool} in w3m) TOOL="w3m $W3MOPTS" ;; links) TOOL="links $LNKOPTS" ;; elinks) TOOL="elinks $ELNKOPTS" ;; lynx) TOOL="lynx $LYXOPTS" ;; esac rm -f CHANGES echo "Creating the CHANGES file using '$TOOL' ..." ${TOOL} ../docs/miscellaneous/printer/changelog.html > CHANGES 2>/dev/null if [ -f CHANGES -a -s CHANGES ] then failed=false break fi fi done if [ ${failed} = "true" ] then echo "Can't convert html to text (CHANGES)" exit 1 fi # Export text docs echo "Creating the NEWS file using '$TOOL' ..." rm -f NEWS touch NEWS for news in `ls -r ../xdocs/news/[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].xml` do print=`echo $news | sed -e 's#xdocs/news#docs/news/printer#' -e 's#\.xml#.html#'` echo "Adding $print to NEWS file ..." ${TOOL} $print >>NEWS done if [ ! -s NEWS ] then echo "Can't convert html to text (NEWS)" exit 1 fi fi # Generate configure et. al. ./buildconf.sh cd ../../ # Pack tar cfz ${JK_DIST}.tar.gz --owner="${JK_OWNER}" --group="${JK_GROUP}" ${JK_DIST} || exit 1 perl ${JK_DIST}/tools/lineends.pl --cr ${JK_DIST} zip -9 -r ${JK_DIST}.zip ${JK_DIST} # Create detached signature and verify it archive=${JK_DIST}.tar.gz . ${JK_TOOLS}/signfile.sh ${SIGN_OPTS} $archive archive=${JK_DIST}.zip . ${JK_TOOLS}/signfile.sh ${SIGN_OPTS} $archive # Cleanup working dirs rm -rf ${JK_DIST}.tmp rm -rf ${JK_DIST} tomcat-connectors-1.2.41-src/xdocs/0000755000000000000020000000000012555256556015453 5ustar rootbintomcat-connectors-1.2.41-src/xdocs/ajp/0000755000000000000020000000000012555256551016220 5ustar rootbintomcat-connectors-1.2.41-src/xdocs/ajp/project.xml0000644000000000000020000001155112472604371020406 0ustar rootbin The Apache Tomcat Connectors - AJP Protocol Reference The Apache Tomcat Connectors - AJP Protocol Reference tomcat-connectors-1.2.41-src/xdocs/ajp/ajpv13ext.xml0000644000000000000020000005247312555244116020574 0ustar rootbin ]> &project; Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. AJPv13 extensions Proposal Henri Gomez $Date: 2015-07-26 21:51:26 +0100 (Sun, 26 Jul 2015) $

    This document is a proposal of evolution of the current Apache JServ Protocol version 1.3, also known as ajp13. I'll not cover here the full protocol but only the add-on from ajp13. This nth pass include comments from the tomcat-dev list and misses discovered during developpment.

    ajp13 is a good protocol to link a servlet engine like tomcat to a web server like Apache:

    • use persistants connections to avoid reconnect time at each request
    • encode many http commands to reduce stream size
    • send to servlet engine many info from web server (like SSL certs)

    But ajp13 lacks support for :

    • security between web server and servlet engine. Anybody can connect to an ajp13 port (no login mecanism used) You could connect, for example with telnet, and keep the remote thread up by not sending any data (no timeout in connection)
    • context information passed from servlet engine to web server. Part of the configuration of JK, the web server connector, is to indicate to the web server which URI to handle. The mod_jk JkMount directive, told to web server which URI must be forwarded to servlet engine. A servlet engine allready knows which URI it handle and TC 3.3 is allready capable to generate a config file for JK from the list of available contexts.
    • state update of contexts from servlet engine to web server. Big site with farm of Tomcat, like ISP and virtuals hosters, may need to stop a context for admin purposes. In that case the front web server must know that the context is currently down, to eventually relay the request to another Tomcat
    • verify state of connection before sending request. Actually JK send the request to the servlet engine and next wait for the answer. But one of the beauty of the socket API, is you that you could write() to a closed connection without any error reporting, but a read() to a closed connection return you the error code.

    Let's descrive here the features and add-on that could be added to AJP13. Since this document is a proposal, a reasonable level of chaos must be expected at first. Be sure that discussion on tomcat list will help clarify points, add features but the current list seems to be a 'minimun vital'

    • Advanced login features at connect time
    • Basic authorisation system, where a shared secret key is present in web server and servlet engine.
    • Basic protocol negociation, just to be sure that if functionnalities are added to AJP13 in the future, current implementations will still works.
    • Clean handling of 'Unknown packets'
    • Extended env vars passed from web-server to servlet engine.
    • Add extra SSL informations needed by Servlet 2.3 API (like SSL_KEY_SIZE)

    1. WEB-SERVER send LOGIN INIT CMD + NEGOCIATION DATA + WEB SERVER INFO
    2. TOMCAT respond with LOGIN SEED CMD + RANDOM DATA
    3. WEB-SERVER calculted the MD5 of RANDOM DATA+SECRET DATA
    4. WEB-SERVER send LOGIN COMP CMD + MD5 (SECRET DATA + RANDOM DATA)
    5. TOMCAT respond with LOGIN STATUS CMD + NEGOCIED DATA + SERVLET ENGINE INFO
    To prevent DOS attack, the servlet engine will wait the LOGIN CMD only 15/30 seconds and reports the timeout exception for admins investigation. The login command will contains basic protocol negociation information like compressing ability, crypto, context info (at start up), context update at run-time (up/down), level of SSL env vars, AJP protocol level supported (level1/level2/level3...) The Web server info will contain web server info and connector name (ie Apache 1.3.26 + mod_ssl 2.8.8 + mod_jk 1.2.41 + mod_perl 1.25). The servlet engine will mask the negociation mask with it's own mask (what it can do) and return it when loggin is accepted. This will help having a basic AJP13 implementation (level 1) on a web-server working with a more advanced protocol handler on the servlet engine side or vice-versa. AJP13 was designed to be small and fast and so many SSL informations present in the web-server are not forwarded to the servlet engine. We add here four negociations flags to provide more informations on client SSL data (certs), server SSL datas, crypto used, and misc datas (timeout...).

    +----------------+------------------+-----------------+ | LOGIN INIT CMD | NEGOCIATION DATA | WEB SERVER INFO | +----------------+------------------+-----------------+ +----------------+----------------+ | LOGIN SEED CMD | MD5 of entropy | +----------------+----------------+ +----------------+----------------------------+ | LOGIN COMP CMD | MD5 of RANDOM + SECRET KEY | +----------------+----------------------------+ +-----------+---------------+---------------------+ | LOGOK CMD | NEGOCIED DATA | SERVLET ENGINE INFO | +-----------+---------------+---------------------+ +------------+--------------+ | LOGNOK CMD | FAILURE CODE | +------------+--------------+

    • LOGIN INIT CMD, LOGIN SEED CMD, LOGIN COMP CMD, LOGOK CMD, LOGNOK CMD are 1 byte long.
    • MD5, MD5 of RANDOM + SECRET KEY are 32 chars long.
    • NEGOCIATION DATA, NEGOCIED DATA, FAILURE CODE are 32 bits long.
    • WEB SERVER INFO, SERVLET ENGINE INFO are CString.
    The secret key will be set by a new propertie in workers.properties : secretkey worker.ajp13.port=8009 worker.ajp13.host=localhost worker.ajp13.type=ajp13 worker.ajp13.secretkey=myverysecretkey

    AJP13 miss a functionnality of AJP12, which is shutdown command. A logout will tell servlet engine to shutdown itself. +--------------+----------------------------+ | SHUTDOWN CMD | MD5 of RANDOM + SECRET KEY | +--------------+----------------------------+ +------------+ | SHUTOK CMD | +------------+ +-------------+--------------+ | SHUTNOK CMD | FAILURE CODE | +-------------+--------------+

    • SHUTDOWN CMD, SHUTOK CMD, SHUTNOK CMD are 1 byte long.
    • MD5 of RANDOM + SECRET KEY are 32 chars long.
    • FAILURE CODE is 32 bits long.

    NOTA: While working on AJP13 in JK, I really discovered "JkEnvVar". The following "Extended Env Vars feature" description may not be implemented in extended AJP13 since allready available in original implementation. DESC: Many users will want to see some of their web-server env vars passed to their servlet engine. To reduce the network traffic, the web-servlet will send a table to describing the external vars in a shorter fashion. We'll use there a functionnality allready present in AJP13, attributes list : In the AJP13, we've got : AJP13_FORWARD_REQUEST := prefix_code 2 method (byte) protocol (string) req_uri (string) remote_addr (string) remote_host (string) server_name (string) server_port (integer) is_ssl (boolean) num_headers (integer) request_headers *(req_header_name req_header_value) ?context (byte string) ?servlet_path (byte string) ?remote_user (byte string) ?auth_type (byte string) ?query_string (byte string) ?route (byte string) ?ssl_cert (byte string) ?ssl_cipher (byte string) ?ssl_session (byte string) ?attributes *(attribute_name attribute_value) request_terminator (byte) Using short 'web server attribute name' will reduce the network traffic. +-------------------+---------------------------+-------------------------------+----+ | EXTENDED VARS CMD | WEB SERVER ATTRIBUTE NAME | SERVLET ENGINE ATTRIBUTE NAME | ES | +-------------------+---------------------------+-------------------------------+----+ ie : JkExtVars S1 SSL_CLIENT_V_START javax.servlet.request.ssl_start_cert_date JkExtVars S2 SSL_CLIENT_V_END javax.servlet.request.ssl_end_cert_date JkExtVars S3 SSL_SESSION_ID javax.servlet.request.ssl_session_id +-------------------+----+-------------------------------------------+ | EXTENDED VARS CMD | S1 | javax.servlet.request.ssl_start_cert_date | +-------------------+----+-------------------------------------------+ +----+-----------------------------------------+ | S2 | javax.servlet.request.ssl_end_cert_date | +----+-----------------------------------------+ +----+-----------------------------------------+ | S3 | javax.servlet.request.ssl_end_cert_date | +----+-----------------------------------------+ During transmission in extended AJP13 we'll see attributes name containing S1, S2, S3 and attributes values of 2001/01/03, 2002/01/03, 0123AFE56. This example showed the use of extended SSL vars but any 'personnal' web-server vars like custom authentification vars could be reused in the servlet engine. The cost will be only some more bytes in the AJP traffic.

    • EXTENDED VARS CMD is 1 byte long.
    • WEB SERVER ATTRIBUTE NAME, SERVLET ENGINE ATTRIBUTE NAME are CString.
    • ES is an empty CString.

    Just after the LOGON PHASE, the web server will ask for the list of contexts and URLs/URIs handled by the servlet engine. It will ease installation in many sites, reduce questions about configuration on tomcat-user list, and be ready for servlet API 2.3. This mode will be activated by a new directive JkAutoMount ie: JkAutoMount examples myworker1 /examples/ If we want to get ALL the contexts handled by the servlet engine, willcard could be used : ie: JkAutoMount * myworker1 * A servlet engine could have many contexts, /examples, /admin, /test. We may want to use only some contexts for a given worker. It was done previously, in apache HTTP server for example, by setting by hand the JkMount accordingly in each [virtual] area of Apache. If you web-server support virtual hosting, we'll forward also that information to servlet engine which will only return contexts for that virtual host. In that case the servlet engine will only return the URL/URI matching these particular virtual server (defined in server.xml). This feature will help ISP and big sites which mutualize large farm of Tomcat in load-balancing configuration. +-----------------+-------------------+----------+----------+----+ | CONTEXT QRY CMD | VIRTUAL HOST NAME | CONTEXTA | CONTEXTB | ES | +-----------------+-------------------+----------+----------+----+ +------------------+-------------------+----------+-------------------+----------+---------------+----+ | CONTEXT INFO CMD | VIRTUAL HOST NAME | CONTEXTA | URL1 URL2 URL3 ES | CONTEXTB | URL1 URL2 ... | ES | +------------------+-------------------+----------+-------------------+----------+---------------+----+ We'll discover via context-query, the list of URL/MIMES handled by the remove servlet engine for a list of contextes. In wildcard mode, CONTEXTA will contains just '*'.

    • CONTEXT QRY CMD and CONTEXT INFO CMD are 1 byte long.
    • VIRTUAL HOST NAME is a CString, ie an array of chars terminated by a null byte (/0).
    • An empty string is just a null byte (/0).
    • ES is an empty CString. Indicate end of URI/URLs or end of CONTEXTs.
    NB:
    When VirtualMode is not to be used, the VIRTUAL HOST NAME is '*'. In that case the servlet engine will send all contexts handled.

    Context update are messages caming from the servlet engine each time a context is desactivated/reactivated. The update will be in use when the directive JkUpdateMount. This directive will set the AJP13_CONTEXT_UPDATE_NEG flag. ie: JkUpdateMount myworker1 +--------------------+-------------------+----------+--------+----------+--------+----+ | CONTEXT UPDATE CMD | VIRTUAL HOST NAME | CONTEXTA | STATUS | CONTEXTB | STATUS | ES | +--------------------+-------------------+----------+--------+----------+--------+----+

    • CONTEXT UPDATE CMD, STATUS are 1 byte long.
    • VIRTUAL HOST NAME, CONTEXTS are CString.
    • ES is an empty CString. Indicate end of CONTEXTs.
    NB:
    When VirtualMode is not in use, the VIRTUAL HOST NAME is '*'. STATUS is one byte indicating if context is UP/DOWN/INVALID

    This query will be used by the web-server to determine if a given contexts are UP, DOWN or INVALID (and should be removed). +-------------------+--------------------+----------+----------+----+ | CONTEXT STATE CMD | VIRTUAL HOST NAME | CONTEXTA | CONTEXTB | ES | +-------------------+--------------------+----------+----------+----+ +-------------------------+-------------------+----------+--------+----------+--------+----+ | CONTEXT STATE REPLY CMD | VIRTUAL HOST NAME | CONTEXTA | STATUS | CONTEXTB | STATUS | ES | +-------------------------+-------------------+----------+-------------------+--------+----+

    • CONTEXT STATE CMD, CONTEXT STATE REPLY CMD, STATUS are 1 byte long.
    • VIRTUAL HOST NAME, CONTEXTs are CString
    • ES is an empty CString
    NB:
    When VirtualMode is not in use, the VIRTUAL HOST NAME is an empty string.

    Sometimes even with a well negocied protocol, we may be in a situation where one end (web server or servlet engine), will receive a message it couldn't understand. In that case the receiver will send an 'UNKNOW PACKET CMD' with attached the unhandled message. +--------------------+------------------------+-------------------+ | UNKNOWN PACKET CMD | UNHANDLED MESSAGE SIZE | UNHANDLED MESSAGE | +--------------------+------------------------+-------------------+ Depending on the message, the sender will report an error and if possible will try to forward the message to another endpoint.

    • UNKNOWN PACKET CMD is 1 byte long.
    • UNHANDLED MESSAGE SIZE is 16bits long.
    • UNHANDLED MESSAGE is an array of byte (length is contained in UNHANDLED MESSAGE SIZE)
    NB:
    added UNHANDLED MESSAGE SIZE (development)

    NOTA: This fonctionality may never be used, since it may slow up the normal process since requiring on the web-server side an extra IO (read) before forwarding the request..... One of the beauty of socket APIs, is that you could write on a half closed socket. When servlet engine close the socket, the web server will discover it only at the next read() to the socket. Basically, in the AJP13 protocol, the web server send the HTTP HEADER and HTTP BODY (POST by chunk of 8K) to the servlet engine and then try to receive the reply. If the connection was broken the web server will learn it only at receive time. We could use a buffering scheme but what happen when you use the servlet engine for upload operations with more than 8ko of datas ? The hack in the AJP13 protocol is to add some bytes to read after the end of the service : EXAMPLE OF DISCUSSION BETWEEN WEB SERVER AND SERVLET ENGINE AJP HTTP-HEADER (+ HTTP-POST) (WEB->SERVLET) AJP HTTP-REPLY (SERVLET->WEB) AJP END OF DISCUSSION (SERVLET->WEB) ---> AJP STATUS (SERVLET->WEB AJP13) The AJP STATUS will not be read by the servlet engine at the end of the request/response #N but at the begining of the next session. More at that time the web server could also use OS dependants functions (or better APR functions) to determine if there is also more data to read. And that datas could be CONTEXT Updates. This will avoid the web server sending a request to a desactivated context. In that case, if the load-balancing is used, it will search for another servlet engine to handle the request. And that feature will help ISP and big sites with farm of tomcat, to updates their servlet engine without any service interruption. +------------+-------------+ | STATUS CMD | STATUS DATA | +------------+-------------+

    • STATUS CMD and STATUS DATA are one byte long.

    The goal of the extended AJP13 protocol is to overcome some of the original AJP13 limitation. An easier configuration, a better support for large site and farm of Tomcat, a simple authentification system and provision for protocol updates. Using the stable ajp13 implementation in JK (native) and in servlet engine (java), it's a reasonable evolution of the well known ajp13.

    Index of Commands and ID to be added in AJP13 Protocol

    Command NameCommand Number
    AJP13_LOGINIT_CMD0x10
    AJP13_LOGSEED_CMD0x11
    AJP13_LOGCOMP_CMD0x12
    AJP13_LOGOK_CMD0x13
    AJP13_LOGNOK_CMD0x14
    AJP13_CONTEXT_QRY_CMD0x15
    AJP13_CONTEXT_INFO_CMD0x16
    AJP13_CONTEXT_UPDATE_CMD0x17
    AJP13_STATUS_CMD0x18
    AJP13_SHUTDOWN_CMD0x19
    AJP13_SHUTOK_CMD0x1A
    AJP13_SHUTNOK_CMD0x1B
    AJP13_CONTEXT_STATE_CMD0x1C
    AJP13_CONTEXT_STATE_REP_CMD0x1D
    AJP13_UNKNOW_PACKET_CMD0x1E

    Command NameNumberDescription
    AJP13_CONTEXT_INFO_NEG0x80000000web-server want context info after login
    AJP13_CONTEXT_UPDATE_NEG0x40000000web-server want context updates
    AJP13_GZIP_STREAM_NEG0x20000000web-server want compressed stream
    AJP13_DES56_STREAM_NEG0x10000000web-server want crypted DES56 stream with secret key
    AJP13_SSL_VSERVER_NEG0x08000000Extended info on server SSL vars
    AJP13_SSL_VCLIENT_NEG0x04000000Extended info on client SSL vars
    AJP13_SSL_VCRYPTO_NEG0x02000000Extended info on crypto SSL vars
    AJP13_SSL_VMISC_NEG0x01000000Extended info on misc SSL vars

    Negociation IDNumberDescription
    AJP13_PROTO_SUPPORT_AJPXX_NEG0x00FF0000mask of protocol supported
    AJP13_PROTO_SUPPORT_AJP13L1_NEG0x00010000communication could use AJP13 Level 1
    AJP13_PROTO_SUPPORT_AJP13L2_NEG0x00020000communication could use AJP13 Level 2
    AJP13_PROTO_SUPPORT_AJP13L3_NEG0x00040000communication could use AJP13 Level 3

    All others flags must be set to 0 since they are reserved for future use.

    Failure IdNumber
    AJP13_BAD_KEY_ERR0xFFFFFFFF
    AJP13_ENGINE_DOWN_ERR0xFFFFFFFE
    AJP13_RETRY_LATER_ERR0xFFFFFFFD
    AJP13_SHUT_AUTHOR_FAILED_ERR0xFFFFFFFC

    Failure IdNumber
    AJP13_CONTEXT_DOWN0x01
    AJP13_CONTEXT_UP0x02
    AJP13_CONTEXT_OK0x03

    tomcat-connectors-1.2.41-src/xdocs/ajp/ajpv13a.xml0000644000000000000020000005661212451477327020222 0ustar rootbin ]> &project; Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. AJPv13 danmil@shore.net Jean-Frederic Clere $Date: 2015-01-02 11:19:51 +0000 (Fri, 02 Jan 2015) $

    The original document was written by Dan Milstein, danmil@shore.net on December 2000. The present document is generated out of an xml file to allow a more easy integration in the Tomcat documentation.

    This describes the Apache JServ Protocol version 1.3 (hereafter ajp13). There is, apparently, no current documentation of how the protocol works. This document is an attempt to remedy that, in order to make life easier for maintainers of JK, and for anyone who wants to port the protocol somewhere (into jakarta 4.x, for example).

    I am not one of the designers of this protocol -- I believe that Gal Shachor was the original designer. Everything in this document is derived from the actual implementation I found in the tomcat 3.x code. I hope it is useful, but I can't make any grand claims to perfect accuracy. I also don't know why certain design decisions were made. Where I was able, I've offered some possible justifications for certain choices, but those are only my guesses. In general, the C code which Shachor wrote is very clean and comprehensible (if almost totally undocumented). I've cleaned up the Java code, and I think it's reasonably readable.

    According to email from Gal Shachor to the jakarta-dev mailing list, the original goals of JK (and thus ajp13) were to extend mod_jserv and ajp12 by (I am only including the goals which relate to communication between the web server and the servlet container):

    • Increasing performance (speed, specifically).
    • Adding support for SSL, so that isSecure() and getScheme() will function correctly within the servlet container. The client certificates and cipher suite will be available to servlets as request attributes.

    The ajp13 protocol is packet-oriented. A binary format was presumably chosen over the more readable plain text for reasons of performance. The web server communicates with the servlet container over TCP connections. To cut down on the expensive process of socket creation, the web server will attempt to maintain persistent TCP connections to the servlet container, and to reuse a connection for multiple request/response cycles.

    Once a connection is assigned to a particular request, it will not be used for any others until the request-handling cycle has terminated. In other words, requests are not multiplexed over connections. This makes for much simpler code at either end of the connection, although it does cause more connections to be open at once.

    Once the web server has opened a connection to the servlet container, the connection can be in one of the following states:

    • Idle
      No request is being handled over this connection.
    • Assigned
      The connecton is handling a specific request.

    Once a connection is assigned to handle a particular request, the basic request informaton (e.g. HTTP headers, etc) is sent over the connection in a highly condensed form (e.g. common strings are encoded as integers). Details of that format are below in Request Packet Structure. If there is a body to the request (content-length > 0), that is sent in a separate packet immediately after.

    At this point, the servlet container is presumably ready to start processing the request. As it does so, it can send the following messages back to the web server:

    • SEND_HEADERS
      Send a set of headers back to the browser.
    • SEND_BODY_CHUNK
      Send a chunk of body data back to the browser.
    • GET_BODY_CHUNK
      Get further data from the request if it hasn't all been transferred yet. This is necessary because the packets have a fixed maximum size and arbitrary amounts of data can be included the body of a request (for uploaded files, for example). (Note: this is unrelated to HTTP chunked tranfer).
    • END_RESPONSE
      Finish the request-handling cycle.

    Each message is accompanied by a differently formatted packet of data. See Response Packet Structures below for details.

    There is a bit of an XDR heritage to this protocol, but it differs in lots of ways (no 4 byte alignment, for example).

    AJP13 uses network byte order for all data types.

    There are four data types in the protocol: bytes, booleans, integers and strings.

    Byte
    A single byte.
    Boolean
    A single byte, 1 = true, 0 = false. Using other non-zero values as true (i.e. C-style) may work in some places, but it won't in others.
    Integer
    A number in the range of 0 to 2^16 (32768). Stored in 2 bytes with the high-order byte first.
    String
    A variable-sized string (length bounded by 2^16). Encoded with the length packed into two bytes first, followed by the string (including the terminating '\0'). Note that the encoded length does not include the trailing '\0' -- it is like strlen. This is a touch confusing on the Java side, which is littered with odd autoincrement statements to skip over these terminators. I believe the reason this was done was to allow the C code to be extra efficient when reading strings which the servlet container is sending back -- with the terminating \0 character, the C code can pass around references into a single buffer, without copying. If the \0 was missing, the C code would have to copy things out in order to get its notion of a string. Note a size of -1 (65535) indicates a null string and no data follow the length in this case.

    According to much of the code, the max packet size is 8 * 1024 bytes (8K). The actual length of the packet is encoded in the header.

    Packets sent from the server to the container begin with 0x1234. Packets sent from the container to the server begin with AB (that's the ASCII code for A followed by the ASCII code for B). After those first two bytes, there is an integer (encoded as above) with the length of the payload. Although this might suggest that the maximum payload could be as large as 2^16, in fact, the code sets the maximum to be 8K.
    Packet Format (Server->Container)
    Byte 0 1 2 3 4...(n+3)
    Contents 0x12 0x34 Data Length (n) Data
    Packet Format (Container->Server)
    Byte 0 1 2 3 4...(n+3)
    Contents A B Data Length (n) Data

    For most packets, the first byte of the payload encodes the type of message. The exception is for request body packets sent from the server to the container -- they are sent with a standard packet header (0x1234 and then length of the packet), but without any prefix code after that (this seems like a mistake to me).

    The web server can send the following messages to the servlet container:
    Code Type of Packet Meaning
    2 Forward Request Begin the request-processing cycle with the following data
    7 Shutdown The web server asks the container to shut itself down.
    8 Ping The web server asks the container to take control (secure login phase).
    10 CPing The web server asks the container to respond quickly with a CPong.
    none Data Size (2 bytes) and corresponding body data.

    To ensure some basic security, the container will only actually do the Shutdown if the request comes from the same machine on which it's hosted.

    The first Data packet is send immediatly after the Forward Request by the web server.

    The servlet container can send the following types of messages to the web server:
    Code Type of Packet Meaning
    3 Send Body Chunk Send a chunk of the body from the servlet container to the web server (and presumably, onto the browser).
    4 Send Headers Send the response headers from the servlet container to the web server (and presumably, onto the browser).
    5 End Response Marks the end of the response (and thus the request-handling cycle).
    6 Get Body Chunk Get further data from the request if it hasn't all been transferred yet.
    9 CPong Reply The reply to a CPing request

    Each of the above messages has a different internal structure, detailed below.

    For messages from the server to the container of type "Forward Request":

    AJP13_FORWARD_REQUEST := prefix_code (byte) 0x02 = JK_AJP13_FORWARD_REQUEST method (byte) protocol (string) req_uri (string) remote_addr (string) remote_host (string) server_name (string) server_port (integer) is_ssl (boolean) num_headers (integer) request_headers *(req_header_name req_header_value) attributes *(attribut_name attribute_value) request_terminator (byte) OxFF

    The request_headers have the following structure:

    req_header_name := sc_req_header_name | (string) [see below for how this is parsed] sc_req_header_name := 0xA0xx (integer) req_header_value := (string)

    The attributes are optional and have the following structure:

    attribute_name := sc_a_name | (sc_a_req_attribute string) attribute_value := (string)

    Not that the all-important header is "content-length', because it determines whether or not the container looks for another packet immediately.

    Detailed description of the elements of Forward Request.

    For all requests, this will be 2. See above for details on other prefix codes.

    The HTTP method, encoded as a single byte:

    Command NameCode
    OPTIONS1
    GET2
    HEAD3
    POST4
    PUT5
    DELETE6
    TRACE7
    PROPFIND8
    PROPPATCH9
    MKCOL10
    COPY11
    MOVE12
    LOCK13
    UNLOCK14
    ACL15
    REPORT16
    VERSION-CONTROL17
    CHECKIN18
    CHECKOUT19
    UNCHECKOUT20
    SEARCH21
    MKWORKSPACE22
    UPDATE23
    LABEL24
    MERGE25
    BASELINE_CONTROL26
    MKACTIVITY27

    Later version of ajp13, when used with mod_jk2, will transport additional methods, even if they are not in this list.

    These are all fairly self-explanatory. Each of these is required, and will be sent for every request.

    The structure of request_headers is the following: First, the number of headers num_headers is encoded. Then, a series of header name req_header_name / value req_header_value pairs follows. Common header names are encoded as integers, to save space. If the header name is not in the list of basic headers, it is encoded normally (as a string, with prefixed length). The list of common headers sc_req_header_nameand their codes is as follows (all are case-sensitive):

    NameCode valueCode name
    accept0xA001SC_REQ_ACCEPT
    accept-charset0xA002SC_REQ_ACCEPT_CHARSET
    accept-encoding0xA003SC_REQ_ACCEPT_ENCODING
    accept-language0xA004SC_REQ_ACCEPT_LANGUAGE
    authorization0xA005SC_REQ_AUTHORIZATION
    connection0xA006SC_REQ_CONNECTION
    content-type0xA007SC_REQ_CONTENT_TYPE
    content-length0xA008SC_REQ_CONTENT_LENGTH
    cookie0xA009SC_REQ_COOKIE
    cookie20xA00ASC_REQ_COOKIE2
    host0xA00BSC_REQ_HOST
    pragma0xA00CSC_REQ_PRAGMA
    referer0xA00DSC_REQ_REFERER
    user-agent0xA00ESC_REQ_USER_AGENT

    The Java code that reads this grabs the first two-byte integer and if it sees an '0xA0' in the most significant byte, it uses the integer in the second byte as an index into an array of header names. If the first byte is not '0xA0', it assumes that the two-byte integer is the length of a string, which is then read in.

    This works on the assumption that no header names will have length greater than 0x9FFF (==0xA000 - 1), which is perfectly reasonable, though somewhat arbitrary. (If you, like me, started to think about the cookie spec here, and about how long headers can get, fear not -- this limit is on header names not header values. It seems unlikely that unmanageably huge header names will be showing up in the HTTP spec any time soon).

    Note: The content-length header is extremely important. If it is present and non-zero, the container assumes that the request has a body (a POST request, for example), and immediately reads a separate packet off the input stream to get that body.

    The attributes prefixed with a ? (e.g. ?context) are all optional. For each, there is a single byte code to indicate the type of attribute, and then a string to give its value. They can be sent in any order (though the C code always sends them in the order listed below). A special terminating code is sent to signal the end of the list of optional attributes. The list of byte codes is:

    InformationCode ValueNote
    ?context0x01Not currently implemented
    ?servlet_path0x02Not currently implemented
    ?remote_user0x03
    ?auth_type0x04
    ?query_string0x05
    ?route0x06
    ?ssl_cert0x07
    ?ssl_cipher0x08
    ?ssl_session0x09
    ?req_attribute0x0AName (the name of the attribut follows)
    ?ssl_key_size0x0B
    ?secret0x0C
    ?stored_method0x0D
    are_done0xFFrequest_terminator

    The context and servlet_path are not currently set by the C code, and most of the Java code completely ignores whatever is sent over for those fields (and some of it will actually break if a string is sent along after one of those codes). I don't know if this is a bug or an unimplemented feature or just vestigial code, but it's missing from both sides of the connection.

    The remote_user and auth_type presumably refer to HTTP-level authentication, and communicate the remote user's username and the type of authentication used to establish their identity (e.g. Basic, Digest). I'm not clear on why the password isn't also sent, but I don't know HTTP authentication inside and out.

    The query_string, ssl_cert, ssl_cipher, and ssl_session refer to the corresponding pieces of HTTP and HTTPS.

    The route, as I understand it, is used to support sticky sessions -- associating a user's session with a particular Tomcat instance in the presence of multiple, load-balancing servers. I don't know the details.

    Beyond this list of basic attributes, any number of other attributes can be sent via the req_attribute code (0x0A). A pair of strings to represent the attribute name and value are sent immediately after each instance of that code. Environment values are passed in via this method.

    Finally, after all the attributes have been sent, the attribute terminator, 0xFF, is sent. This signals both the end of the list of attributes and also then end of the Request Packet.

    For messages which the container can send back to the server. AJP13_SEND_BODY_CHUNK := prefix_code 3 chunk_length (integer) chunk *(byte) AJP13_SEND_HEADERS := prefix_code 4 http_status_code (integer) http_status_msg (string) num_headers (integer) response_headers *(res_header_name header_value) res_header_name := sc_res_header_name | (string) [see below for how this is parsed] sc_res_header_name := 0xA0 (byte) header_value := (string) AJP13_END_RESPONSE := prefix_code 5 reuse (boolean) AJP13_GET_BODY_CHUNK := prefix_code 6 requested_length (integer)

    Details:

    The chunk is basically binary data, and is sent directly back to the browser.

    The status code and message are the usual HTTP things (e.g. "200" and "OK"). The response header names are encoded the same way the request header names are. See above for details about how the the codes are distinguished from the strings. The codes for common headers are:

    NameCode value
    Content-Type0xA001
    Content-Language0xA002
    Content-Length0xA003
    Date0xA004
    Last-Modified0xA005
    Location0xA006
    Set-Cookie0xA007
    Set-Cookie20xA008
    Servlet-Engine0xA009
    Status0xA00A
    WWW-Authenticate0xA00B

    After the code or the string header name, the header value is immediately encoded.

    Signals the end of this request-handling cycle. If the reuse flag is true (anything other than 0 in the actual C code), this TCP connection can now be used to handle new incoming requests. If reuse is false (==0), the connection should be closed.

    The container asks for more data from the request (If the body was too large to fit in the first packet sent over or when the request is chuncked). The server will send a body packet back with an amount of data which is the minimum of the request_length, the maximum send body size (8186 (8 Kbytes - 6)), and the number of bytes actually left to send from the request body.
    If there is no more data in the body (i.e. the servlet container is trying to read past the end of the body), the server will send back an "empty" packet, which is a body packet with a payload length of 0. (0x12,0x34,0x00,0x00)

    What happens if the request headers > max packet size? There is no provision to send a second packet of request headers in case there are more than 8K (I think this is correctly handled for response headers, though I'm not certain). I don't know if there is a way to get more than 8K worth of data into that initial set of request headers, but I'll bet there is (combine long cookies with long ssl information and a lot of environment variables, and you should hit 8K easily). I think the connector would just fail before trying to send any headers in this case, but I'm not certain.

    What about authentication? There doesn't seem to be any authentication of the connection between the web server and the container. This strikes me as potentially dangerous.

    tomcat-connectors-1.2.41-src/xdocs/reference/0000755000000000000020000000000012555256551017404 5ustar rootbintomcat-connectors-1.2.41-src/xdocs/reference/workers.xml0000644000000000000020000014641512472575314021634 0ustar rootbin ]> &project; Mladen Turk workers.properties configuration

    A Tomcat worker is a Tomcat instance that is waiting to execute servlets or any other content on behalf of some web server. For example, we can have a web server such as Apache forwarding servlet requests to a Tomcat process (the worker) running behind it.

    The scenario described above is a very simple one; in fact one can configure multiple Tomcat workers to serve servlets on behalf of a certain web server. The reasons for such configuration can be:

    • We want different contexts to be served by different Tomcat workers to provide a development environment where all the developers share the same web server but own a Tomcat worker of their own.
    • We want different virtual hosts served by different Tomcat processes to provide a clear separation between sites belonging to different companies.
    • We want to provide load balancing, meaning run multiple Tomcat workers each on a machine of its own and distribute the requests between them.

    There are probably more reasons for having multiple workers but I guess that this list is enough...

    Tomcat workers are defined in a properties file dubbed workers.properties and this tutorial explains how to work with it.


    Defining workers to the Tomcat web server plugin can be done using a properties file (a sample file named workers.properties is available in the conf/ directory).


    The lines in the file define properties. The general format is

    <name>=<value>

    Dots are used as part of the name to represent a configuration hierarchy.

    Invalid directives will be logged during web server startup and prevent the web server from working properly. Some directives have been deprecated. Although they will still work, you should replace them by their successors.

    Some directives are allowed multiple times. This will be explicitly noted in the tables below.

    Whitespace at the beginning and the end of a property name or value gets ignored. Comments can be placed in any line and start with a hash sign '#'. Any line contents behind the hash sign get ignored.

    Boolean properties can be set either using the numbers 0 (false) and 1 (true) as values, or off (false) and on (true) or any other string starting with the letters f (false), n (false), t (true) or y (true). The values are taken case insensitive. In this documentation we will stick to false and true.


    These directives have global scope.

    A comma separated list of workers names that the JK will use. When starting up, the web server plugin will instantiate the workers whose name appears in the worker.list property, these are also the workers to whom you can map requests.

    This directive can be used multiple times.

    Worker connection pool maintain interval in seconds. If set to the positive value JK will scan all connections for all workers specified in worker.list directive and check if connections needs to be recycled.

    Furthermore any load balancer does a global maintenance every worker.maintain seconds. During global maintenance load counters are decayed and workers in error are checked for recover_time.

    This feature has been added in jk 1.2.13.


    Each worker configuration directive consists of three words separated by a dot:

    worker.<worker name>.<directive>=<value>

    The first word is always worker. The second word is the worker name you can choose. In the case of load-balancing, the worker name has an additional meaning. Please consult the Load Balancer HowTo.

    The name of the worker can contain only the alphanumeric characters [a-z][A-Z][0-9][_\-] and is case sensitive.

    You can define and use variables in the workers.properties file. To define a variable you use the syntax:

    <variable_name>=<value>

    Dots are allowed in the variable name, but you have to be careful not to use variable names, that clash with standard directives. Therefore variable names should never start with "worker.".

    To use a variable, you can insert "$(variable_name)" at any place on the value side of a property line. If a variable has not been defined before its use, we will search the process environment for a variable with the same name and use their value.


    Often one wants to use the same property values for various workers. To reduce duplication of configuration lines and to ease the maintenance of the file, you can inherit properties from one worker to another, or even from a template to real workers.

    The directive "reference" allows to copy configurations between workers or worker templates in a hierarchical way. If worker castor sets worker.castor.reference=worker.pollux then it inherits all properties of pollux, except for the ones that are explicitly set for castor.

    Please note, that the value of the directive is not only the name of the referred worker, but the complete prefix including "worker.".

    To use a template worker simply define it like a real worker, but do not add it to the "worker.list" or as a member to any load balancer. Such a template worker does not have to contain mandatory directives. This approach is especially useful, if one has a lot of balanced workers in a load balancer and these workers share most of their properties. You can set all of these properties in a template worker, e.g. using the prefix "worker.template1", and then simply reference those common properties in all balanced workers.

    References can be used to inherit properties over multiple hops in a hierarchical way. The maximum depth for nesting references is 20. Be careful not to introduce a reference loop!

    This feature has been added in jk 1.2.19.



    Mandatory directives are the one that each worker must contain. Without them the worker will be unavailable or will misbehave. Those directives will be marked with a strong font in the following tables.

    Type of the worker (can be one of ajp13, ajp14, jni, lb or status). The type of the worker defines the directives that can be applied to the worker.

    Type ajp13 is the preferred worker type that JK uses for communication between web server and Tomcat. This type of worker uses sockets as communication channel. For detailed description of the AJP13 protocol stack browse to AJPv13 protocol specification

    Type ajp14 is experimental and not recommended.

    JNI workers have been deprecated. They will likely not work. Do not use them.

    Connection directives defines the parameters needed to connect and maintain the connections pool of persistent connections between JK and remote Tomcat.

    Host name or IP address of the backend Tomcat instance. The remote Tomcat must support the AJP13 protocol stack. The host name can have a port number embedded separated by the colon (':') character. Port number of the remote Tomcat instance listening for defined protocol requests. The default value depends on the worker type. For ajp13 workers the default port is 8009, while for ajp14 type of worker that value is 8011. Name or IP address used for the connection source (outgoing address). It should only be used on multi-homed hosts.

    This feature is experimental and has been added in jk 1.2.41.

    Socket timeout in seconds used for the communication channel between JK and remote host. If the remote host does not respond inside the timeout specified, JK will generate an error, and retry again. If set to zero (default) JK will wait for an infinite amount of time on all socket operations. Socket connect timeout in milliseconds used for the communication channel between JK and remote host. If the remote host does not respond inside the timeout specified, JK will generate an error, and retry again.

    Note that socket_timeout is in seconds, and socket_connect_timeout in milliseconds, so in absolute terms the default socket_connect_timeout is equal to "socket_timeout.

    This feature has been added in jk 1.2.27.

    This directive should be used when you have a firewall between your webserver and the Tomcat engine, who tend to drop inactive connections. This flag will tell the Operating System to send KEEP_ALIVE messages on inactive connections (interval depend on global OS settings, generally 120 minutes), and thus prevent the firewall to cut inactive connections. To enable keepalive set this property value to true.

    The problem with Firewall cutting inactive connections is that sometimes, neither webserver or Tomcat have information about the cut and couldn't handle it.

    This flag determines, under which conditions established connections are probed to ensure they are still working. The probe is done with an empty AJP13 packet (CPing) and expects to receive an appropriate answer (CPong) within some timeout.

    The value of the flag can be any combination of the following flags (multiple values are combined without any separators):

    C (connect): If set, the connection will be probed once after connecting to the backend. The timeout can be set by connect_timeout. If it is not set, the value of ping_timeout will be used instead.

    P (prepost): If set, the connection will be probed before sending each request to the backend. The timeout can be set by prepost_timeout. If it is not set, the value of ping_timeout will be used instead.

    I (interval): If set, the connection will be probed during the regular internal maintenance cycle, but only if it is idle longer than connection_ping_interval. The timeout can be set by ping_timeout.

    A If set, all of the above probes will be used.

    This feature has been added in jk 1.2.27. Connect and prepost probing were already available via connect_timeout and prepost_timeout since version jk 1.2.6.

    Timeout in milliseconds used when waiting for the CPong answer of a CPing connection probe. The activation of the probes is done via ping_mode. The timeouts for ping_mode connect and prepost can be overwritten individually via connect_timeout and prepost_timeout.

    For compatibility reasons, CPing/CPong is also used, whenever connect_timeout or prepost_timeout are set, even if ping_mode is empty.

    This feature has been added in jk 1.2.27.

    The usage depend on the ping_mode flags used. directive connection_ping_interval was not set, the value of (ping_timeout/1000) * 10 will be used as connection_ping_interval value. When using interval connection probing, connections idle for longer than this interval in seconds are probed by CPing packets whether they still work.

    Interval probing can be activated either by ping_mode, or by setting connection_ping_interval to some value bigger than zero. If you activate interval probing via ping_mode, then the default value of connection_ping_interval is (ping_timeout/1000) * 10. Note that ping_timeout is in milliseconds, and connection_ping_interval in seconds, so in absolute terms the default connection_ping_interval is 10 times ping_timeout.

    This feature has been added in jk 1.2.27.

    This defines the number of connections made to the AJP backend that are maintained as a connection pool. It will limit the number of those connection that each web server child process can made.

    Connection pool size property is only used for multi threaded web servers such as Apache, IIS and Netscape/Sun. The connection_pool_size property needs to reflect the number of requests one web server process should be able to send to a backend in parallel. Usually this is the same as the number of threads per web server process. JK will discover this number for the Apache web server automatically and set the pool size to this value. For IIS the default value is 250 (before version 1.2.20: 10), for Netscape/Sun the default value is 1.

    We strongly recommend adjusting this value for IIS and the Netscape/Sun to the number of requests one web server process should be able to send to a backend in parallel. You should measure how many connections you need during peak activity without performance problems, and then add some percentage depending on your growth rate. Finally you should check, whether your web server processes are able to use at least as many threads, as you configured as the pool size.

    Do not use connection_pool_size with values higher then 1 on Apache 2.x prefork or Apache 1.3.x!
    Minimum size of the connection pool that will be maintained.

    Its default value is (connection_pool_size+1)/2.

    Do not use connection_pool_size with values higher then 1 on Apache 2.x prefork or Apache 1.3.x!

    This feature has been added in jk 1.2.16.

    Cache timeout property should be used with connection_pool_minsize to specify how many seconds JK should keep an inactive socket in cache before closing it. This property should be used to reduce the number of threads on the Tomcat web server. The default value zero disables the closing (infinite timeout).

    Each child could open an ajp13 connection if it has to forward a request to Tomcat, creating a new ajp13 thread on Tomcat side.

    The problem is that after an ajp13 connection is created, the child won't drop it until killed. And since the webserver will keep its childs/threads running to handle high-load, even it the child/thread handle only static contents, you could finish having many unused ajp13 threads on the Tomcat side.

    You should keep this time interval in sync with the keepAliveTimeout attribute (if it is set explicitly) or connectionTimeout attribute of your AJP connector in Tomcat's server.xml. Note however, that the value for mod_jk is given in seconds, the one in server.xml has to use milliseconds.

    Timeout the worker will wait for a free socket in cache before giving up.

    Its default value is retries * retry_interval.

    This feature has been added in jk 1.2.27.

    Only used for a member worker of a load balancer.

    The integer number lbfactor (load-balancing factor) is how much we expect this worker to work, or the worker's work quota. Load balancing factor is compared with other workers that makes the load balancer. For example if one worker has lb_factor 5 times higher then other worker, then it will receive five times more requests.


    Load balancer is a virtual worker that does not really communicate with Tomcat workers. Instead it is responsible for the management of several "real" workers. The worker is supposed to be a load balancer if it's worker type is lb. See worker's type directive.

    Loadbalancer directives define the parameters needed to create the workers that are connecting to a remote cluster of backend Tomcat servers. Each cluster node has to have a worker defined.

    Load balancer management includes:

    • Instantiating the workers in the web server.
    • Using the worker's load-balancing factor, perform weighed-round-robin load balancing where high lbfactor means stronger machine (that is going to handle more requests)
    • Keeping requests belonging to the same session executing on the same Tomcat worker.
    • Identifying failed Tomcat workers, suspending requests to them and instead fall-backing on other workers managed by the lb worker.

    The overall result is that workers managed by the same lb worker are load-balanced (based on their lbfactor and current user session) and also fall-backed so a single Tomcat process death will not "kill" the entire site.

    If you want to use session stickiness, you must set different jvmRoute attributes in the Engine element in Tomcat's server.xml. Furthermore the names of the workers which are managed by the balancer have to be equal to the jvmRoute of the Tomcat instance they connect with.

    The restriction on the worker names can be lifted, if you use the route attribute for the workers.

    The following table specifies properties that the lb worker can accept:

    A comma separated list of workers that the load balancer need to manage.

    This directive can be used multiple times for the same load balancer.

    This directive replaces old balanced_workers directive and can be used only with mod_jk versions 1.2.7 and up.

    As long as these workers should only be used via the load balancer worker, there is no need to also put them into the worker.list property.
    Specifies whether requests with SESSION ID's should be routed back to the same Tomcat worker. If sticky_session is set to true sessions are sticky, otherwise sticky_session is set to false. Set sticky_session to false when Tomcat is using a Session Manager which can persist session data across multiple instances of Tomcat.

    The sticky_session setting can be overwritten using the Apache httpd environment variable JK_STICKY_IGNORE and the worker map extension for sticky_ignore. This has been added in version 1.2.33.

    Specifies whether requests with SESSION ID's for workers that are in error state should be rejected. If sticky_session_force is set to true and the worker that matches that SESSION ID is in error state, client will receive 500 (Server Error). If set to false failover on another worker will be issued with losing client session. This directive is used only when you set sticky_session=true.

    This feature has been added in jk 1.2.9.

    Specifies what method load balancer is using for electing the best worker. Please note, that session stickiness and perfect load balancing are conflicting targets, especially when the number of sessions is small, or the usage of sessions is extremely varying For huge numbers of sessions this usually is not a problem.

    Some methods note, that they aggregate in a sliding time window. They add up accesses, and on each run of the global maintain method, the load counters get divided by 2. Usually this happens once a minute, depending on the setting of worker.maintain. The value of the load counters can be inspected using the status worker.

    If method is set to R[equest] the balancer will use the number of requests to find the best worker. Accesses will be distributed according to the lbfactor in a sliding time window. This is the default value and should be working well for most applications.

    If method is set to S[ession] the balancer will use the number of sessions to find the best worker. Accesses will be distributed according to the lbfactor in a sliding time window. This method should be used, if sessions are your limiting resource, e.g. when you only have limited memory and your sessions need a lot of memory. Because the balancer does not keep any state, it actually does not know the number of sessions. Instead it counts each request without a session cookie or URL encoding as a new session. This method will neither know, when a session is being invalidated, nor will it correct its load numbers according to session timeouts or worker failover. If you know request URLs, that will be called without a session ID but should not be counted as new sessions, you should add them to the stateless mapping rule extension or set the Apache HTTPD environment variable JK_STATELESS for them.

    If method is set to N[ext] the balancer will again use the number of sessions to find the best worker. All remarks concerning the Sessionmethod apply as well. The difference to the Session method is how the session count is handled in the sliding time window. The Next method does not divide by 2, instead it subtracts the current minimum number. This should effectively result in a round-robin session balancing, thus the name Next. Under high load, the two session balancing methods will result in a similar distribution, but Next will be better if you need to distribute small numbers of sessions.

    If set to T[raffic] the balancer will use the network traffic between JK and Tomcat to find the best worker. Accesses will be distributed according to the lbfactor in a sliding time window. This method should be used, if network to and from the backends is your limiting resource.

    If set to B[usyness] the balancer will pick the worker with the lowest current load, based on how many requests the worker is currently serving. This number is divided by the workers lbfactor, and the lowest value (least busy) worker is picked. This method is especially interesting, if your request take a long time to process, like for a download application. The method is not recommended for general use, because under high load on some hardware architectures the busy counter can become wrong.

    This feature has been added in version 1.2.9. The Session method has been added in version 1.2.20, the Next method in version 1.2.33.

    Specifies what lock method the load balancer will use for synchronising shared memory runtime data. If lock is set to O[ptimistic] balancer will not use shared memory lock to find the best worker. If set to P[essimistic] balancer will use shared memory lock. The balancer will work more accurately in case of Pessimistic locking, but can slow down the average response time.

    This feature has been added in jk 1.2.13.

    This directive also exists for normal workers. For those it has a different meaning. If the load balancer can not get a valid member worker or in case of failover, it will try again a number of times given by retries. Before each retry, it will make a pause define by retry_interval directive.

    Until version 1.2.16 the default value was 3.


    The status worker does not communicate with Tomcat. Instead it is responsible for the load balancer management.

    Specifies the url for cascading stylesheet to use. A status worker with read_only=true will not allow any operations, that change the runtime state or configuration of the other workers. These are edit/update/reset/recover.

    This feature has been added in jk 1.2.20.

    It is a list of users which gets compared to the user name authenticated by the web server. If the name is not contained in this list, access is denied. Per default the list is empty and then access is allowed to anybody.

    This directive can be used multiple times.

    This feature has been added in jk 1.2.20.

    By default, the user names are matched case sensitively. You can set user_case_insensitive=true to make the comparison case insensitive. This may be especially useful on the Windows platform.

    This feature has been added in jk 1.2.21.

    For every load balancer worker, the status worker shows a summary of the state of its members. There are three such states, "good", "bad" and "degraded".

    These states are determined depending on the activation of the members (active, disabled, stopped) and their runtime state (ok, n/a, busy, recovering, probing, forced recovery, error). By default, members are assumed to be "good", if their activation is "active" and their runtime state is not "error".

    You can change this mapping, by assigning a list of values to the attribute "good". Each value gives a possible match for the members, and one match suffices. Each value is either a single character, or two characters combined with a dot ".". The single characters are the first characters in the words "active", "disabled", "stopped", "ok", "na", "busy", "recovering", "error". The additional states "probing" and "forced recovery" are always rated equivalent to "recovering". If a value consists only of a single character, then all members with this activation or runtime state will be assumed good. A combination of an activation and a runtime state concatenated with a dot "." does only apply to a member, that has exactly this activation and state.

    Members of a load balancer will first be matched against the state "bad", if they don't match, the state "good" will be tried, and if they still don't match, their state will be "degraded".

    This directive can be used multiple times.

    This feature has been added in jk 1.2.20.

    See: "good".

    By default, members are assumed to be "bad", if their activation is "stopped" or their runtime state is "error".

    This directive can be used multiple times.

    This feature has been added in jk 1.2.20.

    The prefix, which will be used by the status worker when producing properties output (mime=prop). Each property key will be prefixed by this value.

    This feature has been added in jk 1.2.20.

    This directive can be used to customise the XML output from the status worker. If set to - no namespace will be used.

    This feature has been added in jk 1.2.20.

    This directive can be used to customise the XML output from the status worker. If set to - no xmlns will be used.

    Default value is set to xmlns:jk="http://tomcat.apache.org"

    This feature has been added in jk 1.2.20.

    This directive can be used to customise the XML output from the status worker. This value will be inserted to the output xml after the xml header.

    This feature has been added in jk 1.2.20.


    This table lists more advanced configuration options. Most of them only apply to some types of workers. We use the abbreviations AJP for ajp13/ajp14 workers used directly via the workers.list, LB for load balancer workers, and SUB for the workers used indirectly in a load balancer worker as a sub worker or member.

    Connect timeout property told webserver to send a PING request on ajp13 connection after connection is established. The parameter is the delay in milliseconds to wait for the PONG reply. The default value zero disables the timeout (infinite timeout).

    This features has been added in jk 1.2.6 to avoid problem with hung Tomcat's and require ajp13 ping/pong support which has been implemented on Tomcat 3.3.2+, 4.1.28+ and 5.0.13+. Disabled by default.

    Prepost timeout property told webserver to send a PING request on ajp13 connection before forwarding to it a request. The parameter is the delay in milliseconds to wait for the PONG reply. The default value zero disables the timeout (infinite timeout).

    This features has been added in jk 1.2.6 to avoid problem with hung Tomcat's and require ajp13 ping/pong support which has been implemented on Tomcat 3.3.2+, 4.1.28+ and 5.0.13+. Disabled by default.

    The parameter is the number of milliseconds to wait for success during a read event. So this is not a timeout for the complete answer time of a request, but only for the maximum time between two packets received from Tomcat. Usually the longest pause is between sending the request and getting the first packet of the response.

    If the timeout passes without any data received from Tomcat, the webserver will no longer wait for the rest of the response and send an error to the client (browser). Usually this does not mean, that the request is also aborted on the Tomcat backend. If the worker is a member of a load balancer, the load balancer might place the worker into an error state and retry the request on another member. See also max_reply_timeouts, retries and recovery_options.

    By default (value zero) the webserver will wait forever which could be an issue for you. If you set a reply_timeout, adjust it carefully if you have long running servlets.

    The reply_timeout can be overwritten using the Apache httpd environment variable JK_REPLY_TIMEOUT and the worker map extension for reply_timeout.

    This features has been added in jk 1.2.6 to avoid problem with hung Tomcat's and works on all servlet engines supporting ajp13. The variable JK_REPLY_TIMEOUT and the worker map extension have been added in version 1.2.27.

    This directive also exists for load balancer workers. For those it has a different meaning. The maximum number of times that the worker will send a request to Tomcat in case of a communication error. Each retry will be done over another connection. The first time already gets counted, so retries=2 means one retry after error. Before a retry, the worker waits for a configurable sleeping time.

    See also the attribute recovery_options for a more fine-grained control of retries and retry_interval for the sleep time configuration.

    Until version 1.2.16 the default value was 3.

    The amount of time in milliseconds the worker sleeps before doing any retry.

    This features has been added in jk 1.2.27.

    Recovery options influence, how we should handle retries, in case we detect a problem with Tomcat. How often we will retry is controlled by the attribute retries.

    This attribute is a bit mask. The following bits are allowed:
    1: don't recover if Tomcat failed after getting the request
    2: don't recover if Tomcat failed after sending the headers to client
    4: close the connection to Tomcat, if we detect an error when writing back the answer to the client (browser)
    8: always recover requests for HTTP method HEAD (even if Bits 1 or 2 are set)
    16: always recover requests for HTTP method GET (even if Bits 1 or 2 are set)

    This features has been added in jk 1.2.6. Option 4 has been added in version 1.2.16, options 8 and 16 in version 1.2.24.

    Set this value to the HTTP status code that will cause a worker to fail if returned from Servlet container. Use this directive to deal with cases when the servlet container can temporary return non-200 responses for a short amount of time, e.g during redeployment.

    The error page, headers and status codes of the original response will not be send back to the client. Instead the request will result in a 503 response. If the worker is a member of a load balancer, the member will be put into an error state. Request failover and worker recovery will be handled with the usual load balancer procedures.

    This feature has been added in jk 1.2.20.

    Starting with jk 1.2.22 it is possible to define multiple status codes separated by space or comma characters. For example: worker.xxx.fail_on_status=500,503

    Starting with jk 1.2.25 you can also tell the load balancer to not put a member into an error state, if a response returned with one of the status codes in fail_on_status. This feature gets enabled, by putting a minus sign in front of those status codes. For example: worker.xxx.fail_on_status=-404,-500,503

    If set to a positive number, the worker will only be used for a request, if it is currently working on less than this number of concurrent requests.

    Note that this is not related to the Busyness load balancing method.

    This feature is experimental and has been added in jk 1.2.41.

    This attribute sets the maximal AJP packet size in Bytes. The maximum value is 65536. If you change it from the default, you must also change the packetSize attribute of your AJP connector on the Tomcat side! The attribute packetSize is only available in Tomcat 5.5.20+ and 6.0.2+.

    Normally it is not necessary to change the maximum packet size. Problems with the default value have been reported when sending certificates or certificate chains.

    This feature has been added in jk 1.2.19.

    When compiled with IPV6 support, this directive forces IPV6 address resolution for host names which have both IPV6 and IPV4 addresses. In case there is no IPV6 address defined for the given hostname this directive in ineffective. This directive will be also ineffective if there is only IPV6 address defined or if IP address is used for "host", either in IPV4 or IPV6 notation.

    This feature has been added in jk 1.2.38.

    You can set a secret keyword on the Tomcat AJP Connector. Then only requests from workers with the same secret keyword will be accepted.

    Use request.secret="secret key word" in your Tomcat AJP Connector configuration in Tomcat 5.5 or 6.0 and requiredSecret="secret key word" in Tomcat 7.0 onwards.

    If you set a secret on a load balancer, all its members will inherit this secret.

    This feature has been added in jk 1.2.12.

    Space delimited list of uri maps the worker should handle. It is only used, if the worker is included in worker.list.

    This directive can be used multiple times for the same worker.

    If you use a reply_timeout for the members of a load balancer worker, and you want to tolerate a few requests taking longer than reply_timeout, you can set this attribute to some positive value.

    Long running requests will still time out after reply_timeout milliseconds waiting for data, but the corresponding member worker will only be put into an error state, if more than max_reply_timeouts requests have timed out. More precisely, the counter for those bad requests will be divided by two, whenever the load balancer does its internal maintenance (by default every 60 seconds).

    This features has been added in jk 1.2.24 to make reply_timeout less sensitive for sporadic long running requests.

    The recover time is the time in seconds the load balancer will not try to use a worker, after it went into error state. Only after this time has passed, a worker in error state will be marked as in recovering, so that it will be tried for new requests.

    This interval is not checked every time a request is being processed. Instead it is being checked during global maintenance. The time between two runs of global maintenance is controlled by worker.maintain.

    Do not set recover_time to a very short time unless you understand the implications. Every recovery attempt for a worker in error is done by a real request!

    Setting a member of a load balancer into an error state is quite serious. E.g. it means that if you need stickyness, all access to the sessions of the respective node is blocked.

    Some types of error detection do not provide a precise information, whether a node is completely broken or not. In those cases an LB will not immediately put the node into the error state. Only when there have been no successful responses for error_escalation_time seconds after such an error, will the node be put into error state.

    This features has been added in jk 1.2.28.

    The name of the cookie that contains the routing identifier needed for session stickyness. The routing identifier is everything after a "." character in the value of the cookie.

    This feature has been added in jk 1.2.27.

    The name of the path parameter that contains the routing identifier needed for session stickyness. The routing identifier is everything after a "." character in the value of the path parameter.

    This feature has been added in jk 1.2.27.

    Activates generation of session stickyness cookies. Typically you don't need this.

    Some web frameworks replace Tomcat session management and use a different way of generating session IDs. As a consequence the routing ID added by Tomcat to the end of the session ID is lost and we no longer can do sticky load balancing. As a workaround you can use the following steps:

    • Choose a non-standard cookie name using the "session_cookie" attribute.
    • Activate cookie sending by setting the attribute "set_session_cookie" to true.
    • Set the attribute "session_cookie_path" to the correct application URI, like e.g. "/myapp/".

    The cookie will only be send if the request does not already contain a cookie of the same name, or that cookie does not contain a routing ID which the load balancer can fulfill. Especially after a node failover we will send a new cookie to switch stickyness to the new node.

    This feature has been added in jk 1.2.38.

    This attribute is only used if "set_session_cookie" is set to true. See "set_session_cookie" for a description. If the value of "session_cookie_path" is empty (default), then the send cookie will not contain a PATH information.

    This feature has been added in jk 1.2.38.

    Using this directive, a balanced worker of a load balancer can be configured as disabled or stopped. A disabled worker only gets requests, which belong to sessions for that worker. A stopped worker does not get any requests. Users of a stopped worker will lose their sessions, unless session replication via clustering is used.

    Use d or D to disable and s or S to stop. If this directive is not present the deprecated directives "disabled" or "stopped" are used.

    This flag can be changed at runtime using status worker.

    This feature has been added in jk 1.2.19.

    Normally the name of a balanced worker in a load balancer is equal to the jvmRoute of the corresponding Tomcat instance. If you want to include a worker corresponding to a Tomcat instance into several load balancers with different balancing configuration (e.g. disabled, stopped) you can use this attribute.

    Define a separate worker per lb and per Tomcat instance with an arbitrary worker name and set the route attribute of the worker equal to the jvmRoute of the target Tomcat instance.

    If this attribute is left empty, the name of the worker will be used.

    This attribute can be changed at runtime using status worker.

    If the route name contains a period, the part before the first period will be used as domain name, unless domain is set explicitly.

    This feature has been added in jk 1.2.16.
    The automatic domain rule has been added in jk 1.2.20.
    The attribute has been renamed from jvm_route to route in jk 1.2.20.

    An integer number to express preferences between the balanced workers of an lb worker. A load balancer will never choose some balanced worker in case there is another usable worker with lower distance.

    Only in case all workers below a given distance are in error, disabled or stopped, workers of a larger distance are eligible for balancing.

    This feature has been added in jk 1.2.16.

    Domain directive can be used only when the worker is a member of the load balancer. Workers that share the same domain name are treated as single worker. If sticky_session is used, then the domain name is used as session route.

    This directive is used for large system with more then 6 Tomcats, to be able to cluster the Tomcats in two groups and thus lowering the session replication transfer between them.

    This feature has been added in jk 1.2.8.

    Set to the name of the preferred failover worker. If worker matching SESSION ID is in error state then the redirect worker will be used instead. It will be used even if being disabled, thus offering hot standby.

    If you explicitly set a route via the "route" attribute, you must set "redirect" to this route of the preferred failover worker and not to its name.

    This feature has been added in jk 1.2.9.


    The following directives have been deprecated in the past. We include their documentation in case you need to use an older version of mod_jk. We urge you to update and not use them any more. Please migrate your existing configurations.

    This directive has been deprecated since 1.2.16. Cachesize defines the number of connections made to the AJP backend that are maintained as a connection pool. It will limit the number of those connection that each web server child process can make.

    Cachesize property is used only for multi threaded web servers such as Apache 2.0 (worker), IIS and Netscape. The cachesize property should reflect the number of threads per child process. JK will discover the number of threads per child process on Apache 2 web server with worker-mpm and set its default value to match the ThreadsPerChild Apache directive. For IIS the default value is 10. For other web servers than Apache or IIS this value has to be set manually.

    Do not use cachesize with values higher then 1 on Apache 2.x prefork or Apache 1.3.x!
    This directive has been deprecated since 1.2.16. Cache timeout property should be used with cachesize to specify how to time JK should keep an open socket in cache before closing it. This property should be used to reduce the number of threads on the Tomcat web server.

    Each child could open an ajp13 connection if it have to forward a request to Tomcat, creating a new ajp13 thread on Tomcat side.

    The problem is that after an ajp13 connection is created, the child won't drop it until killed. And since the webserver will keep its childs/threads running to handle high-load, even it the child/thread handle only static contents, you could finish having many unused ajp13 threads on the Tomcat side.

    This directive has been deprecated since 1.2.16. The number of seconds that told webserver to cut an ajp13 connection after some time of inactivity. When choosing an endpoint for a request and the assigned socket is open, it will be closed if it was not used for the configured time. It's a good way to ensure that there won't too old threads living on Tomcat side, with the extra cost you need to reopen the socket next time a request be forwarded. This property is very similar to cache_timeout but works also in non-cache mode. If set to value zero (default) no recycle will took place. This directive has been deprecated since 1.2.7. A comma separated list of workers that the load balancer need to manage. This directive has been deprecated since 1.2.19. If set to true the worker will be disabled if member of load balancer. This flag can be changed at runtime using status worker.

    This feature has been added in jk 1.2.9.

    This directive has been deprecated since 1.2.19. If set to true the worker will be stopped if member of load balancer. The flag is needed for stop complete traffic of a sticky session worker. It is only useful, when you have a cluster that replicated the sessions. This flag can be changed at runtime using status worker.

    This feature has been added in jk 1.2.11.

    This directive has been deprecated since 1.2.20. Normally the name of a balanced worker in a load balancer is equal to the jvmRoute of the corresponding Tomcat instance. If you want to include a worker corresponding to a Tomcat instance into several load balancers with different balancing configuration (e.g. disabled, stopped) you can use this attribute.

    Define a separate worker per lb and per Tomcat instance with an arbitrary worker name and set the jvm_route attribute of the worker equal to the jvmRoute of the target Tomcat instance.

    If this attribute is left empty, the name of the worker will be used.

    This attribute can be changed at runtime using status worker.

    This feature has been added in jk 1.2.16.

    tomcat-connectors-1.2.41-src/xdocs/reference/iis.xml0000644000000000000020000003714012446110667020713 0ustar rootbin ]> &project; Mladen Turk Configuring IIS

    The Tomcat redirector requires three entities:

    • isapi_redirect.dll - The IIS server plugin, either obtain a pre-built DLL or build it yourself (see the build section).
    • workers.properties - A file that describes the host(s) and port(s) used by the workers (Tomcat processes). A sample workers.properties can be found under the conf directory.
    • uriworkermap.properties - A file that maps URL-Path patterns to workers. A sample uriworkermap.properties can be found under the conf directory as well.

    The installation includes the following parts:

    • Configuring the ISAPI redirector with a default /examples context and checking that you can serve servlets with IIS.
    • Adding more contexts to the configuration.

    Note that in a 64 Bit environment - at least for IIS 7 - the used IIS Application Pool should have "Enable 32-bit Applications" set to "False". Otherwise the redirector will not be called and returns an http code 404. If you think, the 32bit version of isapi_redirect.dll would do the job instead, you will get an http code 500, because the library is not loadable into a 64 Bit IIS.

    ISAPI redirector reads configuration from the registry, create a new registry key named :

    "HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0"

    Attributes described below as a "string value representing a boolean" can be set either using the numbers 0 (false) and 1 (true) as values, or off (false) and on (true) or any other string starting with the letters f (false), n (false), t (true) or y (true). The values are taken case insensitive. In this documentation we will stick to false and true.

    A string value pointing to the ISAPI extension /jakarta/isapi_redirect.dll

    A value pointing to location where log file will be created. (for example c:\tomcat\logs\isapi.log)
    If one of the log rotation settings (log_rotationtime or log_filesize) are specified then the actual log file name is based on this setting. If the log file name includes any '%' characters, then it is treated as a format string for strftime(3), e.g. c:\tomcat\logs\isapi-%Y-%m-%d-%H_%M_%S.log. Otherwise, the suffix .nnnnnnnnnn is automatically added and is the time in seconds. A full list of format string substitutions can be found in the Apache rotatelogs documentation

    A string value for log level (can be debug, info, warn, error or trace).

    This directive was added in version 1.2.31

    The time between log file rotations in seconds. Setting this to 0 (the default) disables log rotation based on time.

    This directive was added in version 1.2.31

    The maximum log file size in megabytes, after which the log file will be rotated. Setting this to 0 (the default) disables log rotation based on file size.
    The value can have an optional M suffix, i.e. both 5 and 5M will rotate the log file when it grows to 5MB.
    If log_rotationtime is specified, then this setting is ignored.

    A string value which is the full path to workers.properties file (for example c:\tomcat\conf\workers.properties)

    A string value which is the full path to uriworkermap.properties file (for example c:\tomcat\conf\uriworkermap.properties)

    A string value which is the full path to rewrite.properties file (for example c:\tomcat\conf\rewrite.properties)

    A DWORD value size of the shared memory. Set this value to be the number of all defined workers * 400. (Set this value only if you have more then 64 workers)

    This directive has been added in version 1.2.20

    Starting with version 1.2.27 the size of the shared memory is determined automatically, even for large numbers of workers. This attribute is not needed any longer.

    A DWORD value specifying the time in seconds upon which the worker_mount_file will be reloaded.

    This directive has been added in version 1.2.20

    A string value representing a boolean. If it is set to true, URL session suffixes of the form ";jsessionid=..." get stripped of URLs, if the are served locally by the web server.

    The default value is false.

    This directive has been added in version 1.2.21

    A DWORD value representing "0" or "1". This is needed because of minor incompatibilities with IIS 5.1.

    By default its value is 1, which means we use the SF_NOTIFY_AUTH_COMPLETE event. If you set this to 0, then we use SF_NOTIFY_PREPROC_HEADERS. This might be needed for IIS 5.1 when handling requests using the PUT HTTP method.

    This directive has been added in version 1.2.21

    A string value which influences, how URIs are decoded and re-encoded between IIS and Tomcat. You should leave this at it's default value, unless you have a very good reason to change it.

    If the value is "parsed", the forwarded URI will be decoded and explicit path components like ".." will already be resolved. This is less spec compliant and is not safe if you are using prefix forwarding rules.

    If the value is "unparsed", the forwarded URI will be the original request URI. It's spec compliant and also the safest option. Rewriting the URI and then forwarding the rewritten URI will not work.

    If the value is "escaped", the forwarded URI will be the re-encoded form of the URI used by "parsed". Explicit path components like ".." will already be resolved. This will not work in combination with URL encoded session IDs.

    If the value is "proxy", the forwarded URI will be a partially re-encoded form of the URI used by "parsed". Explicit path components like ".." will already be resolved. and problematic are re-encoded.

    The default value since version 1.2.24 is "proxy". Before it was "parsed".

    A string value representing a boolean. If it is set to true, URLs still containing percent signs '%' or backslashes '\' after decoding will be rejected.

    Most web apps do not use such URLs. By enabling reject_unsafe you can block several well known URL encoding attacks.

    The default value is false.

    This directive has been added in version 1.2.24

    One of the string values "all", "none" or "unmount". It controls whether multiple adjacent slashes in request URLs are collapsed before looking for a mount or unmount match.

    Value "all" will result in collapsing before mount and unmount checks, value "none" will result in never collapsing, value "unmount" will check mount rules without collapsing but unmount with collapsing.

    Before version 1.2.41 collapsing was never done. Starting with version 1.2.41 collapsing before looking for unmount matches is the default to prevent easy bypassing of unmount rules.

    This directive has been added in version 1.2.41

    A DWORD value representing the watchdog thread interval in seconds. The workers are maintained periodically by a background thread running periodically every watchdog_interval seconds. Worker maintenance checks for idle connections, corrects load status and is able to detect backend health status.

    The maintenance only happens, if since the last maintenance at least worker.maintain seconds have passed. So setting the watchdog_interval much smaller than worker.maintain is not useful.

    The default value is 0 seconds, meaning the watchdog thread will not be created, and the maintenance is done in combination with normal requests instead.

    This directive has been added in version 1.2.27

    A string value representing the error page url redirection when backend returns non-200 response. This directive can be used to customise the error messages returned from backend server.

    The url must point to a valid server url and can contain format string number (%d) that can be used to separate the pages by error number. The redirect url in that case is formatted by replacing %d from error_page to returned error number.

    This directive has been added in version 1.2.27

    A string value representing a boolean. If it is set to true, chunked encoding is supported by the server.

    The default value is false.

    This directive has been added in version 1.2.27. Until version 1.2.30 it was considered experimental and only available when a special build containing chunking support was used. Starting with 1.2.30 it is no longer considered experimental.

    The ISAPI redirector can read it's configuration from a properties file instead of the registry. This has the advantage that you can use multiple ISAPI redirectors with independent configurations on the same server. The redirector will check for the properties file during initialisation, and use it in preference to the registry if present.

    Create a properties file in the same directory as the ISAPI redirector called isapi_redirect.properties i.e. with the same name as the ISAPI redirector DLL but with a .properties extension. A sample isapi_redirect.properties can be found under the conf directory.

    The property names and values in the properties file are the same as for the registry settings described above. For example:

    # Configuration file for the Tomcat ISAPI Redirector # The path to the ISAPI Redirector Extension, relative to the website # This must be in a virtual directory with execute privileges extension_uri=/jakarta/isapi_redirect.dll # Full path to the log file for the ISAPI Redirector log_file=c:\tomcat\logs\isapi_redirect.log # Log level (debug, info, warn, error or trace) log_level=info # Full path to the workers.properties file worker_file=c:\tomcat\conf\workers.properties # Full path to the uriworkermap.properties file worker_mount_file=c:\tomcat\conf\uriworkermap.properties

    Notes:

    • Back-slashes - '\' - are not escape characters.
    • Comment lines begin with '#'.

    Starting with version 1.2.27 two environment variables are automatically added to the environment that can be used inside .properties files.

    • JKISAPI_PATH - Full path to the ISAPI Redirector.
    • JKISAPI_NAME - Name of the ISAPI Redirector dll without extension

    # Use the logs in the installation path of ISAPI Redirector log_file=$(JKISAPI_PATH)\$(JKISAPI_NAME).log

    The ISAPI redirector with version 1.2.31 can perform log rotation, with configuration and behaviour similar to the rotatelogs program provided with Apache HTTP Server.

    To configure log rotation, configure a log_file, and one of the log_rotationtime or log_filesize options. If both are specified, the log_rotationtime will take precedence, and log_filesize will be ignored.
    For example, to configure daily rotation of the log file:

    # Configuration file for the Tomcat ISAPI Redirector ... # Full path to the log file for the ISAPI Redirector log_file=c:\tomcat\logs\isapi_redirect.%Y-%m-%d.log # Log level (debug, info, warn, error or trace) log_level=info # Rotate the log file every day log_rotationtime=86400 ...

    Or to configure rotation of the log file when it reaches 5MB in size:

    # Configuration file for the Tomcat ISAPI Redirector ... # Full path to the log file for the ISAPI Redirector log_file=c:\tomcat\logs\isapi_redirect.%Y-%m-%d-%H.log # Log level (debug, info, warn, error or trace) log_level=info # Rotate the log file at 5 MB log_filesize=5M ...

    The log will be rotated whenever the configured limit is reached, but only if the log file name would change. If you configure a log file name with strftime(3) format codes in it, then ensure it specifies the same granularity as the rotation time configured, e.g. %Y-%m-%d if rotating daily (log_rotationtime=86400).
    See the rotatelogs documentation for more examples.

    The ISAPI redirector with version 1.2.16 can do a simple URL rewriting. Although not as powerful as Apache Httpd's mod_rewrite, it allows a simple exchange of request URIs

    The rule is in the form original-url-prefix=forward-url-prefix. For example:

    # Simple rewrite rules, making /jsp-examples # and /servlets-examples available under shorter URLs /jsp/=/jsp-examples/ /servlets/=/servlets-examples/

    You can also use regular expressions, if you prefix the rule with a tilde ~:

    # Complex rewrite rule, adding "-examples" # to the first path component of all requests ~/([^/]*)=/$1-examples

    Note that uriworkermap.properties must use the URLs before rewriting.

    tomcat-connectors-1.2.41-src/xdocs/reference/apache.xml0000644000000000000020000013654312472604416021356 0ustar rootbin ]> &project; Mladen Turk Configuring Apache

    Most of the directives are allowed once in the global part of the Apache httpd configuration and once in every <VirtualHost> elements. Exceptions from this rule are explicitly listed in the table below.

    Most values are inherited from the main server to the virtual hosts. Since version 1.2.20 they can be overwritten in the virtual hosts. Exceptions from this rule are again explicitly listed in the table below. See especially JkMountCopy.

    Warning: If Apache httpd and Tomcat are configured to serve content from the same filing system location then care must be taken to ensure that httpd is not able to serve inappropriate content such as the contents of the WEB-INF directory or JSP source code.

    This could occur if the httpd DocumentRoot overlaps with a Tomcat Host's appBase or the docBase of any Context. It could also occur when using the httpd Alias directive with a Tomcat Host's appBase or the docBase of any Context.

    Here are the all directives supported by Apache:

    The name of a worker file for the Tomcat servlet containers.
    This directive is only allowed once. It must be put into the global part of the configuration.
    If you don't use the JkWorkerProperty directives, then you must define your workers with a valid JkWorkersFile. There is no default value.

    Enables setting worker properties inside Apache configuration file. The syntax is the same as in the JkWorkersFile (usually workers.properties). Simply prefix each line with "JkWorkerProperty" to put it directly into the Apache httpd config files.
    This directive is allowed multiple times. It must be put into the global part of the configuration.
    If you don't use the JkWorkerProperty directives, then you must define your workers with a valid JkWorkersFile. There is no default value.
    This directive is available in jk1.2.7 version and later.

    Shared memory file name. Used only on unix platforms. The shm file is used by balancer and status workers.
    This directive is only allowed once. It must be put into the global part of the configuration.
    The default value is logs/jk-runtime-status. It is highly recommended that the shm file be placed on a local drive and not an NFS share.

    The shared memory contains configuration and runtime information for load balancer workers and their members. It is need in order that all apache children

    • share the same status information for load balancing members (OK, ERROR, ...),
    • share the information about load taken by the individual workers,
    • share the information for the parts of the configuration, which are changeable during runtime by status workers.

    Size of the shared memory file name.
    This directive is only allowed once. It must be put into the global part of the configuration.
    The default value depends on the platform. It is usually less than 64KB.

    Starting with version 1.2.27 the size of the shared memory is determined automatically, even for large numbers of workers. This attribute is not needed any longer.

    File containing multiple mappings from a context to a Tomcat worker. It is usually called uriworkermap.properties.
    For inheritance rules, see: JkMountCopy.
    There is no default value.

    This directive configures the reload check interval in seconds. The JkMountFile is checked periodically for changes. A changed file gets reloaded automatically. If you set this directive to "0", reload checking is turned off.
    The default value is 60 seconds.
    This directive has been added in version 1.2.20 of mod_jk.

    A mount point from a context to a Tomcat worker.
    This directive is allowed multiple times. It is allowed in the global configuration and in VirtualHost.
    You can also use it inside Location with a different syntax. Inside Location, one omits the first argument (path), which gets inherited verbatim from the Location argument. Whereas <Location /myapp> matches any URI beginning with "/myapp", any JkMount nested in such a Location block will only match for requests with exact URI /myapp. Therefore nesting JkMount in Location is typically not the right thing to do.
    By default JkMount entries are not inherited from the global server to other VirtualHosts or between VirtualHosts. For the complete inheritance rules, see: JkMountCopy.
    You might append rule extensions to the worker name. The extensions are separated from the worker name by a semicolon ";" using the same syntax as in the uriworkermap.properties file.

    An exclusion mount point from a context to a Tomcat worker. All exclusion mounts are checked after mapping a request to a tomcat worker. If the request maps also to an exclusion, it will not be forwarded to tomcat, and instead be served locally.
    This directive is allowed multiple times. It is allowed in the global configuration and in VirtualHost.
    You can also use it inside Location with a different syntax. Inside Location, one omits the first argument (path), which gets inherited verbatim from the Location argument. Whereas <Location /myapp> matches any URI beginning with "/myapp", any JkUnMount nested in such a Location block will only match for requests with exact URI /myapp. Therefore nesting JkUnMount in Location is typically not the right thing to do.
    For inheritance rules, see: JkMountCopy.
    This directive is available in jk1.2.7 version and later.

    Automatically Alias webapp context directories into the Apache document space.
    Care should be taken to ensure that only static content is served via httpd as a result of using this directive. Any static content served by httpd will bypass any security constraints defined in the application's web.xml.
    For inheritance rules, see: JkMountCopy.
    There is no default value.

    If this directive is set to "On" in some virtual server, the mounts from the global server will be copied to this virtual server, more precisely all mounts defined by JkMount or JkUnMount. The Mounts defined by JkMountFile and JkAutoAlias will only be inherited, if the VirtualHost does not define it's own JkMountFile or JkAutoAlias.
    If you want all vhost to inherit mounts from the main server, you can set JkMountCopy to 'All' in the main server.
    This directive is only allowed inside VirtualHost (with value "On") and in the global server (with value "All").
    The default is Off, so no mounts will be inherited from the global server to any VirtualHost.
    Starting with version 1.2.26 you can also set it to "All" in the global virtual server. This will switch the default to On.

    Name of the Apache environment variable that can be used to set worker names in combination with SetHandler jakarta-servlet.
    This directive is only allowed once per virtual server. It is allowed in the global configuration and in VirtualHost.
    The default value is JK_WORKER_NAME.

    This directive configures the watchdog thread interval in seconds. The workers are maintained periodically by a background thread running periodically every watchdog_interval seconds. Worker maintenance checks for idle connections, corrects load status and is able to detect backend health status.
    The maintenance only happens, if since the last maintenance at least worker.maintain seconds have passed. So setting the JkWatchdogInterval much smaller than worker.maintain is not useful.
    The default value is 0 seconds, meaning the watchdog thread will not be created, and the maintenance is done in combination with normal requests instead.
    This directive is only allowed once. It must be put into the global part of the configuration.
    This directive has been added in version 1.2.27 of mod_jk. It is available only for httpd 2.x and above using APR libraries including thread support.

    Full or server relative path to the mod_jk log file. It will also work with pipe, by using a value of the form "| ...".
    The default value is logs/mod_jk.log.
    Pipes are supported for Apache 1.3 only since version 1.2.16. The default value exists only since version 1.2.20.

    The mod_jk log level, can be debug, info, warn error or trace.
    The default value is info.

    The mod_jk date log format, using an extended strftime syntax. This format will be used for the time stamps in the JkLogFile. The maximum length of the format is 63 characters.
    Starting with version 1.2.24 of mod_jk you can also use %Q for adding milliseconds to the log and %q for microseconds. These conversion specifiers are an extension to strftime. They will only work on platforms with a gettimeofday() function. You can use %Q and %q only once in the pattern and also not both together in the same pattern.
    The default value is "[%a %b %d %H:%M:%S %Y] " and beginning with version 1.2.24 on platforms with a gettimeofday() function it is "[%a %b %d %H:%M:%S.%Q %Y] ".

    Request log format string. See detailed description below.
    There is no default value. Without defining a value, the request logging is turned off.

    Turns on SSL processing and information gathering by mod_jk
    The default value is On.
    In order to make SSL data available for mod_jk in Apache, you need to set SSLOptions +StdEnvVars. For the certificate information you also need to add SSLOptions +ExportCertData.

    Specifically, mod_jk will export the following environment variables from Apache httpd to Tomcat under these request attributes as per the Servlet Specification 3.0, section 3.8:

    Env VarRequest Attribute NameTypeExample
    SSL_CIPHER
    (or JkKEYSIZEIndicator)
    javax.servlet.request.cipher_suite java.lang.String DHE-RSA-AES256-SHA
    SSL_CIPHER_USEKEYSIZE
    (or JkKEYSIZEIndicator)
    javax.servlet.request.key_size java.lang.Integer 256
    SSL_SESSION_ID
    (or JkSESSIONIndicator)
    javax.servlet.request.ssl_session java.lang.String 905...32E (a hex string)
    SSL_CLIENT_CERT_CHAIN_n
    (or JkCERTCHAINPrefixn)
    javax.servlet.request.X509Certificate java.security.X509Certificate[] (A chain of certs in ascending order of trust, the first one being ths client's certificate, the second being the signer of that certificate, and so on)

    In addition mod_jk sends the name of the SSL protocol used as a proprietary request attribute named AJP_SSL_PROTOCOL. Modern Tomcat versions will expose this attribute under the name org.apache.tomcat.util.net.secure_protocol_version. This feature has been added in version 1.2.41 of mod_jk. See also JkSSLPROTOCOLIndicator.

    For all other SSL-related variables, use JkEnvVar for each variable you want. Please note that, like JkEnvVar, these variables are available from the request attributes, not as environment variables or as request headers.

    Name of the Apache environment variable that contains SSL indication.
    The default value is "HTTPS".

    Name of the Apache environment variable that contains the SSL protocol name.
    The default value is "SSL_PROTOCOL".
    This directive has been added in version 1.2.41 of mod_jk.

    Name of the Apache environment variable that contains SSL client certificates.
    The default value is "SSL_CLIENT_CERT".

    Name of the Apache environment variable that contains SSL client cipher.
    The default value is "SSL_CIPHER".

    Name of the Apache environment (prefix) that contains SSL client chain certificates.
    The default value is "SSL_CLIENT_CERT_CHAIN_".

    Name of the Apache environment variable that contains SSL session.
    The default value is "SSL_SESSION_ID".

    Name of the Apache environment variable that contains SSL key size in use.
    The default value is "SSL_CIPHER_USEKEYSIZE".

    Name of the Apache environment variable which can be used to overwrite the forwarded local name. Use this only if you need to adjust the data (see the proxy documentation).
    The default value is "JK_LOCAL_NAME".
    This directive has been added in version 1.2.28 of mod_jk.

    Name of the Apache environment variable which forces to ignore an existing Content-Length request header. This can be used to make mod_jk conpatible with mod_deflate request body inflation (see below).
    The default value is "JK_IGNORE_CL".
    This directive has been added in version 1.2.41 of mod_jk.

    Name of the Apache environment variable which can be used to overwrite the forwarded local IP address. Use this only if you need to adjust the data (see the proxy documentation).
    The default value is "JK_LOCAL_ADDR".
    This directive has been added in version 1.2.41 of mod_jk.

    Name of the Apache environment variable which can be used to overwrite the forwarded local port. Use this only if you need to adjust the data (see the proxy documentation).
    The default value is "JK_LOCAL_PORT".
    This directive has been added in version 1.2.28 of mod_jk.

    Name of the Apache environment variable which can be used to overwrite the forwarded remote (client) host name. Use this only if you need to adjust the data (see the proxy documentation).
    The default value is "JK_REMOTE_HOST".
    This directive has been added in version 1.2.28 of mod_jk.

    Name of the Apache environment variable which can be used to overwrite the forwarded remote (client) IP address. Use this only if you need to adjust the data (see the proxy documentation).
    The default value is "JK_REMOTE_ADDR".
    This directive has been added in version 1.2.28 of mod_jk.

    Name of the Apache environment variable which can be used to overwrite the forwarded remote (client) IP address. Use this only if you need to adjust the data (see the proxy documentation).
    The default value is "JK_REMOTE_PORT".
    This directive has been added in version 1.2.32 of mod_jk.

    Name of the Apache environment variable which can be used to overwrite the forwarded user name. Use this only if you need to adjust the data (see the proxy documentation).
    The default value is "JK_REMOTE_USER".
    This directive has been added in version 1.2.28 of mod_jk.

    Name of the Apache environment variable which can be used to overwrite the forwarded authentication type. Use this only if you need to adjust the data (see the proxy documentation).
    The default value is "JK_AUTH_TYPE".
    This directive has been added in version 1.2.28 of mod_jk.

    Set one of more options to configure the mod_jk module. See below for details about this directive.
    This directive can be used multiple times per virtual server.
    The default value is "ForwardURIProxy" since version 1.2.24. It was "ForwardURICompatUnparsed" in version 1.2.23 and "ForwardURICompat" until version 1.2.22.

    Adds a name and an optional default value of environment variable that should be sent to servlet-engine as a request attribute. If the default value is not given explicitly, the variable will only be send, if it is set during runtime.
    The default is empty, so no additional variables will be sent.
    This directive can be used multiple times per virtual server. The settings will be merged between the global server and any virtual server.
    You can retrieve the variables on Tomcat as request attributes via request.getAttribute(attributeName). Note that the variables send via JkEnvVar will not be listed in request.getAttributeNames().
    Empty default values are supported since version 1.2.20. Not sending variables with empty defaults and empty runtime value has been introduced in version 1.2.21.

    If this directive is set to On in some virtual server, the session IDs ;jsessionid=... will be removed for URLs which are not forwarded but instead are handled by the local server.
    This directive is only allowed inside VirtualHost.
    The default is Off.
    This directive has been introduced in version 1.2.21.
    With version 1.2.27 and later this directive can have optional session ID identifier. If not specified it defaults to ;jsessionid.

    We'll discuss here the mod_jk directive types.

    JkWorkersFile specify the location where mod_jk will find the workers definitions. Take a look at Workers documentation for detailed description. JkWorkersFile /etc/httpd/conf/workers.properties

    JkLogFile specify the location where mod_jk is going to place its log file.

    JkLogFile /var/log/httpd/mod_jk.log

    Since JK 1.2.3 for Apache 2.x and JK 1.2.16 for Apache 1.3 this can also be used for piped logging:

    JkLogFile "|/usr/bin/rotatelogs /var/log/httpd/mod_jk.log 86400"

    JkLogLevel set the log level between :

    • info log will contain standard mod_jk activity (default).
    • warn log will contain non fatal error reports.
    • error log will contain also error reports.
    • debug log will contain all information on mod_jk activity
    • trace log will contain all tracing information on mod_jk activity
    JkLogLevel info

    info should be your default selection for normal operations.

    JkLogStampFormat will configure the date/time format found on mod_jk log file. See above for details.

    JkLogStampFormat "[%Y-%m-%d %H:%M:%S.%Q] "



    You can log mod_jk information using the Apache standard module mod_log_config. The module sets several notes in the Apache httpd notes table. Most of them are are only useful in combination with a load balancer worker.

    Name of the worker selected by the URI mapping Type of the worker selected by the URI mapping Actual worker name selected by the URI mapping (usually a member of the load balancer).
    Before version 1.2.26 only available if JkRequestLogFormat is set.
    Request duration in seconds and microseconds.
    Before version 1.2.26 only available if JkRequestLogFormat is set.
    Load-Balancer: Name of the first worker tried Load-Balancer: Type of the first worker tried Load-Balancer: Access count for the first worker tried Load-Balancer: Count of created sessions for the first worker tried Load-Balancer: Bytes read for the first worker tried Load-Balancer: Bytes transferred for the first worker tried Load-Balancer: Error count for the first worker tried Load-Balancer: Busy count for the first worker tried Load-Balancer: Activation state for the first worker tried Load-Balancer: Error state for the first worker tried Load-Balancer: Name of the last worker tried Load-Balancer: Type of the last worker tried Load-Balancer: Access count for the last worker tried Load-Balancer: Count of created sessions for the last worker tried Load-Balancer: Bytes read for the last worker tried Load-Balancer: Bytes transferred for the last worker tried Load-Balancer: Error count for the last worker tried Load-Balancer: Busy count for the last worker tried Load-Balancer: Activation state for the last worker tried Load-Balancer: Error state for the last worker tried
    LogFormat "%h %l %u %t \"%r\" %>s %b %{JK_WORKER_NAME}n %{JK_LB_FIRST_NAME}n \ %{JK_LB_FIRST_BUSY}n %{JK_LB_LAST_NAME}n %{JK_LB_LAST_BUSY}n" mod_jk_log CustomLog logs/access_log mod_jk_log

    You can also log a request protocol in the mod_jk log file instead of the access log. This is not recommended and mostly a backward compatibility feature. The directive JkRequestLogFormat will configure the format of this protocol. It gets configured and enabled on a per virtual host basis. To enable request logging for a virtual host just add a JkRequestLogFormat config. The syntax of the format string is similar to the Apache LogFormat command, here is a list of the available request log format options:

    Bytes sent, excluding HTTP headers (CLF format) Bytes sent, excluding HTTP headers The request protocol The request method The canonical Port of the server serving the request The query string (prepended with a ? if a query string exists, otherwise an empty string) First line of request Request HTTP status code Request duration, elapsed time to handle request in seconds '.' micro seconds The URL path requested, not including any query string. The canonical ServerName of the server serving the request The server name according to the UseCanonicalName setting Tomcat worker name Real worker name JkRequestLogFormat "%w %V %T"

    The directive JkOptions allow you to set many forwarding options which will enable (+) or disable (-) following option. Without any leading signs, options will be enabled.

    The four following options +ForwardURIxxx are mutually exclusive. Exactly one of them is required, a negative sign prefix is not allowed with them. The default value is "ForwardURIProxy" since version 1.2.24. It was "ForwardURICompatUnparsed" in version 1.2.23 and "ForwardURICompat" until version 1.2.22. You can turn the default off by switching on one of the other two options. You should leave this at it's default value, unless you have a very good reason to change it.

    All options are inherited from the global server to virtual hosts. Options that support enabling (plus options) and disabling (minus options), are inherited in the following way:

    options(vhost) = plus_options(global) - minus_options(global) + plus_options(vhost) - minus_options(vhost)

    Using JkOptions ForwardURIProxy, the forwarded URI will be partially reencoded after processing inside Apache httpd and before forwarding to Tomcat. This will be compatible with local URL manipulation by mod_rewrite and with URL encoded session ids. JkOptions +ForwardURIProxy

    Using JkOptions ForwardURICompatUnparsed, the forwarded URI will be unparsed. It's spec compliant and secure. It will always forward the original request URI, so rewriting URIs with mod_rewrite and then forwarding the rewritten URI will not work. JkOptions +ForwardURICompatUnparsed

    Using JkOptions ForwardURICompat, the forwarded URI will be decoded by Apache httpd. Encoded characters will be decoded and explicit path components like ".." will already be resolved. This is less spec compliant and is not safe if you are using prefix JkMount. This option will allow to rewrite URIs with mod_rewrite before forwarding. JkOptions +ForwardURICompat

    Using JkOptions ForwardURIEscaped, the forwarded URI will be the encoded form of the URI used by ForwardURICompat. Explicit path components like ".." will already be resolved. This will not work in combination with URL encoded session IDs, but it will allow to rewrite URIs with mod_rewrite before forwarding. JkOptions +ForwardURIEscaped

    JkOptions RejectUnsafeURI will block all URLs, which contain percent signs '%' or backslashes '\' after decoding.

    Most web apps do not use such URLs. Using the option RejectUnsafeURI, you can block several well known URL encoding attacks. By default, this option is not set.

    You can also realise such a check with mod_rewrite, which is more powerful but also slightly more complicated. JkOptions +RejectUnsafeURI

    JkOptions CollapseSlashesAll will collapse multiple adjacent slashes in request URLs before looking for mount or unmount matches. JkOptions +CollapseSlashesAll

    JkOptions CollapseSlashesUnmount will collapse multiple adjacent slashes in request URLs only before looking for unmount matches. This is the default value. JkOptions +CollapseSlashesUnmount

    JkOptions CollapseSlashesNone will never collapse multiple adjacent slashes in request URLs before looking for mount or unmount matches. Using this value might make you vulnerable for attacks bypassing your unmount rules. JkOptions +CollapseSlashesNone

    JkOptions ForwardDirectories is used in conjunction with DirectoryIndex directive of Apache web server. As such mod_dir should be available to Apache, statically or dynamically (DSO)

    When DirectoryIndex is configured, Apache will create sub-requests for each of the local-url's specified in the directive, to determine if there is a local file that matches (this is done by stat-ing the file).

    If ForwardDirectories is set to false (default) and Apache doesn't find any files that match, Apache will serve the content of the directory (if directive Options specifies Indexes for that directory) or a 403 Forbidden response (if directive Options doesn't specify Indexes for that directory).

    If ForwardDirectories is set to true and Apache doesn't find any files that match, the request will be forwarded to Tomcat for resolution. This is used in cases when Apache cannot see the index files on the file system for various reasons: Tomcat is running on a different machine, the JSP file has been precompiled etc.

    Note that locally visible files will take precedence over the ones visible only to Tomcat (i.e. if Apache can see the file, that's the one that's going to get served). This is important if there is more then one type of file that Tomcat normally serves - for instance Velocity pages and JSP pages. JkOptions +ForwardDirectories

    Setting JkOptions ForwardLocalAddress, you ask mod_jk to send the local address, of the Apache web server instead remote client address. This can be used by Tomcat remote address valve for allowing connections only from registered Apache web servers. JkOptions +ForwardLocalAddress

    Setting JkOptions ForwardPhysicalAddress, you ask mod_jk to send the physical peer TCP IP address as the client address. By default mod_jk uses the logical address as provided by the web server. For example the module mod_remoteip sets the logical IP address to the client IP forwarded by proxies in the X-Forwarded-For header. JkOptions +ForwardPhysicalAddress

    JkOptions FlushPackets, you ask mod_jk to flush Apache's connection buffer after each AJP packet chunk received from Tomcat. This option can have a strong performance penalty for Apache and Tomcat as writes are performed more often than would normally be required (ie: at the end of each response). JkOptions +FlushPackets

    JkOptions FlushHeader, you ask mod_jk to flush Apache's connection buffer after the response headers have been received from Tomcat. JkOptions +FlushHeader

    JkOptions DisableReuse, you ask mod_jk to close connections immediately after their use. Normally mod_jk uses persistent connections and pools idle connections to reuse them, when new requests have to be sent to Tomcat.

    Using this option will have a strong performance penalty for Apache and Tomcat. Use this only as a last resort in case of unfixable network problems. If a firewall between Apache and Tomcat silently kills idle connections, try to use the worker attribute socket_keepalive in combination with an appropriate TCP keepalive value in your OS. JkOptions +DisableReuse

    JkOptions ForwardKeySize, you ask mod_jk, when using ajp13, to forward also the SSL Key Size as required by Servlet API 2.3. This flag shouldn't be set when servlet engine is Tomcat 3.2.x (on by default). JkOptions +ForwardKeySize

    JkOptions ForwardSSLCertChain, you ask mod_jk, when using ajp13, to forward SSL certificate chain (off by default). Mod_jk only passes the SSL_CLIENT_CERT to the AJP connector. This is not a problem with self-signed certificates or certificates directly signed by the root CA certificate. However, there's a large number of certificates signed by an intermediate CA certificate, where this is a significant problem: A servlet will not have the possibility to validate the client certificate on its own. The bug would be fixed by passing on the SSL_CLIENT_CERT_CHAIN to Tomcat via the AJP connector.
    This directive exists only since version 1.2.22. JkOptions +ForwardSSLCertChain

    The directive JkEnvVar allows you to forward environment variables from Apache server to Tomcat engine. You can add a default value as a second parameter to the directive. If the default value is not given explicitly, the variable will only be send, if it is set during runtime.
    The variables can be retrieved on the Tomcat side as request attributes via request.getAttribute(attributeName). Note that the variables send via JkEnvVar will not be listed in request.getAttributeNames().

    The variables are inherited from the global server to virtual hosts. JkEnvVar SSL_CLIENT_V_START undefined

    If you have created a custom or local version of mod_jk.conf-local as noted above, you can change settings such as the workers or URL prefix.

    JkMount directive assign specific URLs to Tomcat. In general the structure of a JkMount directive is:

    JkMount [URL prefix] [Worker name] # send all requests ending in .jsp to worker1 JkMount /*.jsp worker1 # send all requests ending /servlet to worker1 JkMount /*/servlet/ worker1 # send all requests jsp requests to files located in /otherworker will go worker2 JkMount /otherworker/*.jsp worker2

    You can use the JkMount directive at the top level or inside <VirtualHost> sections of your httpd.conf file.

    JkUnMount directive acts as an opposite to JkMount and blocks access to a particular URL. The purpose is to be able to filter out the particular content types from mounted context. The following example mounts /servlet/* context, but all .gif files that belongs to that context are not served.

    # send all requests ending with /servlet to worker1 JkMount /servlet/* worker1 # do not send requests ending with .gif to worker1 JkUnMount /servlet/*.gif worker1

    JkUnMount takes precedence over JkMount directives, meaning that the JK will first try to mount and then checks, if there is an exclusion defined by a JkUnMount. A JkUnMount overrides a JkMount only, if the worker names in the JkMount and in the JkUnMount are the same.

    The following example will block all .gif files although there is a JkMount for them:

    # do not send requests ending with .gif to worker1 JkUnMount /*.gif worker1 # The .gif files will not be mounted cause JkUnMount takes # precedence over JkMount directive JkMount /servlet/*.gif worker1

    Starting with version 1.2.26 of JK you can apply a JkUnMount to any worker, by using the star character '*' as the worker name in the JkUnMount. More complex patterns in JkUnMount worker names are not allowed.

    # Mapping the webapps myapp1 and myapp2: /myapp1/*=worker1 /myapp2/*=worker2 # Exclude the all subdirectories static for all workers: !/*/static/*=* # Exclude some suffixes for all workers: !*.html=*

    JkAutoAlias directive automatically Alias webapp context directories into the Apache document space. It enables Apache to serve a static context while Tomcat serving dynamic context. This directive is used for convenience so that you don't have to put an apache Alias directive for each application directory inside Tomcat's webapp directory. For security reasons it is strongly recommended that JkMount is used to pass all requests to Tomcat by default and JkUnMount is used to explicitly exclude static content to be served by httpd. It should also be noted that content served by httpd will bypass any security constraints defined in the application's web.xml.

    # enter the full path to the tomcat webapps directory JkAutoAlias /opt/tomtact/webapps

    The following example shows how to serve a dynamic context by Tomcat and static using Apache. The webapps directory has to be accessible by apache.

    # enter the full path to the tomcat webapps directory JkAutoAlias /opt/tomtact/webapps # Mount 'servlets-examples' directory. It's physical location # is assumed to be in the /opt/tomtact/webapps/servlets-examples # ajp13w is a worker defined in the workers.properties JkMount /servlets-examples/* ajp13w # Unmount desired static content from servlets-examples webapp. # This content will be served by the httpd directly. JkUnMount /servlets-examples/*.gif ajp13w JkUnMount /servlets-examples/*.jpg ajp13w

    Note that you can have a single JkAutoAlias directive per virtual host inside your httpd.conf

    JkWorkerProperty is a new directive available from JK 1.2.7 version. It is a convenient method for setting directives that are usually set inside workers.propeties file. The parameter for that directive is raw line from workers.properties file.

    # Just like workers.properties but exact line is prefixed # with JkWorkerProperty # Minimal jk configuration JkWorkerProperty worker.list=ajp13w JkWorkerProperty worker.ajp13w.type=ajp13 JkWorkerProperty worker.ajp13w.host=localhost JkWorkerProperty worker.ajp13w.port=8009

    JkMountFile is a new directive available from JK 1.2.9 version. It is used for dynamic updates of mount points at runtime. When the mount file is changed, JK will reload it's content.

    # Load mount points JkMountFile conf/uriworkermap.properties

    If the mount point uri starts with an exclamation mark '!' it defines an exclusion in the same way JkUnMount does. If the mount point uri starts with minus sign '-' the mount point will only be disabled. A disabled mount can be reenabled by deleting the minus sign and waiting for the JkMountFile to reload. An exclusion can be disabled by prefixing it with a minus sign.

    # Sample uriworkermap.properties file /servlets-examples/*=ajp13w # Do not map .jpeg files !/servlets-examples/*.jpeg=ajp13w # Make jsp examples initially disabled -/jsp-examples/*=ajp13w

    At run time you can change the content of this file. For example removing minus signs will enable the previously disabled uri mappings. You can add any number of new entries at runtime that reflects the newly deployed applications. Apache will reload the file and update the mount points within 60 second interval.

    There is no way to delete entries by dynamic reloading, but you can disable or exclude mappings.

    Alternatively to the mod_jk specific directives, you can also use SetHandler and environment variables to control, which requests are being forwarded via which worker. This gives you more flexibility, but the results might be more difficult to understand. If you mix both ways of defining the forwards, in general to mod_jk directives will win.

    SetHandler jakarta-servlet forces requests to be handled by mod_jk. If you neither specify any workers via JkMount and the related directives, not via the environment variable described below, the first worker in the list of all worker will be chosen. You can use SetHandler for example in Location blocks or with Apache 2.2 and later also in RewriteRule.

    In order to control the worker using SetEnvIf or RewriteRule for more complex rules, you can set the environment variable JK_WORKER_NAME to the name of your chosen target worker. This enables you to decide on the chosen worker in a more flexible way, including dependencies on cookie values. This feature has been added in version 1.2.19 of mod_jk. Furthermore you might append rule extensions to the worker name. The extensions are separated from the worker name by a semicolon ";" using the same syntax as in the uriworkermap.properties file. Supporting rule extensions in the worker name has been added in version 1.2.33.

    In order to use another variable than JK_WORKER_NAME, you can set the name of this variable via the JkWorkerIndicator directive.

    You can also define exclusions from mod_jk forwards by setting the environment variable no-jk.

    # Automatically map all encoded urls <Location *;jsessionid=> SetHandler jakarta-servlet SetEnv JK_WORKER_NAME my_worker </Location> # Map all subdirs to workers via naming rule # and exclude static content. <Location /apps/> SetHandler jakarta-servlet SetEnvIf REQUEST_URI ^/apps/([^/]*)/ JK_WORKER_NAME=$1 SetEnvIf REQUEST_URI ^/apps/([^/]*)/static no-jk </Location>

    Environment variables allow to overwrite the default behaviour of mod_jk depending on request properties like e.g. the request URI, header values or cookie. This can be done using the SetEnvIf or RewriteRule directives.

    The environment variable JK_ROUTE can be set to explicitely choose a member of a load balancer worker. The value must be equal to the route attribute of the member, or if that attribute is not used, equal to the member name. Note that this is only needed if session IDs and routes are encoded in a non standard way in the request. Stickyness using the Java Servlet compliant way of encoding the IDs is supported by default. This is available since version 1.2.33.

    The environment variable JK_REPLY_TIMEOUT can be set to dynamically define a reply timeout. The value must be given in milliseconds. This is available since version 1.2.27.

    The environment variable JK_STICKY_IGNORE can be set to disable session stickyness for individual requests. If the variable is set to an empty string or a nonzero number, session stickyness will be disabled. Setting it to 0 will reset to the behaviour defined by the worker configuration. This is available since version 1.2.33.

    This feature can be useful to optimize load balancing when using cookie based session stickyness. In this case, as long as she keeps her browser open, any request by a user who started a session will be send to the same Tomcat instance, even if he left the part of the application which uses the session. You can for instance set this environment variable when a user requests a login form to ensure, that this initial session request is balanced non-sticky.

    The environment variable JK_STATELESS can be used to improve load balancing for the session based balancing methods Session and Next. In this case normally any request which does not come with a session id counts as a new session. This can be problematic, if for instance static content is retrieved without a session id. If you set the environment variable JK_STATELESS for a request, then the request will not count as a new session, even if it does not come with a session id. This is available since version 1.2.33.

    The environment variable JK_IGNORE_CL can be set to force ignoring the request Content-Length header (if it exists). mod_jk will then stream the request body until the web server indicates that the full body was read. No Content-Length header will be send to the backend. This is available since version 1.2.41.

    This feature can be used to make mod_jk compatible with filters which change the size of the request body. One such filter is mod_deflate when used to inflate the body of a request with gzip encoded body. In this case mod_jk will by default forward a truncated body, because it gets the wrong body size from the web server. Telling mod_jk to ignore the Content-Length header will result in streaming all request body data it can read from the web server to the backend.

    You should only set the JK_IGNORE_CL environment variables for requests that actually need it. Unfortunately there's no way for mod_jk to detect the need automatically.

    tomcat-connectors-1.2.41-src/xdocs/reference/uriworkermap.xml0000644000000000000020000004037212472575314022662 0ustar rootbin ]> &project; Rainer Jung Mladen Turk uriworkermap.properties configuration

    The forwarding of requests from the web server to tomcat gets configured by defining mapping rules. Such a rule maps requests to workers. The request part of the map is described by a URI pattern, the worker by it's worker name.

    The so-called uriworkermap file is a mechanism of defining rules, which works for all web servers. There exist also other web server specific configuration options for defining rules, which will be mostly discussed on the reference pages for configuring tomcat connectors for the individual web servers.

    The name of the file is usually uriworkermap.properties, although this is configurable in the web server. Please consult the web server specific documentation pages on how to enable the uriworkermap file.

    The main features supported by the uriworkermap file are

    • Support for comments in the rule file.
    • Exact and wildchar matches, shortcuts to map a directory and all including content.
    • Exclusion rules, disabling of rules and rule priorities.
    • Rule extensions, modifying worker behaviour per rule.
    • Virtual host integration: uri mapping rules can be expressed per virtual host. The details are web server specific though.
    • Dynamic reloading: The file gets checked periodically for changes. New versions are automatically reloaded without web server restarts.
    • Integration with the status worker.
    The following sections describe these aspects in more detail.



    The file has a line based format. There are no continuation characters, so each rule needs to be defined on a single line. Each rule is a pair consisting of a URI pattern and a worker name, combined by an equals sign '=': /myapp=myworker The URI pattern is case sensitive.


    All text after and including the character '#' gets ignored and can be used for comments. Leading and trailing white space gets trimmed around the URI pattern and also around the worker name. The following definitions are all equivalent: # This is a white space example /myapp=myworker /myapp=myworker /myapp = myworker


    Inside the URI pattern three special characters can be used, '*', '?' and '|'. The character '*' is a wildchar that matches any number of arbitrary characters in the URI, '?' matches exactly one character. Each URI pattern has to start with the character '/', or with '*' or with '?', optionally prefixed by any combination of the modifiers '!' and '-' (see next section). # Mapping the URI /myapp1 and everything under /myapp1/: /myapp1=myworker-a /myapp1/*=myworker-a # Mapping all URI which end with a common suffix: *.jsp=myworker *.do=myworker Since the first case of mapping a certain location and everything inside it is very common, the character '|' gives a handy shortcut: # Mapping the URI /myapp1 and everything under /myapp1/: /myapp1|/*=myworker-a The pattern 'X|Y' is exactly equivalent to the two maps 'X' and 'XY'.



    Exclusion rules allows to define exclusions from URI rules, which would forward requests to tomcat. If the exclusion rule matches, the request will not be forwarded. This is usually used to serve static content by the web server. A rule is an exclusion rule, if it is suffixed with '!': # Mapping the URI /myapp and everything under /myapp/: /myapp|/*=myworker # Exclude the subdirectory static: !/myapp/static|/*=myworker # Exclude some suffixes: !*.html=myworker An exclusion rule overrides a normal mapping rule only, if the worker names in the normal rule and in the exclusion rule are the same. Starting with version 1.2.26 of JK you can apply an exclusion rule to any worker, by using the star character '*' as the worker name in the exclusion rule. More complex patterns in exclusion worker names are not allowed. # Mapping the webapps /myapp1 and /myapp2: /myapp1|/*=myworker1 /myapp2|/*=myworker2 # Exclude the all subdirectories static for all workers: !/*/static|/*=* # Exclude some suffixes for all workers: !*.html=*

    Rule disabling comes into play, if your web server merges rules from various sources, and you want to disable any rule defined previously. Since the uriworkermap file gets reloaded dynamically, you can use this to temporarily disable request forwarding: A rule gets disabled, if it is suffixed with '-': # We are not in maintenance. # The maintenance rule got defined somewhere else. -/*=maintenance Exclusion rules can get disabled as well, then the rule starts with '-!'.


    The most restrictive URI pattern is applied first. More precisely the URI patterns are sorted by the number of '/' characters in the pattern (highest number first), and rules with equal numbers are sorted by their string length (longest first).

    If both distinctions still do not suffice, then the defining source of the rule is considered. Rules defined in uriworkermap.properties come first, before rules defined by JkMount (Apache) and inside workers.properties using the mount attribute.

    All disabled rules are ignored. Exclusion rules are applied after all normal rules have been applied.

    There is no defined behaviour, for the following configuration conflict: using literally the same URI pattern in the same defining source but with different worker targets.


    Rule extensions were added in version 1.2.27 and are not available in earlier versions.


    Rule extensions are additional attributes, that can be attached to any rule. They are added at the end of the rule, each extension separated by a semicolon: # This is an extension example, # setting a reply_timeout of 1 minute # only for this mapping. /myapp=myworker;reply_timeout=60000 # # This is an example using multiple extensions /myapp=myloadbalancer;reply_timeout=60000;stopped=member1 Attributes set via rule extensions always overwrite conflicting configurations in the worker definition file.


    The extension reply_timeout sets a reply timeout for a single mapping rule. # Setting a reply_timeout of 1 minute # only for this mapping. /myapp=myworker;reply_timeout=60000 It overrides any reply_timeout defined for the worker. The extension allows to set a reasonable default reply timeout to the worker, and a more relaxed reply timeout to URLs, which are known to start time intensive tasks. For a general description of reply timeouts see the timeouts documentation.


    The extension sticky_ignore will disable session stickyness for a single mapping rule. # Disable session stickyness # only for this mapping. /myapp/loginform.jsp=myworker;sticky_ignore=1 This extension can be useful to optimize load balancing when using cookie based session stickyness. In this case, as long as she keeps her browser open, any request by a user who started a session will be send to the same Tomcat instance, even if he left the part of the application which uses the session. You can for instance set this environment variable when a user requests a login form to ensure, that this initial session request is balanced non-sticky.

    This extension is available since version 1.2.33.


    The extension stateless is only useful when using session based load balancing. In this case normally any request which does not come with a session id counts as a new session. If you mark a mapping rule with the stateless extension, then the requests matching the mapping rule will not count as a new session, even if they do not come with a session id. # Don't let static content trash our session balancing /myapp/static/*=myworker;stateless=1 This extension is available since version 1.2.33.


    The extensions active, disabled, and stopped can be used in a load balancer mapping rule to set selected members of the load balancer into a special activation state. # Stop forwarding only for member1 of loadbalancer /myapp=myloadbalancer;stopped=member1 Multiple members must be separated by commas or white space: # Stop forwarding for member01 and member02 of loadbalancer # Disable forwarding for member21 and member22 of loadbalancer /myapp=myloadbalancer;stopped=member01,member02;disabled=member21,member22 For the precise meaning of the activation states see the description of activation.


    The extension fail_on_status can be used in any rule: # Send 503 instead of 404 and 500, # and if we get a 503 also set the worker to error /myapp=myworker;fail_on_status=-404,-500,503 Multiple status codes must be separated by commas. For the precise meaning of the attribute see the description of fail_on_status.


    The extension use_server_errors allows to let the web server send an error page, instead of the backend (e.g. Tomcat) error page. This is useful, if one wants to send customized error pages, but those are not part of all web applications. They can then be put onto the web server.

    The value of use_server_errors is a positive number. Any request send to the backend, that returns with an http status code bigger or equal to use_server_errors, will be answered to the client with the error page of the web server for this status code. # Use web server error page for all errors /myapp=myworker;use_server_errors=400 # Use web server error page only for technical errors /myotherapp=myworker;use_server_errors=500


    The extensions

    • session_cookie
    • session_path
    • set_session_cookie
    • session_cookie_path
    allow to define the load balancer worker attributes of the same name per mount. See their descriptions in the worker.properties configuration reference.



    When using IIS you can restrict individual rules to special virtual hosts by prefixing the URI pattern with the virtual host information. The rules is that the url must be prefixed with the host name. # Use www.foo.org as virtual host /www.foo.org/myapp/*=myworker # Use www.bar.org as virtual host /www.bar.org/myapp/*=myworker # Normal mapping /mysecondapp/*=myworker

    Note that /mysecondapp/* will be mapped to all virtual hosts present. In case one needs to prevent the mappings to some particular virtual host then the exclusion rule must be used # Make sure the myapp is accessible by all virtual hosts /myapp/*=myworker # Disable mapping myapp for www.foo.org virtual host !/www.foo.org/myapp/*=myworker


    For Apache you can define individual uriworkermap files per virtual host. The directive JkMountFile can be used in the main server and in each virtual host. If a virtual host does not use JkMountfile, but JkMountCopy is set to 'On', then it inherits the JkMountFile from the main server. If you want all vhost to inherit mounts from the main server, you can set JkMountCopy to 'All' in the main server.


    When a request is being processed, tomcat connectors check the file modification time of the uriworkermap file. To keep the performance penalty low, this happens only, if the last check happened at least n seconds ago.

    For Apache you can configure the interval "n" using the directive JkMountFileReload, for IIS you would use the attribute worker_mount_reload. The default value is 60 seconds. A value of "0" turns off the reloading.

    If the file changed, it gets reloaded completely. If there exist rules coming from other sources than the uriworkermap file (e.g. the workers.properties mount attribute or JkMount with Apache httpd), the new uriworkermap file gets dynamically merged with these ones exactly like when you do a web server restart.

    Until version 1.2.19 reloading behaved slightly differently: it continuously added the full contents of the uriworkermap file to the rule mapping. The merging rules were, that duplicated got eliminated and old rules could be disabled, by defining the rule as disabled in the new file. Rules never got deleted.


    The configuration view of the status worker also shows the various mapping rules. After each worker's configuration, the rules are listed, that forward to this worker. The list contains four columns:

    • the name of the virtual server
    • the URI pattern, prefixed with '-' for a disabled pattern and '!' for an exclusion pattern
    • the type of the rule: Exact or Wildchar
    • and the source of the rule definition: 'worker definition' for the workers.properties file (mount attribute), 'JkMount' for Apache httpd JkMount and it's relatives and finally 'uriworkermap' for the uriworkermap file.

    Note: The following restriction has been removed starting with version 1.2.26.
    For Apache httpd, there is an important subtlety: the request going to the status worker gets executed in the context of some server (main or virtual). The status worker will only show the mapping rules, that are defined for this server (main or virtual).
    Until version 1.2.25 the list contained three columns:

    • the type of the rule: Exact or Wildchar, eventually prefixed with Disabled or Unmount (for exclusion rules)
    • the URI pattern
    • and the source of the rule definition: 'worker definition' for the workers.properties file (mount attribute), 'JkMount' for Apache httpd JkMount and it's relatives and finally 'uriworkermap' for the uriworkermap file.

    tomcat-connectors-1.2.41-src/xdocs/reference/project.xml0000644000000000000020000001152412472604371021572 0ustar rootbin The Apache Tomcat Connectors - Reference Guide The Apache Tomcat Connectors - Reference Guide tomcat-connectors-1.2.41-src/xdocs/reference/status.xml0000644000000000000020000005302112453255640021445 0ustar rootbin ]> &project; Rainer Jung Status Worker Reference

    Tomcat Connectors has a special type of worker, the so-called status worker. The status worker does not forward requests to Tomcat instances. Instead it allows to retrieve status and configuration information at runtime, and furthermore to change many configuration items dynamically. This can be done via a simple embedded web interface.

    The status worker is especially powerful, when used together with load balancing workers.

    This document does not explain the HTML user interface of the status worker. Until now it is very simple, so just go ahead and use it. This doc instead tries to explain the less obvious features of the status worker. We also will give a complete coverage of the various request parameters and their meaning, so that you can include the status worker in your automation scripts.

    The documentation of the status worker starts with jk 1.2.20



    The status worker knows about the following actions:

    • list: lists the configurations and runtime information of all configured workers. The output will be grouped by global information first (version data), then load balancer information, after that AJP worker information and finally the legend. For load balancers, there will be a summary part, and after that details for each member worker. For all workers, we also include the URL mappings (forward definitions).
    • show: the same as list, but only shows data for one chosen worker
    • edit: produces a form to edit configuration data for a chosen worker. There is a special subtype of "edit", that makes it easy to change one attribute for all members of a load balancer, e.g. their activation state.
    • update: commit changes made in an edit form. Caution: the changes will not be persisted to the configuration files. As soon as your restart your web server, all changes made through the status worker will be lost! On the other hand, the changes done by the status worker will be applied during runtime without a restart of the web server.
    • reset: reset all runtime statistics for a worker.
    • recover: Mark a member of a load balancer, that is in error state, for immediate recovery.
    • version: only show version information of the web server and the JK software
    • dump: list the original workers configuration. Caution: the dump will only contain the configuration that was used during startup. Any changes applied later by the dynamic management interface of the status worker itself will not be contained in this dump. The dump action has been added in version 1.2.27.


    For most actions you can choose between 4 output formats.

    • HTML: Used interactively with a browser
    • XML: Mostly useful for automation, when your scripting environment is XML friendly. This format has rich structure information, but does not work line based, so you would really like to use it together with XML tools.
    • Properties: This format is a line based format, that conforms to the rules of Java property files. Most structure information is contained in the hierarchical key. For information, that is of configuration nature, the format should produce lines very similar to the ones you can use in workers.properties. It will not produce a complete configuration file!
    • Text: A simple textual output format.
    The "edit" action does only make sense for the HTML output type.


    In the HTML view, there is an automatic refresh feature, implemented via the meta refresh option of HTML. Once you start the automatic refresh, the UI will will respect it for all actions except edit, update and maintain. Even if you navigate through one of those, the automatic refresh will start again as soon as you come back to one of the other actions.

    Many parts of the HTML page can be minimised, if they are not interesting for you. There are a couple of "Hide" links, which will collapse parts of the information. The feature exists for the following blocks of information:

    • Legend: Do not show the legend for the information presented in "list" and "show" actions
    • URI mappings: Do not show the URI mapping for the workers
    • Load Balancing Workers: Do not show workers of type "lb"
    • AJP Workers: Do not show workers of type ajp
    • Balancer Members: Do not show detailed information concerning each member of load balancers
    • Load Balancer Configuration: Do not show configuration data for load balancers
    • Load Balancer Summary: Do not show status summary for load balancers
    • AJP Configuration: Do not show configuration data for ajp workers load balancer members
    The last three minimisation features have been added in version 1.2.27.


    Note: The following restriction has been removed starting with version 1.2.26.

    The Apache module mod_jk makes use of the internal Apache httpd infrastructure concerning virtual hosts. The downside of this is, that the status worker can only show URL maps, for the virtual host it is defined in. It is not able to reach the configuration objects for other virtual hosts. Of course you can define a status worker in any virtual host you are using. All information presented apart from the URL maps will be the same, independent of the virtual host the status worker has been called in.


    The status worker will log changes made to the configuration with log level "info" to the usual JK log file. Invalid requests will be logged with log level "warn". If you want to report some broken behaviour, log file content of level "debug" or even "trace" will be useful.



    The basic configuration of a status worker is very similar to that of a usual ajp worker. You need to specify a name for the worker, and the URLs you want to map to it. The first part of the configuration happens in the workers.properties file. We define a worker named mystatus of type status: worker.list=mystatus worker.mystatus.type=status Then we define a URL, which should be mapped to this worker, i.e. the URL we use to reach the functionality of the status worker. You can use any method mod_jk supports for the web server of your choice. Possibilities are maps inside uriworkermap.properties, an additional mount attribute in workers.properties, or in Apache JkMount. Here's an example for a uriworkermap.properties line: /private/admin/mystatus=mystatus The URI pattern is case sensitive.

    As you will learn in the following sections, the status worker is very powerful. You should use the usual authentication and authorisation methods of your web server to secure this URL.

    You can also define multiple instances of the status worker, by using different names and URL mappings. For instance you might want to configure them individually and then allow special groups of people to use them


    There are a couple of attributes for the workers.properties entries, which allow to customise various aspects of the output of the status worker.

    The attribute css can be set to the URL of a stylesheet: worker.mystatus.css=/private/admin/static/mystatus.css When writing HTML output, the status worker then includes the line <link rel="stylesheet" type="text/css" href="/private/admin/static/mystatus.css" /> There is no sample stylesheet included with the mod_jk release, and by default the attribute css is empty, so no stylesheet reference will be included in the pages. The HTML code of the status worker output pages does not include any class attributes. If you like to contribute a stylesheet or improvements to the HTML layout, please contact us on the tomcat developers list.

    The properties output format can be customised via the attribute prefix. The names of all properties the status worker does output, will begin with this prefix. The default is "worker".

    Several attributes influence the format when writing XML output. The attribute ns allows to set a namespace prefix, that will be used for every status worker+element. The default is "jk:". Setting it to "-" disables the namespace prefix.

    With the attribute xmlns you can map the prefix to a namespace URL. The default value is xmlns:jk="http://tomcat.apache.org". Setting it to "-" disables the output of the URL.

    Finally you can specify an XML document type via the attribute doctype. The specified string will be inserted at the beginning of the document, directly after the xml header. The default is empty.


    We urge you to use the builtin access control features of your web server to control access to the status worker URLs you have chosen. Nevertheless two configuration attributes of status workers are helpful. The attribute "read_only" disables all features of the status worker, that can be used to change configurations or runtime status of the other workers. A read_only status worker will not allow access to the edit, update, reset or recover actions. The default value is false, ie. read/write. To enable read_only you need to set it to true.

    You could configure two status workers, one has read_only and will be made available to a larger admin group, the other one will be used fully featured, but only by fewer people: worker.list=jk-watch worker.jk-watch.type=status worker.jk-watch.read_only=true worker.jk-watch.mount=/user/status/jk worker.list=jk-manage worker.jk-manage.type=status worker.jk-manage.mount=/admin/status/jk Starting with version 1.2.21, a read/write status worker can also be switched temporarily into read-only mode by the user via a link in the HTML GUI. The user can always switch it back to read/write. Only a status worker configured as read-only via the "read_only" attribute is completely safe from applying any changes.

    The other attribute you can use is user. By default this list is empty, which means no limit on the users. You can set "user" to a comma separated list of user names. If your web server is configured such that it sends the user names with the request, the status worker will check, if the name attached with the request is contained in it's "user" list.

    The user list can be split over multiple occurrences of the "user" attribute.

    By default, the user names are matched case sensitively. Starting with version 1.2.21 you can set the attribute user_case_insensitive to true. Then the comparison will be made case insensitive.


    For load balancing workers the status worker shows some interesting overview information. It categorises the members of the load balancer into the classes "good", "bad" and degraded". This feature can be combined with external escalation procedures. Depending on your global system design and your operating practises your preferred categorisation might vary.

    The categorisation is based on the activation state of the workers (active, disabled or stopped), which is a pure configuration state, and the runtime state (OK or ERR with possible substates idle, busy, recovering, probing, and forced recovery) which only depends on the runtime situation.

    The runtime substates have the following meaning:

    • OK (idle): This worker didn't receive any request since the last balancer maintenance. By default balancer maintenance runs every 60 seconds. The worker should be OK, but since we didn't have to use it for some time, we can't be sure. This state has been called N/A before version 1.2.24.
    • OK (busy): All connections for this worker are in use for requests.
    • ERROR (recovering): The worker was in error state for some time and is now marked for recovery. The next request suitable for this worker will use it.
    • ERROR (probing): After setting the worker to recovering, we received a request suitable for this worker. This request is now using the worker.
    • ERROR (forced recovery): The worker is in error, but we don't have an alternative worker, so we keep using it.

    By default the status worker groups into "good" all members, that have activation "active" and runtime state not equal to "error" with empty substate. The "bad" group consists of the members, that have either activation "stopped", or are in runtime state "error" with empty substate.

    Workers that fit neither of the two groups, are considered to be "degraded".

    You can define other rules for the grouping into good, bad and degraded. The two attributes "good" and "bad" can be populated by a comma-separated list ob single characters or dot-separated pairs. Each character stands for the first character of one of the possible states "active", "disabled", "stopped", "ok", "idle", "busy", "recovering" and "error". The additional states "probing" and "forced recovery" are always rated equivalent to "recovering". Comma-separated entries will be combined with logical "or", if you combine a configuration and a runtime state with a dot. the are combined with logical "and". So the default value for "good" is "a.o,a.i,a.b,a.r", for "bad" it is "e,s".

    The status worker first tries to match against the "bad" definitions, if this doesn't succeed it tries to match against "good", and finally it chooses "degraded", if no "bad" or "good" match can be found.


    This section should help you building automation scripts based on the jk status management interface. This interface is stable in the sense, that we only expect to add further parameters in the future. Existing parameters from previous versions will keep their original semantics. We also expect the output formats XML, Properties and Text to be kept stable. So please use those, if you want to parse status worker output in your automation scripts.


    The action is determined by the parameter cmd. It can have the values "list", "show", "edit", "update", "reset", "recover", "version" and "dump". If you omit the cmd parameter, the default "list" will be used. All actions except for "list", "refresh", "version" and "dump" need additional parameters.

    The action "dump" has been added in version 1.2.27.


    The format is determined by the parameter mime. It can have the values "html", "xml", "txt" and "prop". If you omit the mime parameter, the default "html" will be used. The action "edit" (the edit form) does only make sense for "mime=html".


    Actions that operate on a single worker need one or two additional parameters to select this worker. The parameter w contains the name of the worker from the worker list. If an action operates on a member (sub worker) of a load balancer, the parameter w contains the name of the load balancer worker, and the additional parameter sw contains the name of the sub worker.


    During automatic refresh, the parameter re contain the refresh interval in seconds. If you omit this parameter, automatic refresh will be off.


    The parameter opt contains a bit mask of activated options. The default is 0, so by default no options are activated. The following options exist:

    • 0x0001: hide members of lb workers
    • 0x0002: hide URL maps
    • 0x0004: hide the legend
    • 0x0008: hide load balancer workers
    • 0x0010: hide ajp workers
    • 0x0020: only allow read_only actions for a read/write status worker.
    • 0x0040: hide load balancer configuration
    • 0x0080: hide load balancer status summary
    • 0x0100: hide configuration for ajp and load balancer member workers
    Values 0x0040-0x0100 have been added in version 1.2.27.


    You can use the edit action with a final click to the update button, to change settings of workers. But you can also make direct calls to the update action. The following request parameters contain the configuration information, you want to change. First the list for load balancer workers:

    • vlr: retries (number)
    • vlt: recover_time (seconds)
    • vlee: error_escalation_time (seconds)
    • vlx: max_reply_timeouts (number)
    • vls: sticky_session (0/f/n/off=off, 1/t/y/on=on; case insensitive)
    • vlf: sticky_session_force (0/f/n/off=off, 1/t/y/on=on; case insensitive)
    • vlm: method (0/r="Requests", 1/t="Traffic", 2/b="Busyness", 3/s="Sessions", 4/s="Next"; case insensitive, only first character is used)
    • vll: lock (0/o="Optimistic", 1/p="Pessimistic"; case insensitive, only first character is used)
    And now the list of parameters you can use to change settings for load balancer members:
    • vwa: activation flag (0/a="active", 1/d="disabled", 2/s="stopped"; case insensitive, only first character is used)
    • vwf: load balancing factor (integer weight)
    • vwn: route for use with sticky sessions (string)
    • vwr: redirect to define simple failover rules (string)
    • vwc: domain to tell JK about your replication design (string)
    • vwd: distance to express preferences (integer)
    Finally the list of parameters you can use to change settings for ajp workers and ajp load balancer members:
    • vahst: host (string)
    • vaprt: port (number)
    • vacpt: connection_pool_timeout (number)
    • vact: connect_timeout (number)
    • vapt: prepost_timeout (number)
    • vart: reply_timeout (number)
    • var: retries (number)
    • varo: recovery_options (number)
    • vabl: busy_limit (number)
    • vamps: max_packet_size (number)
    Note that changing the host name or port will only take effect for new connections. Already established connections to the old address will still be used. Nevertheless this feature is interesting, because you can provision load balancer members with port "0", which will automatically be stopped during startup. Later when you know the final names and ports, you can set them and they will be automatically activated.

    The leading character "v" has been added to the parameters in version 1.2.27. Changing settings for ajp workers has also been introduced in version 1.2.27.

    For the details of all parameters, we refer to the workers.properties Reference.


    You can use the edit action to edit all settings for a load balancer or for a member of a load balancer respectively on one page. If you want to edit one configuration aspect for all members of a load balancer simultaneously, this will be triggered by the parameter att. The value of the parameter indicates, which aspect you want to edit. The list is the same as in the previous section, except for "vahst" and "vaprt": "vwa", "vwf", "vwn", "vwr", "vwc", "vwd", "vacpt", "vact", "vapt", "vart", "var", "varo", "vabl" and "vamps". But here you need to put the name into the parameter att, instead of using it as a request parameter name.

    The values of the common aspect for all the load balancer members will be given in parameters named "val0", "val1", ....

    tomcat-connectors-1.2.41-src/xdocs/index.xml0000644000000000000020000001527612555242175017307 0ustar rootbin ]> &project; Mladen Turk Rainer Jung Documentation Index

    This is the top-level entry point of the documentation bundle for the Apache Tomcat Connectors

    Select one of the links from the navigation menu (to the left) to drill down to the more detailed documentation that is available. Each available manual is described in more detail below.

    • JK-1.2.41 released

      The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.41 Stable. This release contains a security fix and bug fixes for issues found in previous releases.

      Download the JK 1.2.41 release.

    • Download previous releases from the archives.


    • workers.properties

      A Tomcat worker is a Tomcat instance that is waiting to execute servlets on behalf of some web server. For example, we can have a web server such as Apache forwarding servlet requests to a Tomcat process (the worker) running behind it.

      This page contains detailed description of all workers.properties directives.

    • uriworkermap.properties

      The forwarding of requests from the web server to tomcat gets configured by defining mapping rules. The so-called uriworkermap file is a mechanism of defining those rules.

    • Status Worker

      The status worker is a builtin management worker. It displays state information and can also be used to dynamically reconfigure JK.

    • Apache

      This page contains detailed description of all directives related to Apache web server.

    • IIS

      This page contains detailed description of all IIS directives.


    • Quick Start

      This page describes the configuration files used by JK on the Web Server side for the 'impatients'.

    • All about workers

      This page contains an overview about the various aspects of defining and using workers.

    • Timeouts

      This page describes the possible timeout settings you can use.

    • Load Balancing

      This page contains an introduction on load balancing with JK.

    • Reverse Proxy

      This page contains an introduction to reverse proxies, how JK handles this situation and how you can influence the JK proxying behaviour.


    These pages contain detailed descriptions of how to build and install JK for the various web servers.


    • AJPv13

      This page describes the Apache JServ Protocol version 1.3 (hereafter ajp13).

    • AJPv13 Extension Proposal

      This page describes an extension proposal for ajp13.


    tomcat-connectors-1.2.41-src/xdocs/common_howto/0000755000000000000020000000000012555256551020156 5ustar rootbintomcat-connectors-1.2.41-src/xdocs/common_howto/workers.xml0000644000000000000020000003412612472575314022401 0ustar rootbin ]> &project; Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Workers HowTo Henri Gomez Gal Shachor Mladen Turk $Date: 2015-02-23 10:02:52 +0000 (Mon, 23 Feb 2015) $

    A Tomcat worker is a Tomcat instance that is waiting to execute servlets on behalf of some web server. For example, we can have a web server such as Apache forwarding servlet requests to a Tomcat process (the worker) running behind it.

    The scenario described above is a very simple one; in fact one can configure multiple Tomcat workers to serve servlets on behalf of a certain web server. The reasons for such configuration can be:

    • We want different contexts to be served by different Tomcat workers to provide a development environment where all the developers share the same web server but own a Tomcat worker of their own.
    • We want different virtual hosts served by different Tomcat processes to provide a clear separation between sites belonging to different companies.
    • We want to provide load balancing, meaning run multiple Tomcat workers each on a machine of its own and distribute the requests between them.

    There are probably more reasons for having multiple workers but I guess that this list is enough... Tomcat workers are defined in a properties file dubbed workers.properties and this tutorial explains how to work with it.

    This document was originally part of Tomcat: A Minimalistic User's Guide written by Gal Shachor, but has been split off for organisational reasons.

    Defining workers to the Tomcat web server plugin can be done using a properties file (a sample file named workers.properties is available in the conf/ directory).

    the file contains entries of the following form:

    worker.list=<a comma separated list of worker names>

    # the list of workers worker.list= worker1, worker2

    When starting up, the web server plugin will instantiate the workers whose name appears in the worker.list property, these are also the workers to whom you can map requests. The directive can be used multiple times.

    Each named worker should also have a few entries to provide additional information on his behalf. This information includes the worker's type and other related worker information. Currently the following worker types that exists are (JK 1.2.5):

    TypeDescription
    ajp12This worker knows how to forward requests to out-of-process Tomcat workers using the ajpv12 protocol.
    ajp13This worker knows how to forward requests to out-of-process Tomcat workers using the ajpv13 protocol.
    lbThis is a load-balancing worker; it knows how to provide round-robin based sticky load balancing with a certain level of fault-tolerance.
    statusThis is a status worker for managing load balancers.

    Defining workers of a certain type should be done with the following property format:

    worker.worker name.type=<worker type> Where worker name is the name assigned to the worker and the worker type is one of the four types defined in the table (a worker name may only contain any space the characters [a-zA-Z0-9\-_]).

    # Defines a worker named "local" that uses the ajpv12 protocol to forward requests to a Tomcat process. worker.local.type=ajp12 # Defines a worker named "remote" that uses the ajpv13 protocol to forward requests to a Tomcat process. worker.remote.type=ajp13 # Defines a worker named "loadbalancer" that loadbalances several Tomcat processes transparently. worker.loadbalancer.type=lb

    After defining the workers you can also specify properties for them. Properties can be specified in the following manner:

    worker.<worker name>.<property>=<property value>

    Each worker has a set of properties that you can set as specified in the following subsections:

    The ajp12 has been deprecated with Tomcat 3.3.x and you should use instead ajp13 which is the only ajp protocol known by all Tomcat 4 and above.

    The ajp12 typed workers forward requests to out-of-process Tomcat workers using the ajpv12 protocol over TCP/IP sockets.

    the ajp12 worker properties are :

    host property sets the host where the Tomcat worker is listening for ajp12 requests.

    port property sets the port where the Tomcat worker is listening for ajp12 requests

    lbfactor property is used when working with a load balancer worker, this is the load-balancing factor for the worker. We'll see more on this in the lb worker section.

    # worker "worker1" will talk to Tomcat listening on machine www.x.com at port 8007 using 2 lb factor worker.worker1.host=www.x.com worker.worker1.port=8007 worker.worker1.lbfactor=2

    Notes: In the ajpv12 protocol, connections are created, used and then closed at each request. The default port for ajp12 is 8007

    The ajp13 typed workers forward requests to out-of-process Tomcat workers using the ajpv13 protocol over TCP/IP sockets. The main difference between ajpv12 and ajpv13 are that:

    • ajpv13 is a more binary protocol and it tries to compress some of the request data by coding frequently used strings as small integers.
    • ajpv13 reuses open sockets and leaves them open for future requests (remember when you've got a Firewall between your web server and Tomcat).
    • ajpv13 has special treatment for SSL information so that the container can implement SSL related methods such as isSecure().

    You should note that Ajp13 is now the only out-process protocol supported by Tomcat 4 and above.

    # worker "worker2" will talk to Tomcat listening on machine www2.x.com at port 8009 using 3 lb factor worker.worker2.host=www2.x.com worker.worker2.port=8009 worker.worker2.lbfactor=3 # worker "worker2" uses connections, which will stay no more than 10mn in the connection pool worker.worker2.connection_pool_timeout=600 # worker "worker2" ask operating system to send KEEP-ALIVE signal on the connection worker.worker2.socket_keepalive=1 # mount can be used as an alternative to the JkMount directive worker.worker2.mount=/contexta /contexta/* /contextb /contextb/*

    Notes: In the ajpv13 protocol, the default port is 8009

    The load-balancing worker does not really communicate with Tomcat workers. Instead it is responsible for the management of several "real" workers. This management includes:

    • Instantiating the workers in the web server.
    • Using the worker's load-balancing factor, perform weighed-round-robin load balancing where high lbfactor means stronger machine (that is going to handle more requests)
    • Keeping requests belonging to the same session executing on the same Tomcat worker.
    • Identifying failed Tomcat workers, suspending requests to them and instead falling-back on other workers managed by the lb worker.

    The overall result is that workers managed by the same lb worker are load-balanced (based on their lbfactor and current user session) and also fall-backed so a single Tomcat process death will not "kill" the entire site. The following table specifies some properties that the lb worker can accept:

    • balance_workers is a comma separated list of workers that the load balancer need to manage. As long as these workers should only be used via the load balancer worker, there is no need to also put them into the worker.list property. This directive can be used multiple times for the same load balancer.
    • sticky_session specifies whether requests with SESSION ID's should be routed back to the same Tomcat worker. Set sticky_session to false when Tomcat is using a Session Manager which can persist session data across multiple instances of Tomcat. By default sticky_session is set to true.

    # The worker balance1 while use "real" workers worker1 and worker2 worker.balance1.balance_workers=worker1, worker2

    The status worker does not communicate with Tomcat. Instead it is responsible for the load balancer management.

    # Add the status worker to the worker list worker.list=jkstatus # Define a 'jkstatus' worker using status worker.jkstatus.type=status

    Next thing is to mount the requests to the jkstatus worker. For Apache web servers use the:

    # Add the jkstatus mount point JkMount /jkmanager/* jkstatus

    To obtain a higher level of security use the:

    # Enable the JK manager access from localhost only <Location /jkmanager/> JkMount jkstatus Order deny,allow Deny from all Allow from 127.0.0.1 </Location>

    You can define "macros" in the property files. These macros let you define properties and later on use them while constructing other properties.

    # property example, like a network base address mynet=194.226.31 # Using the above macro to simplify the address definitions # for a farm of workers. worker.node1.host=$(mynet).11 worker.node2.host=$(mynet).12 worker.node3.host=$(mynet).13

    Workers can reference configurations of other workers. If worker "x" references worker "y", then it inherits all configuration parameters from "y", except for the ones that have explicitly been set for "x".

    # worker toe defines some default settings worker.toe.type=ajp13 worker.toe.socket_keepalive=true worker.toe.connect_timeout=10000 worker.toe.recovery_options=7 # workers tic and tac inherit those values worker.tic.reference=worker.toe worker.tac.reference=worker.toe

    Please note, that the reference contains the full prefix to the referenced configuration attributes, not only the name of the referenced worker.

    References can be nested with a maximum depth of 20. Be careful to avoid loops!

    Attributes which are allowed multiple times for a single worker can not be merged from a worker and a reference. An attribute is only inherited from a reference, if it is not already set for the referring worker.

    References are especially useful, when configuring load balancers. Try to understand the following two stage references:

    # We only use one load balancer worker.list=lb # Let's define some defaults worker.basic.port=8009 worker.basic.type=ajp13 worker.basic.socket_keepalive=true worker.basic.connect_timeout=10000 worker.basic.recovery_options=7 # And we use them in two groups worker.lb1.domain=dom1 worker.lb1.distance=0 worker.lb1.reference=worker.basic worker.lb2.domain=dom2 worker.lb2.distance=1 worker.lb2.reference=worker.basic # Now we configure the load balancer worker.lb.type=lb worker.lb.method=B worker.lb.balanced_workers=w11,w12,w21,w22 worker.w11.host=myhost11 worker.w11.reference=worker.lb1 worker.w12.host=myhost12 worker.w12.reference=worker.lb1 worker.w21.host=myhost21 worker.w21.reference=worker.lb2 worker.w22.host=myhost22 worker.w22.reference=worker.lb2

    Since coping with worker.properties on your own is not an easy thing to do, a sample worker.properties file is bundled along JK.

    You could also find here a sample workers.properties defining :

    • An ajp12 worker that used the host localhost and the port 8007
    • An ajp13 worker that used the host localhost and the port 8008
    • An lb worker that load balance the ajp12 and ajp13 workers
    # Define 3 workers, 2 real workers using ajp12, ajp13, the last one being a loadbalancing worker worker.list=worker1, worker2, worker3 # Set properties for worker1 (ajp12) worker.worker1.type=ajp12 worker.worker1.host=localhost worker.worker1.port=8007 worker.worker1.lbfactor=1 # Set properties for worker2 (ajp13) worker.worker2.type=ajp13 worker.worker2.host=localhost worker.worker2.port=8009 worker.worker2.lbfactor=1 worker.worker2.connection_pool_timeout=600 worker.worker2.socket_keepalive=1 worker.worker2.socket_timeout=60 # Set properties for worker3 (lb) which use worker1 and worker2 worker.worker3.balance_workers=worker1,worker2
    tomcat-connectors-1.2.41-src/xdocs/common_howto/loadbalancers.xml0000644000000000000020000002321512446056535023474 0ustar rootbin ]> &project; Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. LoadBalancer HowTo Mladen Turk $Date: 2014-12-22 18:05:17 +0000 (Mon, 22 Dec 2014) $

    A load balancer is a worker that does not directly communicate with Tomcat. Instead it is responsible for the management of several "real" workers, called members or sub workers of the load balancer.

    This management includes:

    • Instantiating the workers in the web server.
    • Using the worker's load-balancing factor, perform weighted load balancing (distributing load according to defined strengths of the targets).
    • Keeping requests belonging to the same session executing on the same Tomcat (session stickyness).
    • Identifying failed Tomcat workers, suspending requests to them and instead falling-back on other workers managed by the load balancer.
    • Providing status and load metrics for the load balancer itself and all members via the status worker interface.
    • Allowing to dynamically reconfigure load-balancing via the status worker interface.

    Workers managed by the same load balancer worker are load-balanced (based on their configured balancing factors and current request or session load) and also secured against failure by providing failover to other members of the same load balancer. So a single Tomcat process death will not "kill" the entire site.

    Some of the features provided by a load balancer are even interesting, when only working with a single member worker (where load balancing is not possible).

    A worker is configured as a load balancer by setting its worker type to lb.

    The following table specifies some properties used to configure a load balancer worker:

    • balance_workers is a comma separated list of names of the member workers of the load balancer. These workers are typically of type ajp13. The member workers do not need to appear in the worker.list property themselves, adding the load balancer to it suffices.
    • sticky_session specifies whether requests with SESSION ID's should be routed back to the same Tomcat instance that created the session. You can set sticky_session to false when Tomcat is using a session manager which can share session data across multiple instances of Tomcat - or if your application is stateless. By default sticky_session is set to true.
    • lbfactor can be added to each member worker to configure individual strengths for the members. A higher lbfactor will lead to more requests being balanced to that worker. The factors must be given by integers and the load will be distributed proportional to the factors given. Higher factors lead to more requests.
    # The load balancer worker balance1 will distribute # load to the members worker1 and worker2 worker.balance1.type=lb worker.balance1.balance_workers=worker1, worker2 worker.worker1.type=ajp13 worker.worker1.host=myhost1 worker.worker1.port=8009 worker.worker2.type=ajp13 worker.worker1.host=myhost2 worker.worker1.port=8009 Session stickyness is not implemented using a tracking table for sessions. Instead each Tomcat instance gets an individual name and adds its name at the end of the session id. When the load balancer sees a session id, it finds the name of the Tomcat instance and sends the request via the correct member worker. For this to work you must set the name of the Tomcat instances as the value of the jvmRoute attribute in the Engine element of each Tomcat's server.xml. The name of the Tomcat needs to be equal to the name of the corresponding load balancer member. In the above example, Tomcat on host "myhost1" needs jvmRoute="worker1", Tomcat on host "myhost2" needs jvmRoute="worker2".

    For a complete reference of all load balancer configuration attributes, please consult the worker reference.

    The load balancer supports complex topologies and failover configurations. Using the member attribute distance you can group members. The load balancer will always send a request to a member of lowest distance. Only when all of those are broken, it will balance to the members of the next higher configured distance. This allows to define priorities between Tomcat instances in different data center locations.

    When working with shared sessions, either by using session replication or a persisting session manager (e.g. via a database), one often splits up the Tomcat farm into replication groups. In case of failure of a member, the load balancer needs to know, which other members share the session. This is configured using the domain attribute. All workers with the same domain are assumed to share the sessions.

    For maintenance purposes you can tell the load balancer to not allow any new sessions on some members, or even not use them at all. This is controlled by the member attribute activation. The value Active allows normal use of a member, disabled will not create new sessions on it, but still allow sticky requests, and stopped will no longer send any requests to the member. Switching the activation from "active" to "disabled" some time before maintenance will drain the sessions on the worker and minimize disruption. Depending on the usage pattern of the application, draining will take from minutes to hours. Switching the worker to stopped immediately before maintenance will reduce logging of false errors by mod_jk.

    Finally you can also configure hot spare workers by using activation set to disabled in combination with the attribute redirect added to the other workers:

    # The advanced router LB worker worker.list=router worker.router.type=lb worker.router.balance_workers=worker1,worker2 # Define the first member worker worker.worker1.type=ajp13 worker.worker1.host=myhost1 worker.worker1.port=8009 # Define preferred failover node for worker1 worker.worker1.redirect=worker2 # Define the second member worker worker.worker2.type=ajp13 worker.worker2.host=myhost2 worker.worker2.port=8009 # Disable worker2 for all requests except failover worker.worker2.activation=disabled

    The redirect flag on worker1 tells the load balancer to redirect the requests to worker2 in case that worker1 has a problem. In all other cases worker2 will not receive any requests, thus acting like a hot standby.

    A final note about setting activation to disabled: The session id coming with a request is send either as part of the request URL (;jsessionid=...) or via a cookie. When using bookmarks or browsers that are running since a long time, it is possible to send a request carrying an old and invalid session id pointing at a disabled member. Since the load balancer does not have a list of valid sessions, it will forward the request to the disabled member. Thus draining takes longer than expected. To handle such cases, you can add a Servlet filter to your web application, which checks the request attribute JK_LB_ACTIVATION. This attribute contains one of the strings "ACT", "DIS" or "STP". If you detect "DIS" and the session for the request is no longer active, delete the session cookie and redirect using a self-referential URL. The redirected request will then no longer carry session information and thus the load balancer will not send it to the disabled worker. The request attribute JK_LB_ACTIVATION has been added in version 1.2.32.

    The status worker does not communicate with Tomcat. Instead it is responsible for the worker management. It is especially useful when combined with load balancer workers.

    # Add the status worker to the worker list worker.list=jkstatus # Define a 'jkstatus' worker using status worker.jkstatus.type=status

    Next thing is to mount the requests to the jkstatus worker. For Apache web servers use the:

    # Add the jkstatus mount point JkMount /jkmanager/* jkstatus

    To obtain a higher level of security use the:

    # Enable the JK manager access from localhost only <Location /jkmanager/> JkMount jkstatus Order deny,allow Deny from all Allow from 127.0.0.1 </Location>
    tomcat-connectors-1.2.41-src/xdocs/common_howto/quick.xml0000644000000000000020000001227511347450610022011 0ustar rootbin ]> &project; Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Quick Start HowTo Henri Gomez $Date: 2010-03-15 15:26:00 +0000 (Mon, 15 Mar 2010) $

    This document describes the configuration files used by JK on the Web Server side for the 'impatient':

    • workers.properties is a mandatory file used by the webserver and which is the same for all JK implementations (Apache/IIS/NES).
    • web server add-ons to be set on the webserver side.

    We'll give here minimum servers configuration and an example workers.properties to be able to install and check quickly your configuration.

    Here is a minimum workers.properties, using just ajp13 to connect your Apache webserver to the Tomcat engine, complete documentation is available in Workers HowTo.

    # Define 1 real worker using ajp13 worker.list=worker1 # Set properties for worker1 (ajp13) worker.worker1.type=ajp13 worker.worker1.host=localhost worker.worker1.port=8009

    Here is a minimum information about Apache configuration, a more complete separate HowTo for Apache is available.

    You should first have mod_jk.so (unix) or mod_jk.dll (Windows) installed in your Apache module directory (see your Apache documentation to locate it).

    Usual locations for modules directory on Unix:

    • /usr/lib/apache/
    • /usr/lib/apache2/
    • /usr/local/apache/libexec/

    Usual locations for modules directory on Windows :

    • C:\Program Files\Apache Group\Apache\modules\
    • C:\Program Files\Apache Group\Apache2\modules\

    You'll find a link to prebuilt binaries here

    Here is the minimum which should be set in httpd.conf directly or included from another file:

    Usual locations for configuration directory on Unix:

    • /etc/httpd/conf/
    • /etc/httpd2/conf/
    • /usr/local/apache/conf/

    Usual locations for configuration directory on Windows :

    • C:\Program Files\Apache Group\Apache\conf\
    • C:\Program Files\Apache Group\Apache2\conf\

    # Load mod_jk module # Update this path to match your modules location LoadModule jk_module libexec/mod_jk.so # Declare the module for <IfModule directive> (remove this line on Apache 2.x) AddModule mod_jk.c # Where to find workers.properties # Update this path to match your conf directory location (put workers.properties next to httpd.conf) JkWorkersFile /etc/httpd/conf/workers.properties # Where to put jk shared memory # Update this path to match your local state directory or logs directory JkShmFile /var/log/httpd/mod_jk.shm # Where to put jk logs # Update this path to match your logs directory location (put mod_jk.log next to access_log) JkLogFile /var/log/httpd/mod_jk.log # Set the jk log level [debug/error/info] JkLogLevel info # Select the timestamp log format JkLogStampFormat "[%a %b %d %H:%M:%S %Y] " # Send everything for context /examples to worker named worker1 (ajp13) JkMount /examples/* worker1

    A separate HowTo for the IIS web server is available.

    More information to be added!

    A separate HowTo for the Netscape/iPlanet/Sun web server is available. More information to be added?

    (Re)start the web server and browse to the http://localhost/examples/

    tomcat-connectors-1.2.41-src/xdocs/common_howto/timeouts.xml0000644000000000000020000004634412446266173022564 0ustar rootbin ]> &project; Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Timeouts HowTo Rainer Jung $Date: 2014-12-23 13:22:03 +0000 (Tue, 23 Dec 2014) $

    Setting communication timeouts is very important to improve the communication process. They help to detect problems and stabilise a distributed system. JK can use several different timeout types, which can be individually configured. For historical reasons, all of them are disabled by default. This HowTo explains their use and gives hints how to find appropriate values.

    All timeouts can be configured in the workers.properties file. For a complete reference of all worker configuration items, please consult the worker reference. This page assumes, that you are using at least version 1.2.16 of JK. Dependencies on newer versions will be mentioned where necessary.

    Do not set timeouts to extreme values. Very small timeouts will likely be counterproductive. Long Garbage Collection pauses on the backend do not make a good fit with some timeouts. Try to optimise your Java memory and GC settings.

    CPing/CPong is our notion for using small test packets to check the status of backend connections. JK can use such test packets directly after establishing a new backend connection (connect mode) and also directly before each request gets send to a backend (prepost mode). Starting with version 1.2.27 it can also be used when a connection was idle for a long time (interval mode). The maximum waiting time (timeout) for a CPong answer to a CPing and the idle time in interval mode can be configured.

    The test packets will be answered by the backend very fast with a minimal amount of needed processing resources. A positive answer tells us, that the backend can be reached and is actively processing requests. It does not detect, if some context is deployed and working. The benefit of CPing/CPong is a fast detection of a communication problem with the backend. The downside is a slightly increased latency.

    The worker attribute ping_mode can be set to a combination of characters to determine, in which situations test packets are used:

    • C: connect mode, timeout ping_timeout overwritten by connect_timeout
    • P: prepost mode, timeout ping_timeout overwritten by prepost_timeout
    • I: interval mode, timeout ping_timeout, idle time connection_ping_interval
    • A: all modes

    Multiple values must be concatenated without any separator characters. We recommend using all CPing tests. If your application is very latency sensitive, then you should only use the combination of connect and interval mode.

    Activating the CPing probing via ping_mode has been added in version 1.2.27. For older versions only the connect and prepost modes exist and must be activated by explicitely setting connect_timeout and prepost_timeout.

    The worker attribute ping_timeout sets the default wait timeout in milliseconds for CPong for all modes. By default the value is "10000" milliseconds. The value only gets used, if you activate CPing/Cpong probes via ping_mode. The default value should be fine, except if you experience very long Java garbage collection pauses. Depending on your network latency and stability, good custom values often are between 5000 and 15000 milliseconds. You can overwrite the timeout used for connect and prepost mode with connect_timeout and prepost_timeout. Remember: don't use extremely small values.

    The worker attribute connect_timeout sets the wait timeout in milliseconds for CPong during connection establishment. You can use it if you want to overwrite the general timeout set with ping_timeout. To use connect mode CPing, you need to enable it via ping_mode. Since JK usually uses persistent connections, opening new connections is a rare event. We therefore recommend activating connect mode. Depending on your network latency and stability, good values often are between 5000 and 15000 milliseconds. Remember: don't use extremely small values.

    The worker attribute prepost_timeout sets the wait timeout in milliseconds for CPong before request forwarding. You can use it if you want to overwrite the general timeout set with ping_timeout. To use prepost mode CPing, you need to enable it via ping_mode. Activating this type of CPing/CPong adds a small latency to each request. Usually this is small enough and the benefit of CPing/CPong is more important. So in general we also recommend using prepost_timeout. Depending on your network latency and stability, good values often are between 5000 and 10000 milliseconds. Remember: don't use extremely small values.

    Until version 1.2.27 ping_mode and ping_timeout did not exist and to enable connect or prepost mode CPing you had to set connect_timeout respectively prepost_timeout to some reasonable positive value.

    Some platforms allow to set timeouts for all operations on TCP sockets. This is available for Linux and Windows, other platforms do not support this, e.g. Solaris. If your platform supports TCP send and receive timeouts, you can set them using the worker attribute socket_timeout. You can not set the two timeouts to different values.

    JK will accept this attribute even if your platform does not support socket timeouts. In this case setting the attribute will have no effect. By default the value is "0" and the timeout is disabled. You can set the attribute to some seconds value (not: milliseconds). JK will then set the send and the receive timeouts of the backend connections to this value. The timeout is low-level, it is used for each read and write operation on the socket individually.

    Using this attribute will make JK react faster to some types of network problems. Unfortunately socket timeouts have negative side effects, because for most platforms, there is no good way to recover from such a timeout, once it fired. For JK there is no way to decide, if this timeout fired because of real network problems, or only because it didn't receive an answer packet from a backend in time. So remember: don't use extremely small values.

    For the general case of connection establishment you can use socket_connect_timeout. It takes a millisecond value and works on most platforms, even if socket_timeout is not supported. We recommend using socket_connect_timeout because in some network failure situations failure detection during connection establishment can take several minutes due to TCP retransmits. Depending on the quality of your network a timeout somewhere between 1000 and 5000 milliseconds should be fine. Note that socket_timeout is in seconds, and socket_connect_timeout in milliseconds.

    JK handles backend connections in a connection pool per web server process. The connections are used in a persistent mode. After a request completed successfully we keep the connection open and wait for the next request to forward. The connection pool is able to grow according to the number of threads that want to forward requests in parallel.

    Most applications have a varying load depending on the hour of the day or the day of the month. Other reasons for a growing connection pool would be temporary slowness of backends, leading to an increasing congestion of the frontends like web servers. Many backends use a dedicated thread for each incoming connection they handle. So usually one wants the connection pool to shrink, if the load diminishes.

    JK allows connections in the pool to get closed after some idle time. This maximum idle time can be configured with the attribute connection_pool_timeout which is given in units of seconds. The default value is "0", which disables closing idle connections.

    We generally recommend values around 10 minutes, so setting connection_pool_timeout to 600 (seconds). If you use this attribute, please also set the attribute keepAliveTimeout (if it is set explicitly) or connectionTimeout in the AJP Connector element of your Tomcat server.xml configuration file to an analogous value. Caution: keepAliveTimeout and connectionTimeout must be given in milliseconds. So if you set JK connection_pool_timeout to 600, you should set Tomcat keepAliveTimeout or connectionTimeout to 600000.

    JK connections do not get closed immediately after the timeout passed. Instead there is an automatic internal maintenance task running every 60 seconds, that checks the idle status of all connections. The 60 seconds interval can be adjusted with the global attribute worker.maintain. We do not recommend to change this value, because it has a lot of side effects. Until version 1.2.26, the maintenance task only runs, if requests get processed. So if your web server has processes that do not receive any requests for a long time, there is no way to close the idle connections in its pool. Starting with version 1.2.27 you can configure an independent watchdog thread when using Apache 2.x with threaded APR or IIS.

    The maximum connection pool size can be configured with the attribute connection_pool_size. We generally do not recommend to use this attribute in combination with Apache httpd. For Apache httpd we automatically detect the number of threads per process and set the maximum pool size to this value. For IIS we use a default value of 250 (before version 1.2.20: 10), for the Sun Web Server the default is "1". We strongly recommend adjusting this value for IIS and the Sun Web Server to the number of requests one web server process should be able to send to a backend in parallel. You should measure how many connections you need during peak hours without performance problems, and then add some percentage depending on your growth rate etc. Finally you should check, whether your web server processes are able to use at least as many threads, as you configured as the pool size.

    The JK attribute connection_pool_minsize defines, how many idle connections remain when the pool gets shrunken. By default this is half of the maximum pool size.

    One particular problem with idle connections comes from firewalls, that are often deployed between the web server layer and the backend. Depending on their configuration, they will silently drop connections from their status table if they are idle for to long.

    From the point of view of JK and of the web server, the other side simply doesn't answer any traffic. Since TCP is a reliable protocol it detects the missing TCP ACKs and tries to resend the packets for a relatively long time, typically several minutes. Therefore you should always use connection_pool_timeout and connection_pool_minsize on the JK side and keepAliveTimeout or connectionTimeout on the Tomcat side to prevent idle connection drop.

    Furthermore using the boolean attribute socket_keepalive you can set a standard socket option, that automatically sends TCP keepalive packets after some idle time on each connection. By default this is set to false. If you suspect idle connection drops by firewalls you should set this to true.

    Unfortunately the default intervals and algorithms for these packets are platform specific. You might need to inspect TCP tuning options for your platform on how to control TCP keepalive. Often the default intervals are much longer than the firewall timeouts for idle connections. Nevertheless we recommend talking to your firewall administration and your platform administration in order to make them agree on good configuration values for the firewall and the platform TCP tuning.

    In case none of our recommendations help and you are definitively having problems with idle connection drops, you can disable the use of persistent connections when using JK together with Apache httpd. For this you set "JkOptions +DisableReuse" in your Apache httpd configuration. The amount of performance impact this will have depends on the details of your network and your firewall.

    JK can also use a timeout on request replies. This timeout does not measure the full processing time of the response. Instead it controls, how much time between consecutive response packets is allowed.

    In most cases, this is what one actually wants. Consider for example long running downloads. You would not be able to set an effective global reply timeout, because downloads could last for many minutes. Most applications though have limited processing time before starting to return the response. For those applications you could set an explicit reply timeout. Applications that do not harmonise with reply timeouts are batch type applications, data warehouse and reporting applications which are expected to observe long processing times.

    If JK aborts waiting for a response, because a reply timeout fired, there is no way to stop processing on the backend. Although you free processing resources in your web server, the request will continue to run on the backend - without any way to send back a result once the reply timeout fired.

    JK uses the worker attribute reply_timeout to set reply timeouts. The default value is "0" (timeout disabled) and you can set it to any millisecond value.

    In combination with Apache httpd, you can also set a more flexible reply_timeout using an httpd environment variable. If you set the variable JK_REPLY_TIMEOUT to some integer value, this value will be used instead of the value in the worker configuration. This way you can set reply timeouts more flexible with mod_setenvif and mod_rewrite depending on URI, query string etc. If the environment variable JK_REPLY_TIMEOUT is not set, or is set to a negative value, the default reply timeout of the worker will be used. If JK_REPLY_TIMEOUT contains the value "0", then the reply timeout will be disabled for the request.

    In combination with a load balancing worker, JK will disable a member worker of the load balancer if a reply timeout fires. The worker will then no longer be used until it gets recovered during the next automatic maintenance task. Starting with JK 1.2.24 you can improve this behaviour using max_reply_timeouts. This attribute will allow occasional long running requests without disabling the worker. Only if those requests happen to often, the worker gets disabled by the load balancer.


    A load balancer worker does not only have the ability to balance load. It also handles stickyness and failover of requests in case of errors. When a load balancer detects an error on one of its members, it needs to decide, whether the error is serious, or only a temporary error or maybe only related to the actual request that was processed. Temporary errors are called local errors, serious errors will be called global errors.

    If the load balancer decides that a backend should be put into the global error state, then the web server will not send any more requests there. If no session replication is used, this means that all user sessions located on the respective backend are no longer available. The users will be send to another backend and will have to login again. So the global error state is not transparent to the users. The application is still available, but users might loose some work.

    In some cases the decision between local error and global error is easy. For instance if there is an error sending back the response to the client (browser), then it is very unlikely that the backend is broken. So this situation is a typical example of a local error.

    Some situations are harder to decide though. If the load balancer can't establish a new connection to a backend, it could be because of a temporary overload situation (so no more free threads in the backend), or because the backend isn't alive any more. Depending on the details, the right state could either be local error or global error.

    Until version 1.2.26 most errors were interpreted as global errors. Starting with version 1.2.27 many errors which were previously interpreted as global were switched to being local whenever the backend is still busy. Busy means, that other concurrent requests are send to the same backend (successful or not).

    In many cases there is no perfect way of making the decision between local and global error. The load balancer simply doesn't have enough information. In version 1.2.28 you can now tune, how fast the load balancer switches from local error to global error. If a member of a load balancer stays in local error state for too long, the load balancer will escalate it into global error state.

    The time tolerated in local error state is controlled by the load balancer attribute error_escalation_time (in seconds). The default value is half of recover_time, so unless you changed recover_time the default is 30 seconds.

    Using a smaller value for error_escalation_time will make the load balancer react faster to serious errors, but also carries the risk of more often loosing sessions in not so serious situations. You can lower error_escalation_time down to 0 seconds, which means all local errors which are potentially serious are escalated to global errors immediately.

    Note that without good basic error detection the whole escalation procedure is useless. So you should definitely use socket_connect_timeout and activate CPing/CPong with ping_mode and ping_timeout before thinking about also tuning error_escalation_time.

    tomcat-connectors-1.2.41-src/xdocs/common_howto/proxy.xml0000644000000000000020000004265112446106150022055 0ustar rootbin ]> &project; Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Reverse Proxy HowTo Rainer Jung $Date: 2014-12-22 21:26:00 +0000 (Mon, 22 Dec 2014) $

    The Apache module mod_jk and its ISAPI and NSAPI variants connect a web server to a backend (typically Tomcat) using the AJP protocol. The web server receives an HTTP(S) request and the module forwards the request to the backend. This function is usually called a gateway or a proxy, in the context of HTTP it is called a reverse proxy.


    A reverse proxy is not totally transparent to the application on the backend. For instance the host name and port the original client (e.g. browser) needs to talk to belong to the web server and not to the backend, so the reverse proxy talks to a different host name and port. When the application on the backend returns content including self-referential URLs using its own backend address and port, the client will usually not be able to use these URLs.

    Another example is the client IP address, which for the web server is the source IP of the incoming connection, whereas for the backend the connection always comes from the web server. This can be a problem, when the client IP is used by the backend application e.g. for security reasons.


    Most of these problems are automatically handled by the AJP protocol and the AJP connectors of the backend. The AJP protocol transports this communication metadata and the backend connector presents this metadata whenever the application asks for it using Servlet API methods.

    The following list contains the communication metadata handled by AJP and the ServletRequest/HttpServletRequest API calls which can be used to retrieve them:

    • local name: getLocalName(). This is also equal to getServerName(), unless a Host header is contained in the request. In this case the server name is taken from that header.
    • local IP address: getLocalAddr(). The local IP address was initially not supported. It is available when using mod_jk 1.2.41 with Apache or IIS (not for the NSAPI plugin) together with Tomcat version at least 6.0.42, 7.0.55 or 8.0.11. For older versions, getLocalAddr() will incorrectly return the same result as getLocalName(). As a workaround you can forward the local IP address by setting JkEnvVar SERVER_ADDR and then either using request.getAttribute("SERVER_ADDR") instead of getLocalAddr() or wrapping the request using a filter and overriding getLocalAddr() with request.getAttribute("SERVER_ADDR").
    • local port: getLocalPort(). This is also equal to getServerPort(), unless a Host header is contained in the request. In this case the server port is taken from that header if it contains an explicit port, or is equal to the default port of the scheme used.
    • client address: getRemoteAddr()
    • client port: getRemotePort(). The remote port was initially not supported. It is available when using mod_jk 1.2.32 with Apache or IIS (not for the NSAPI plugin) together with Tomcat version at least 5.5.28, 6.0.20 or 7.0.0. For older versions, getRemotePort() will incorrectly return 0 or -1. As a workaround you can forward the remote port by setting JkEnvVar REMOTE_PORT and then either using request.getAttribute("REMOTE_PORT") instead of getRemotePort() or wrapping the request using a filter and overriding getRemotePort() with request.getAttribute("REMOTE_PORT").
    • client host: getRemoteHost()
    • authentication type: getAuthType()
    • remote user: getRemoteUser(), if tomcatAuthentication="false"
    • protocol: getProtocol()
    • HTTP method: getMethod()
    • URI: getRequestURI()
    • HTTPS used: isSecure(), getScheme()
    • query string: getQueryString()
    The following additional SSL-related data will be made available by Apache and forwarded by mod_jk only if you set SSLOptions +StdEnvVars. For the certificate information you also need to set SSLOptions +ExportCertData.
    • SSL cipher: getAttribute(javax.servlet.request.cipher_suite)
    • SSL key size: getAttribute(javax.servlet.request.key_size). Can be disabled using JkOptions -ForwardKeySize.
    • SSL client certificate: getAttribute(javax.servlet.request.X509Certificate). If you want the whole certificate chain, then you need to also set JkOptions ForwardSSLCertChain. It is likely, that in this case you also need to adjust the maximal AJP packet size using the worker attribute max_packet_size.
    • SSL session ID: getAttribute(javax.servlet.request.ssl_session). This is for Tomcat, it has not yet been standardized.


    In some situations this is not enough though. Assume there is another less clever reverse proxy in front of your web server, for instance an HTTP load balancer or similar device which also serves as an SSL accelerator.

    Then you are sure that all your clients use HTTPS, but your web server doesn't know about that. All it can see is requests coming from the accelerator using plain HTTP.

    Another example would be a simple reverse proxy in front of your web server, so that the client IP address that your web server sees is always the IP address of this reverse proxy, and not of the original client. Often such reverse proxies generate an additional HTTP header, like X-Forwareded-for which contains the original client IP address (or a list of IP addresses, if there are more cascading reverse proxies in front). It would be nice, if we could use the content of such a header as the client IP address to pass to the backend.

    So we might need to manipulate some of the data that AJP sends to the backend. When using mod_jk inside Apache httpd you can use several httpd environment variables to let mod_jk know, which data it should forward. These environment variables can be set by the httpd directives SetEnv or SetEnvIf, but also in a very flexible way using mod_rewrite (since httpd 2.x it can not only test against environment variables, but also set them).

    The following list contains all environment variables mod_jk checks, before sending data to the backend:

    • JK_LOCAL_NAME: the local name
    • JK_LOCAL_PORT: the local port
    • JK_REMOTE_HOST: the client host
    • JK_REMOTE_ADDR: the client address
    • JK_AUTH_TYPE: the authentication type
    • JK_REMOTE_USER: the remote user
    • HTTPS: On (case-insensitive) to indicate, that HTTPS is used
    • SSL_CIPHER: the SSL cipher
    • SSL_CIPHER_USEKEYSIZE: the SSL key size
    • SSL_CLIENT_CERT: the SSL client certificate
    • SSL_CLIENT_CERT_CHAIN_: prefix of variable names, containing the client cerificate chain
    • SSL_SESSION_ID: the SSL session ID

    Remember: in general you don't need to set them. The module retrieves the data automatically from the web server. Only in case you want to change this data, you can overwrite it by using these variables.

    Some of these variables might also be used by other web server modules. All variables whose name does not begin with "JK" are set directly by Apache httpd. If you want to change the data, but do not want to negatively influence the behaviour of other modules, you can change the names of all variables mod_jk uses to private ones. For the details see the Apache reference page.

    All variables, that are not SSL-related have only been introduced in version 1.2.27.

    In addition there are two special shortcuts to influence the client IP address that is forwarded. Using JkOptions ForwardLocalAddress you can forward the local IP address of the web server as the client IP address. This can be useful, e.g. when using the Tomcat remote address valve for allowing connections only from registered Apache web servers. Using JkOptions ForwardPhysicalAddress you always forward the physical peer IP address as the client address. By default mod_jk uses the logical address as provided by the web server. For example the module mod_remoteip sets the logical IP address to the client IP forwarded by proxies in the X-Forwarded-For header.


    As an alternative to using the environment variables described in the previous section (which do only exist when using Apache httpd), you can also configure Tomcat to overwrite some of the communications data forwarded by mod_jk. The AJP connector in Tomcat's server.xml allows to set the following properties:

    • proxyName: server name as returned by getServerName()
    • proxyPort: server port as returned by getServerPort()
    • scheme: protocol scheme as returned by getScheme()
    • secure: set to "true", if you wish isSecure() to return "true".
    Remember: in general you don't need to set those. AJP automatically handles all cases where the web server running mod_jk knows the right data.


    Sometimes one want to change path components of the URLs under which an application is available. Especially if a web application is deployed as some context, say /myapp, marketing prefers short URLs, so want the application to be directly available under http://www.mycompany.com/. Although you can deploy the application as the so-called ROOT context, which will be directly available at "/", admins often prefer not to use the ROOT context, e.g. because only one application can be the root context (per host).

    The procedure to change the URLs in the reverse proxy is tedious, because often an application produces self-referential URLs, which then include the path components which you tried to hide to the outside world. Nevertheless, if you absolutely need to do it, here are the steps.

    Case A: You need to make the application available at a simple URL, but it is OK, if users proceed using the more complex URLs, as long as they don't have to type them in. That's the easy case, and if this suffices to you, you're lucky. Use a simply RedirectMatch for Apache httpd:

    RedirectMatch ^/$ http://www.mycompany.com/myapp/

    Your application will then be available under http://www.mycompany.com/, and each visitor will be immediately redirected to the real URL http://www.mycompany.com/myapp/

    Case B: You need to hide path components for all requests going to the application. Here's the recipe for the case, where you want to hide the first path component /myapp. More complex manipulations are left as an exercise to the reader. First the solution for the case of Apache httpd:

    1. Use mod_rewrite to add /myapp to all requests before forwarding to the backend:

    # Don't forget the PT flag! (pass through) RewriteRule ^/(.*) http://www.mycompany.com/myapp/$1 [PT]

    2. Use mod_headers to rewrite any HTTP redirects your application might return. Such redirects typically contain the path components you want to hide, because by the HTTP standard, redirects always need to include the full URL, and your application is not aware of the fact, that your clients talk to it via some shortened URL. An HTTP redirect is done with a special response header named Location. We rewrite the Location headers of our responses:

    # Keep protocol, server and port if present, # but insert our webapp name before the rest of the URL Header edit Location ^([^/]*//[^/]*)?/(.*)$ $1/myapp/$2

    3. Use mod_headers again, to rewrite the paths contained in any cookies, your application might set. Such cookie paths again might contain the path components you want to hide. A cookie is set with the HTTP response header named Set-Cookie. We rewrite the Set-Cookie headers of our responses:

    # Fix the cookie path Header edit Set-Cookie "^(.*; Path=/)(.*)" $1/myapp/$2

    3. Some applications might contain hard coded absolute links. In this case check, whether you find a configuration item for your web framework to configure the base URL. If not, your only chance is to parse all response content bodies and do search and replace. This is fragile and very resource intensive. If you really need to do this, you can use mod_proxy_html, mod_substitute or mod_sed for this task.

    If you are using Microsoft IIS as a web server, the ISAPI plugin provides a way of doing the first step with a builtin feature. You define a mapping file for simple prefix changes like this:

    # Add a context prefix to all requests ... /=/myapp/ # ... or change some prefix ... /oldapp/=/myapp/

    and then put the name of the file in the rewrite_rule_file entry of the registry or your isapi_redirect.properties file. In your uriworkermap.properties file, you still need to map the URLs as they are before rewriting!

    More complex rewrites can be done using the same file, but with regular expressions. A leading tilde sign '~', indicates, that you are using a regular expression:

    # Use a regular expression rewrite ~/oldapps([0-9]*)/=/newapps$1/

    There is no support for Steps 2 (rewriting redirect responses) or 3 (rewriting cookie paths).

    Some types of problems are triggered by the use of encoded URLs (see percent encoding). For the same location there exist a lot of different URLs which are equivalent. The reverse proxy needs to inspect the URL in order to apply its own authentication rules and to decide, to which backend it should send the request (or whether it should handle it itself). Therefore the request URL first is normalized: percent encoded characters are decoded, /./ is replaced by /, /XXX/../ is replaced by / and similar manipulations of the URL are done. After that, the web server might apply rewrite rules to further change the URL in less obvious ways. Finally there is no more way to put the resulting URL in an encoding, which is "similar" to the one which was used for the original URL.

    For historical reasons, there have been several alternatives, how mod_jk and the ISAPI plugin encoded the resulting URL before sending it to the backend. They could be chosen via JkOptions (Apache httpd) or uri_select (ISAPI). None of those historical encodings are recommended, because they have either negative functionality implications or pose a security risk. The default encoding since version 1.2.24 is ForwardURIProxy (Apache httpd) or proxy (ISAPI) and it is strongly recommended to keep the default and remove all old explicit settings.


    You can also add more attributes to any request you are forwarding when using Apache httpd. For this use the JkEnvVar directive (for details see the Apache reference page). Such request attributes can be retrieved on the Tomcat side via request.getAttribute(attributeName). Note that their names will not be listed in request.getAttributeNames()!

    tomcat-connectors-1.2.41-src/xdocs/common_howto/project.xml0000644000000000000020000001150712472604371022345 0ustar rootbin The Apache Tomcat Connectors - Common HowTo The Apache Tomcat Connectors - Common HowTo tomcat-connectors-1.2.41-src/xdocs/style.xsl0000644000000000000020000005573312451224326017341 0ustar rootbin <xsl:value-of select="project/title"/> - <xsl:value-of select="properties/title"/> PAGE HEADERHEADER SEPARATOR LEFT SIDE NAVIGATION RIGHT SIDE MAIN BODYFOOTER SEPARATORPAGE FOOTER
    TOMCAT LOGO {$alt} APACHE LOGO  :: Apache Software Foundation

    Printer Friendly Version
    print-friendly
    version

    Copyright © 1999-2015, Apache Software Foundation

  •         
            
    Attribute Description
    Directive Default Description
    -
    Directive Worker Type Default Description
    ? -
    Directive Successor Default Description
    - -

    /images/add.gif add /images/update.gif update /images/design.gif design /images/docs.gif docs /images/fix.gif fix /images/code.gif code
    Priority Action Item Volunteers

    This paragraph has not been written yet, but you can contribute to it. The original author left a note attached to this TO-DO item:

    [...]
    [user@host] ~ / $
    c:\ / >
    ===>


    tomcat-connectors-1.2.41-src/xdocs/images/0000755000000000000020000000000012555256551016713 5ustar rootbintomcat-connectors-1.2.41-src/xdocs/images/printer.gif0000644000000000000020000000066610147164027021064 0ustar rootbinGIF89a ÄÿÿÿÿÿÞßÞÖ×ÖÎÏÎÎ1ÆÇƵ¶µ¥¦¥œžœ”–”„†„sqscžcacÿ0œÀÀÀ!ù, ÿ $ŽdI.¨©®ê2¦l\º3-³4Õw[ê"C$Ò›‰€$a‘”HØ$HåRÒ”äv#i±:0<Ú×Ë8@±¢ê©/‹áA G†¬ä~rt^ yD"nxz €r…(Š‹# ‰ yo“‡B~ š‹4TAp‡¸ª««‹ˆ¯ ”±””ˆ¹o¼« qÁǸˆoɪšjDÁ’“T‰^Îkp¼ÌŒ í” ÎåçÙC# ë íàûòòÐK6„'ÑŠù/ß< †¨2ØhÂbþ)8oˆ½û—Àa5ï3™Pi1‘Æ’Cò½a¹â c ‘猦Œ!à¼ì è³ÈyrÊ+:EÂK)6]É4F;tomcat-connectors-1.2.41-src/xdocs/images/void.gif0000644000000000000020000000005310147164027020330 0ustar rootbinGIF89a€ÿÿÿÿÿÿ!ù ,L;tomcat-connectors-1.2.41-src/xdocs/images/docs.gif0000644000000000000020000000040510151327516020317 0ustar rootbinGIF89a„ÿÿÿþþþ000ðððààà///111ÀÀÀÏÏÏßßß¿¿¿ÐÐÐýÿþ/10ÎÎÎÞàßÀÀ¾þÿÿ€€€NNN___ááá°°°OOOáßàÿÿý002,Š Ždi–A0ªç(¼p ŸÂ`ß¡Åi ‡àA$&> bX4"Mµ`‘ iƒâ˜è>IŒÁÑìv_’€P6Ó.6ñáF@ࢵњ Bî& Uf}vx…rˆ4lŽxy–˜(Ž ¡-23­³³£³!;tomcat-connectors-1.2.41-src/xdocs/images/design.gif0000644000000000000020000000114010151327516020635 0ustar rootbinGIF89aÆÿÿÿþþþþÿÿ???>>>??=@@@=?>>@?*EVe¹èO¿ÿB±ø?®ö2£é-Ÿæ“Ù‹Ñ ƒÄz²%sšJbòÿÿÿÿý*FT1¢èIaooopno@>?¯¯¯ïïïðîïðððÏÏÏ¿¿¿°°°   «¡ŸÿþÿÍÒÎÂή¿¯®¾±©Â¬‘¥”®®®ÏÑлÀº¡¯¢“­’~ nod|dSkS#}&¾ÐIJϹ¤Í«›Ð¦“Π¿ˆÐ‘u܃¼Á»¡®¤•®™~ ‡m’sk‰q*w/ÁϯÀ°±¿°°¾¯¬Á®ÐÐв®­ÐÎÏÏÏÑ,Å€‚‚ƒƒ†Šƒ…‹Ž’••Ž Š¢¤§©«®Š¼½¾ŽÅÆ !ÂÄ"#$%%&&̃''ÃÅ()*++*,-ØŠ./012345667ç†Ã(89:;<=>>?ê 2 H!Cˆ‘gD  nPA‚$‰’%æ!¢äŒI4M¬]æÄÉ“'"R¦d"Â!¥˜,ɬ4)Ò¤›’lâ;tomcat-connectors-1.2.41-src/xdocs/images/tomcat.gif0000644000000000000020000000402211472000016020643 0ustar rootbinGIF89a’\ÄÿÿÿÒ¦)ýÝu" GB4pl^¨”W‹r+’’‘ÓÓÓóóô³´´Ð´bñÑp¸”.!ù,’\ÿ Ždižhª®bQ(l,›LÁ”P®C@>ú³ pxRŽq ¨!Q¼_´7eZ¯%ÃñHH`e í–%ñν¯úJØn_k”¢í(qæ4:Οbc7}" umƒx?"QU„4 uGŠq[^&UŽ‘¤&†–˜_š[ Z'¡‹¥¶Z®[wX†–¹¸¶ÃD•– _ ʺËÄÕ`mǩПV tu“ÍÖç( GÒÈÐd# õö÷ Í¿–ìä˜CGpÄv@3`´‡“@1`¯‚èR¤¨ ¢ÇcÄU^5¥~tT¹Çxw̵ܜç©ÙÖŠYwQ€ Hçí{¦nÍ›3L8nÿþõñ2?À«äänÁ+:Pðy–Õ¿¹²¹ìˆ‡ÏëîOI5§½Î[ŠpŽWáâÇ/³*÷@ý¿)otî²ülÎe˜à-{a ñ:U0/€tÞ$—ˆYÇ/êàa2åY΃”_¯àóë! ƒ¿ÀDà¸ð@f=@y@JÅ׫èL8‘à €Sª ªª…ëgX´çÍÆP:$Pdá>Ú‰¯`D¤áN cBž%1@€PU‡E)úCH¼" ð'ÿ"îm0c¿¶‰¶ð b,„Ô8·^Ñq°sÙ¯À¶¿8’ñ "ŇF.$fR9Œ£þ8 $P!dü ç2€ÜI}YÙ%á?.J2~`[Ðþæ— ¹ßCœ'?IÈa(¿ Àñ é5ñaƒ•ÛËðÊ‚ è´ÔL†I̘Ü—òãZå FJ“¸ˆº,‘%rä˜`™s“àÅ€ð…]“8rôl6¬#ÛL¢*<Ci~ä(¤™fK0D<†rÍ´†)óè2Á0Àï[d<è‘“•¸¤ž!” ¸Œ‚@_þok£$û<²AôÌ£Pþ9J*gè‚×ÿ’t,·¦*ÛLô!=ü­P…+ 4›ß<`VéÑý4t…ɧA¦£)—2Œ&CM™ŽpÖÁb<Í!|:CJÂѡ˘٠Ypš1|ÁV]+P KóTMâxª@êˆþ³¬:G†á3ÜQt5>+Zcœëê þ鎆ÆmË`jÙZÄÅéÊc(aŒjE»!S¸ÛhøÂz°¨ÆÕ¯JªjNrÔKÕ€ë ŠV'æÑê x}H¯€›oå¥åš*$~C¢2§«’.‹„Ìâk³‹¹HeØ 4‡¢‘HV%m‰ÏH8ÐanU]QÚ[+”³g4ŠNç Ø{IP¶D°Õ=¶[Ù!ØÊ´¶ @!»é¦Ã(…S­"gkZNÎ?ØXËÆ”­ ˜B§{É5»£¹?CÈòŽÐÜûÊ@¸GI«ÿ&ÑË_@“ÀŽ‚÷Äw9Éeò¯}#¼† ‡o„:ÝMw9¬×Q®+ ™Š»4b—ˆ±Œgì?µ¹x½ÂÉIœc”!;tomcat-connectors-1.2.41-src/xdocs/images/code.gif0000644000000000000020000000061210151327516020301 0ustar rootbinGIF89a¥ÿÿÿþþþ000ðððààà///111ÀÀÀVVãssä]]êÏÏÏßßß¿¿¿––Î..ô¢¢ÚŠŠßEEï••êJJôýÿþ/10ÎÎÎddñ||í¸¸ÔÇÇã22øÆÇãÀÀ¾þÿÿ€€ÔKKõ@@退€NNN___ÈÈäûkkÛø««Å°°°OOO°®ç––Ìÿÿý002‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”‘¥”,¯@€pH,‹ÀPy žÐ(ô(X¯‚–P8‡0"‘P, Üp< 7Zm¬†#’³dBHSgxg ~E eh tE† “T—q›o”D–g† ¦F }’ °§B† !g"»±u#$%&' ()*+½N,+-.ÛÓÔH//#+°ÝÞM00RSêððàðA;tomcat-connectors-1.2.41-src/xdocs/images/add.gif0000644000000000000020000000201510151327516020116 0ustar rootbinGIF89açÿÿÿÿþÿþþþÿÿýþÿÿ# ê£aì¥c 4Àn ì£_ÿ¡Iÿ­Uï´r ÿüï5؉Pñ†8ùCÞ˜\Cö¡Qý¡Jÿ­Sý±Yÿ½fôÄ„ ÿüñ1ݘ]ï“@ÿ@ÿžCý¢Iý±[ÿ½dóà æÓµ ÿþô$ ä˜Mÿž>ÿŸAóà õÓ–ûЋðÒ  é£^õ¤Ué²yI+ 8."0000026/%A/ ïЙùщõÑ•î±n÷²díÀ‡>,˜¢×°û ÐÿµØëïЗúÑ‚õÒñÀ~ûÁwìÄ‘ */B—³Û“Âðµ×ò àÇ©5/#äÒ®,-I€†Úžÿ«Êùÿ÷ÿJKšR)£:‰1!zohÅxwì†õ7«»Ô ÿúÿEP*»OÜdÿk2ýwNòhÔ2ÿüÿ FR%³e*ärCß)ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,ò ÀÀƒppÀ€ƒ&dˆ‰ p(£@†0p„(XÀ ÀÈ@ˆP ,\ÀAÃ<|yD#H”0ñàŠ*V°háâà 1d˜øÙaÆ5lÜÀQu :vðèáã B†)’0‚‘#H’(Y¤‰“'P¢HIøa •*V®`É¢e —.Dz òL1c–)c¦ãCgФQ³†M7oàÄ‘3¡EsèÔ±sO={øôé30âÀ~þ $hEQ ,°›7ÆçУG§(@@;tomcat-connectors-1.2.41-src/xdocs/images/jakarta-logo.gif0000644000000000000020000002061010147164027021743 0ustar rootbinGIF89aù0ç:5:[Q,‡{Dß:³«N¿JñÉ[£%·.•#Ñ;Td-ð×\‡*÷T@™5Mðá]~ &æSI÷|J†2Em¡/èàbîîî¶V:NÈ‘v_ "v8:\I’ˆI®¦bK>–T=çÎbÐEöòŠ[]_¶ivŠ•N &‘hk<5¸±[ÚÙÙ:Jf.Y¸xP.--c*]î3t2¡–YbF2}FöööÝBvh7˜Œf= Sö£Q¢,F¶®jÈĈÜ,Tˤ„îæj¢‚IZxY;>¥´ºfed¥:o{ƒÁ=Y6ÊEîÒfúúúL#4Rm>>>c&`Ú$Ako“pQ§šeÝ9Xv6S{oFááà/ IÎvЇGC7$2 DlùhF 08¤*["4” *ʦ¦ÒÒв²°h6M¯o^’~^¼)Qž%DŽ-Oª Rö›WÌixì<Ž":è5R4g‡ a–¤¬TTUºº†•S„ÚÊj––•€[_MXIJJöHAn0ééè¡D3µÄÈþþþi"^®¢jƒ?qË´˜vP‚`lpìxJÎʘb 2‰œ¦‚*Q¥H” \Ö>*0’&R°W~ 2Í(Vö1¹›‘õ4>´®n.UuDvljh¼SQ5W{(9ï»ZK)PrSoèiMvvvò>àÍ˦¦¥³AKN 6’fV¶Œxòòòî~Ftt¯gb0"5h7ie,<‡HgÎ~††|N| f~>F”T[$%a:dÄ»¼¶¶Š·|y€€º¤”ÐÌÆ†1p a` N{c_ô$>u¢`…††n[Arrr¬®¯?TiDvhú‹KïµTX"b AP&&&μ}ù3žžê)Ju*UY8e¾J„$`!þ+Thanks to Brian.Ewins@i-documentsystems.com,ù0þ H° Áå4\Ȱ¡Ã‡#JœH±¢Å‹3jÜȱ£Ç CŠôè…ÍÈ“(Sª\ɲ¥Ë—0c†œá¥¢—‰^¤xL¦ÏŸ@ƒ J´¨LCePô”¨¤'"ikñ1Ó‹…TOª‹ÆuiVƒÇ¸FS÷µ,A b£a5›Ò‹KâElR.Qº=kí¨¡¾VjîyÑH >¶«(^¼8QÑ@–cìÊècº¥dر¡ŠÝ0¨ÂRÃM/³@Žê¬˜O4“'_ˆPS¤¡7S›%3ŸÊ _¨P²&ŠgJö&²U @Œ5ê©Ñ©1@øð½X‹xàìïRþù]ˆeÑšQ†þŽ'Åõ£YŽBò2{ÑÀCz™í>¤ýôl€oêHÁÐ]å ¢Ä#*çÉP³CsÈàa!¡pÓ 7ÜÒŠWÝI!☉hàc‘é¤CA/Äó‚ÉöÝgDý—|ßÕ6|¤­4fvdß}˜‘’!£D“$wÙØ]<½a&@1º´F<“ìÍ#{4ˆ@ùÔ…PœC—\’F…Ôa u0AŒ,E胈_ýHÐcU "^ (Zý8[]5Ò‡’!é4Š#¡ñÈR4Šzd_ÝtSŽ ¢UÙÝž•v·Š¢Í ñÁÇ$“ðÑ¥4þ‰¬áÌpØp@þ@Å `áWàQidÃ+ô|‚9àüUVztÙ(Ï`¶D":”À‹®@D÷™gÐ,äêfˆ4ÝÄ#A³\éJ7ÒăêAƒn:k¬ëä ®¸¢£A%M9鬑³ýÛn<ïÆ;¯@’T.¹éÐ"º®¤ó°@W<‹ð!Z1»"_Ǥó.Ç0É}Uˆ(P9³×±ÄëŽÀ«Hóo"R[².'ðÀ3dÃݤS›Ì0rÉw²¶˜€‚rR ‡ (LÂe"­XbIöÌf=ÈQf—ÜÑ\dƒGuܸÉÌþ†Ü0ã‰\FQ ¨ã%B"iêp­†`öóAñˆ¦Íl§3›"óG‘g"† 9²@ÿy1¹hBœÜáÇyDÒÌ+ Žttƒ…=bƒÒ·­ì²—¿þÍÉ 'š2¬¤ŠÆ1†”MÅ®ŒFÄ40½¨  M€£0‡q a½èE)̦¿P$cš`ÄÎAÒ Àá—hÎ%žêàáá  °9}N>Á“ÖQÁD„æ[«ë¤AB¨ lÑp cÔè9HÙe6a¡<ņ2àRÏz”@PXñP4^¡htäÔ1DR€ÐÜ ƒ :ÊUó;KXB Õ ™½Ð ‰[¡C˜ˆ­!ш=ƒÅ\áDÌø®‹õ”ÞQ¹Vž‚Õ¨Õ[—žÅÿØ¡y X¨>Ì@€ˆ#¨„~Œ£É…ðh ]° µi8þ€l ÿ銂ôÕž€V0C$G8Žeã¦'™¤Nu) ¨ Å膟ŠFp‡…Å ˆY²·jc4PãD¸åá²}³Ù ¹9̬â`j5È«EXÊR4ÊYÈ,ë :uwÝ+ˆ ÁUjŽS}\áƒ)wˆNÌ– íÍé@¤†™ƒ6±ë…°hÞ+Ù¸ìdNÂ,½VAáÙ`ÒpÅhWÌyà"m6z! ~¤müØ#Û@R”é PduaÕ 6¸‡*È LÄB N I³ÓžbkÖkóþ$¼zK»P­Øl¼âWˆN4Égþ‰\Å@.æ\92LÚ¤ÌU0¥h`Ÿifw\lãß*a‚Ðõ ^°%‘öŠÄ¬å¨ñ² R-ÌU±cai8ÑLšÍq»Qâ~Î`óà@8ð jø`ãÀB°Œ`°Öΰ%ô7‡9|@¶P8@ Sƒ¼ÂWG&‡² ì­oàÈ ¹„:TÊ•LÍvÈv1™½‘sÂQCBEü&¢Îr†¯ìB=öœ•H¨,HUKØßËÀ¹à¢Ç]ÂA,¾ìbAÄÍíz¢»|T'¿£'ê³Ä¥Äâ>`Às`ޏ8.2ŠGFô‚µg›ÕþΠ Røªw@išLq7V¼ãw«A x¢­ˆ²YôM$D=ÍMœ\¼<šn¤ÌÞ_¹Ó{îÙð!IPWÒX"‚ØÚ½ ®8úžë+BòZi6BD<ªNh:TF#Ë: t6F1ƒpÅÆžˆUˆæZ¶ ³¦eWgD=êd±O¼•ŽvQ»¢{pÅ#š°Y!,!ÚÐs禱TØàÀP ãf‚Ö§G™p‡ÇaþcyuÀ‰A~€2…À!îñŠW8¡jhµ‹²åF#UïMÏôTgDlÃüæ½;N#þÈóS|®—AT,úÀþéBæ×{ëÁ·˜Eã 2–»wóÏà3ƒ‚ðŸv¾/ÉØÝÒ osÃW÷Œ%¨à¡(Ѓ0†0 y ’·û0«¦j‡ã ßpZÉ Ô`ÇÁ0Âc{t¡²Çv ` ¬€,¹p—PÕ‘d2 ‹° ÆÐ 9W€DQ`%TÛ–26Õ7 5cî±tæ–Tô^ôï—DÁ‡kQg|FN91Vnݶ9™v…mwv˜Z/|æ—svt×]à'%æsæTôAñÇ÷8µab¸/° ¬òªòÐ;a Xà4þ˜ gep óðýPq7߉H@ ãPò #W¹ÀQp)… +À.øð`d5` $  ` að D,è S¿¹w ê`ƒååéc=&4‡¢mzD¨Ô{]5Ø#à^!Ðs^\ˆ€3F¯BjÝ wûõ„Ô„Œa…mïÆiuwT,Ä„mµn@$Tß&0"ˆåIGxäØfO£CŒ\VpàHý€Gö` Ê€GzÀD6PþGVmÀ )Ui`Ë€@vp´Çµx¾ PÖ ɇD¸Aa(VõsœSºÁY ¥0ò”¢‘M%&n¦¢3U0XjíV)X©•àÁu=‚Œí—ÄÑ :µQ†£ÔOU 1óÅYfw|Åt—l·BÑ@Oâ$ýQ–U@Eéq|Ó— ‡˜³Q}y†la+ñ ®¢(Ð%5¡Ð ³b ŒÐ Í@ òÓ yB €¬Vqщ_à§SP½ gÀ6õ€»Æ‚„¦àe6ð“ÜÃvd°ŠN€7}sáþP‹°‚¶·»Ð£Dñƒq|81F÷Ñ÷˜À‡Xî–pú§…Í':°•ßjDtwëÒž³¡o㑘씳 yúö}kf ŠFÀG˜Vè÷8ÞètCsE®3Ú<IFÕ ^`JP  2 **npùp¤Prà –àY Ô€ ûР ó  8Z—X >ÀHP ‚¼– ¯Åbr&à |tæ`Ôaœxp9`.Xrà ¬@p‚÷ ddPúÐ#‘>œyau1FlÀBP9`w ãUh@Ó *{„þ[¨]gVÏà)qÉÔ‹ú¸B|jo>5¡@CO a,T•qTzY³@D=R`3 Ij…¹‡ù;‚™Œñ†!épfð ÁdÅ g( #Ÿ ˜˜õV¡¢“ð&: 4’xpÓ L¤0sÀ,€£µ€ y0>Ó00Ѐã hkfã ÁP Éà’²»6+À ‚¹àceò 6ŠGÆÈ'$çЮü°}ó ²'YžP‘ s,±]³ M)·±F±_ª¨Á87a ûªDS2éÇ8š~ñ° R2³3;†2c·þ}šmvš±ç¦IëI&;²l±k€²{Ô5P@à?cpõ  ¢àš4P Õ Š0¥@$e°Óµ¬6 ÕÀq¤…S6s`cÀZÙ H—@š [p¶’&p#ï   õ@RàrPx÷ Sd@@c°¸á=¸Žû¸Qi˜A±;X2Ä!­PD[™`!p$Œ­VµÔµH€ ²é£˜¡€X‹É ø ŒÀQTP µÐ ü0¤˜ b« ›pº¢+ p¾`lÙÂÒ Ì@W@èþP‹¹` –ðÈ Y@×° /ð@)Ѹ•{¾èk93ÀYs‰¾("ÇàÇ0´/ˆ¥50xÐŒà Îð´ÕàP[ ¢À ˜ˆœ¥pj>0 X°Zz —84p²ÅfS‘,Ðk|t=¦+¦  éʉ'•Rc w³!Ÿð›½ÀQm mÚ°G–ÄP¾¥ê¾8Üpêù|9¼Ï"¶`qPgðÕqG†ÿàš ¨ÀÀ:ú‘˜àºêƒ ¨€ ºicÕ r  e…à :†Œ°Z–Pº°¶erâ‚[@qsôq¹{hà¹edL@]þa¾=<ÈŸ¢žBP„ŒÄ@¬ !pP¯à‚z@ þðPÅ:*ÅÿÀ‚ ó`ÀÐh¬‹µ¬… ²[ /Ö›æ  úc¨ð´0°½l“ p RÞ0 “8ã` và[¹Àº’Räpnà5øÃ5DC¹‰Í_1 2 ÍÒ씇€ôpÕA p¢œ`µ`6k|‘¢°»º[  µþ;Õ€ ó0 ‰DÚàf¯6 IZVð<4ð€ò  (i\à»p› ¼ ‰` p2!¼Œp¸@ Ö` ûÐjð¦Ú4%ŠÈ×<Ò$]Òq dþ÷ Í.ç‚™°ÕàÀõÐkü­–ÀÍpÎP‹ ® ®Ù ,4 €¡ŒDÀp hÓ Õ@GÁy¬¢c+Üì?6ГXq>` Äö›¬ÕcÀ Ÿ ,3• ÷ð5À Ö Äpíp Q '€°&×z½×E0„pôÀ àDÀ ,P™`çÉsà ¸v»6êZzÀæ0ö€É\[ ó`óУ›æ-J} Zûóy² ·;rJk T’à¡°¯€ œ¹°7|ó[°Ñ[¾ $À?ð×p ] CC Ò|þ=ÝÔmÒ†° ´Pù  „à ÷ðàù[a2£õ0Áv~ÀÙö& Π] 0 Ó,@Êpˆû VÌJjf@Xà»fi@ !9‰æðcS‰ã0i°H¦Pzô$LVJÙ7p•!Ý'QŽz[²*è8T/¾ê`$ Ñ˜#aÍî‹âîÛ8)@ Y¸Œ°d‘Ü cPà68ÍqcP¤ÀÞ*έ®•ß6 ,PåëlŠ  Ø fðß÷!¥`X; ¯6;6H‰¸°Èvd‚ÀÍk&‡pÊR‹þá âP7•`ë`= A`k@žQù¥t~Vœ Ú€°U€\ñõ›.–sÍŽî¾lÐé(a ìP±P~Ps°Õq þ`—p9@@ ¯9@lO¾´T>~°´šcö XP Õ  Ðßµ0@1@· ÔG]ÚÞ2¹0¥Ø0  (Õ Љ7F ¹`Ø¿)€â è°FÀ 7à < ³ê{é3é$1•*ð#Ñ 6Ÿ.Íú~¾BÀÌ*q  à @ô@ v !LÞ '5Š&ð@ð‚ðJ ›þü°cçM ÿ€kŠÐksÀÓÕº`£¸€ Iêf ðŒ bp o±ª¼£ Øž 90Ê0xDwpÂÕ±Gp À• ë°)ÐQÀ •Ðîëpk)ép Rãs¡šÉÁôhÙ :@3Àð<÷ á x9y¿:À2tBK ÅДo4Å0U€t-‘á«À€"¯aÝ€}bö‘£ ø«@¹^ ³ A(ú‰¿ø¿UŠ*¦:öR“…`á'so(âìÆ°Ïð9RPe ® õG„4‹À@„€@þps3ÄÕ¬Íñ&Õ±·Í1³^z& š +¡À¶9 ´ª¹å,ð¸ ?\Ð< xôÓ ›0€ V@¨€ Ñ~  y™)S@Aî ²'8xœÇ£„„8… „¸ Tª´H /‰<~R$È*Bø¬I€È5BF¥‹'¤BÒ¥3R!Ý^Sd7³Fz¬òâh¢Aé–z”’ŽO´‘(Ò½XƒbÆÈnT¡4Rš´c/\¹s”€hB=êàfGR^¾8VÅÓ‘«Ø¬y1*ÀÈtf\4X䨲gÝ‚¤-Þšr«D–äó¢°º‘êf¼þЯ̾!©œ/ÀJ‘F¹Œw¹ àrr¦[RZ÷î£^NÑqC‚$FjÔȆî½pðàyÇ„«ÏñdsžÊ¥KÎ3‘¦@& @isà@=Ršø±ç£Y³qh,9K–‡Ã~0šYP™<¾á€š/QfTæÙgLn1˜2 °Â2„pgàÁ#@ ‹v@ñ."‡\ám)8óH°.‹«*ŽÚÉ(¤, I CÒ‘i$R$)ˆÔ­›Qø2¤¨¡–Œ†Ýfè&-j)tk²È9R©ÒÑæ#)ÊÀò(*EbÌéÅQþ ¤!uLDy‚ENóÒ#ž9Š:¹ò(>Òü²Ñ¥|\C˜7®ùá‡Åœ36G¥–^zQ†zQ*¹šº€fÛ1ìâˆ.Ä a‘­ú_ƒ?ª‚Q¨ºþ£ŠºÅE—…5‰½¸ ¿ÎÒ`(ž¶:ê¬%؈§'+?þ7é… 6Î")ˆ†6ŸÚàh¨ÿÈ{ðŘ䥂ODó4€hŒ¢€÷ãþ&(‚Y~$ñ¢Œ—ˆý΂K9†8@CFp@ ôVƒy!àÐÛª:Ñ ¸ÕàÈ0Ž& 7~8q¨Ž©:Nàä¸Äs®°‰ñ4à§ëE3`xîРzÀÎC,tËɰÁvEŽÿØÃ8¨ˆ½@t„DÁ#BÀ) á€ÜÀƒ†Bð»âÕo$ òpd>C}éHíKD󔉩 AÊÑP<6ƒÜ© Ò«B=²“™$€˜"-É— LQ Í>±=’x’üJ9~F0&¬Lüê’™@šàDÕØ—^З#yÁ "þ‰7°ª<¨ÄM±B ŒpÇŽƒŽ;0C¡¸T €p½­ÐDhÕŒS&\¡UÊ`%œ•.êÌÅÆamn68ÇxLð„9Ô£¦àEP¸ ë@ XG±¯­P”u©‚4F"…npo|¸¼Y]2’¼,åà’ ¦<d/TÙ *wâRàÉtcÚ¤G8É›60I S(v$FÍô”"Ä+ÿ‡¥V&¢“#É,ÞÔ#PÔ©-mÔ@" !@m‚e é/Åú|AÂèZ°_ЃÌ0ÅÙ±ƒ* £òŧìþº®0p7M•¬šðg=<`‡nâáõ8@.Æ™œgq Àƒ©Î-î ÁB€Jdà ACê‚!XТÉKD4¡ƒ©’4jR¨-OÓ¡)«Úƒj"^=?% MG4À'½´|V…J[ßÚt)MÚWnÑ !dÏUÈi'§@ÒÀ”c À ¤0 (ÕLÒ¥.P9‹2ŒÂ(^(.ñX™Ó* 'Rx*©z\¸¢»‰˜Å –Ôš[B%|Hw¯’Àv¬6©!z PÁ^Ü!³5„h tó‡@:èñŠþ\ÊgëÄâ`V –m3¸1d˜b;¦è&,Ïñx€Cf9¶p7Sˆ#E@%Bà ð` Èx‘­ò«ŽÂ’6(V¬‚BùMÄNÑ®Ajì·!)ƒvAR†2/¥u‰ ´½'}de©j(ÔQ›R ©GA¡*´écì¥Gž1¡GÚ2K˜4ª\EËwM"ñxP†L[4§‰ …é#-X$¦ÕçIcmITHÊ¡Q ›7î>ñ†]„:±8Bòcz„a8d8DÞj`xL‡䈱[õÃÂÜágÈñ vþ¯HÃs ˆ*H@fñ€LÜ Øri+‰nרuyÔÇ–§5/xÕ‡*Í3t`ƒ·H ¤n¤Ð¾YT¼4:ðx<ª°q¾\<ã“Ôs£Ö{òGi å~ôtH´Qçƒ×üKÁlE$ޱ†n£N‡) Í:>>??=@@@=?>>@?*EVe¹èO¿ÿB±ø?®ö2£é-Ÿæ“Ù‹Ñ ƒÄz²%sšJbòÿÿÿÿý*FT1¢èIaooopno@>?¯¯¯ïïïðîïðððÏÏÏ¿¿¿°°°    ÿþÿÍÒÎÂή¿¯®¾±©Â¬2 ›Ä¢5E:®®®ÏÑлÀº¡¯¢“­’~ nod|d$,#}&Y¿\/t1 /%¾ÐIJϹ¤Í«›Ð¦“Π¿7ˆÐ‘u܃XÊjtÜ…”Þ¡*¼Á»¡®¤•®™~ ‡m’sk‰q$**w/؆4q5 / ÁϯÀ°±¿°°¾¯¬Á® -¯ÍµÐÐв®­«¡Ÿ#ÐÎÏÏÏÑÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,Ø€‚‚ƒƒ†Šƒ…‹Ž’••Ž Š¢¤§©«®Š¼½¾ŽÅÆ !ÂÄ"#$%Ô&Öƒ''ÃÅ()*++*,-./‰†0123456789:;<=>é(?@ABCˆ1rI%K XǤ‰“'P¢H™B¥Š•+ùqû€K–,Z¶péâE Dˆ(9û͘0aÄ\S4`Ì2dDèÔùEÄa0YZiR¤IH%M:(;tomcat-connectors-1.2.41-src/xdocs/images/fix.gif0000644000000000000020000000053110151327516020155 0ustar rootbinGIF89a¥ÿÿÿþþþŸŸŸ€€€ÀÀÀ°°° OOOÁÁÁŒ{s¢t\ŒN7J<ÿûûÿÿý€¯±°,B“K2ÿ¯¦S .þÿÿþþü3–J2ÿ®—QÿûúÿûôC“K5Q 0ÿ¯˜Qÿûó“K3R R>‰O9è¼±3ÿüûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ,~@€ȤrY\2KÁ`*… „BÁ@8 ’M‘H¦NÅ`‘eœŸƒCQh8ˆ$9™`)FCX^B !"K#$C%&'()FaJ‘*+zVB,&-. ¨*/0–Vª1234°B¾ÂþA;tomcat-connectors-1.2.41-src/xdocs/news/0000755000000000000020000000000012555256551016422 5ustar rootbintomcat-connectors-1.2.41-src/xdocs/news/20041100.xml0000644000000000000020000001371510666607673020050 0ustar rootbin ]> &project; Apache Jakarta Project 2004 News and Status

    17 December - JK-1.2.8 released

    The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.8.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    17 December - JK-1.2.8-rc-1 released

    The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.8-rc-1 (Relase Canditate 1).

    We expect it to be ratified as a Stable release when the vote takes place in the next week.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    13 December - JK-1.2.7-beta-3 released

    The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.7-beta-3. The release contains a fix to few configuration problems detected with JK-1.2.7-beta-2 version.

    We expect it to be ratified as a Stable release when the vote takes place in the next week.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    7 December - JK-1.2.7-beta-2 released

    The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.7-beta-2. The release contains a fix to few compilation problems detected with JK-1.2.7-beta version. This release also introduces a new domain concept clustering support. See 32317 for details.

    We expect it to be ratified as a Stable release when the vote takes place in the next two weeks.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    30 November - JK-1.2.7-beta released

    The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.7-beta. The release contains a significant number of bug fixes and new features.

    We expect it to be ratified as a Stable release when the vote takes place in the next two weeks.

    Please see the ChangeLog for a full list of changes.

    Since release 1.2.7 the socket_timeout property has been renamed to recycle_timeout. The socket_timeout now sets the real timeout for socket operations.

    If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    15 November - JK2 is officially unsupported

    JK2 has been put in maintainer mode and no further development will take place. The reason for shutting down JK2 development was the lack of developers interest. Other reason was lack of users interest in adopting JK2, caused by configuration complexity when compared to JK.

    The latest official JK2 release is 2.0.4.

    JK2 will have it's successor within core Apache2.1/2.2 distribution. We have developed new proxy_ajp that is an addition to the mod_proxy and uses Tomcat's AJP protocol stack. It is developped in httpd-2.1 and integrated in it. We have also developed a new proxy_balancer module for load balancing http and ajp protocol stacks.

    JK will be fully supported for all other web servers. The next JK release is planned for the end of November. Lots of code from JK2 has been ported to JK


    tomcat-connectors-1.2.41-src/xdocs/news/20120301.xml0000644000000000000020000001031711761651572020036 0ustar rootbin ]> &project; Apache Tomcat Connectors Project 2012 News and Status


    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.37. This is a stable release concentrating mainly on bug fixes.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.36. This is a stable release concentrating mainly on bug fixes.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.35. This is a stable release concentrating mainly on bug fixes.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


    The Apache Tomcat team wishes to draw your attention to stability issues that have been identified with the recent mod_jk 1.2.33 release. If you have not yet upgraded to mod_jk 1.2.33 we recommend that you wait for the mod_jk 1.2.34 release which is currently in progress. If you have upgraded and are experienced issues we recommend that you downgrade to mod_jk 1.2.32 until mod_jk 1.2.34 is available.

    We apologise for any inconvenience.


    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.33. This is a stable release concentrating mainly on some bug fixes.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

    tomcat-connectors-1.2.41-src/xdocs/news/20100101.xml0000644000000000000020000000613511463441605020026 0ustar rootbin ]> &project; Apache Tomcat Connectors Project 2010 News and Status


    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.31. This is a stable release concentrating mainly on some bug fixes.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report.



    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.30. This is a stable release concentrating mainly on some bug fixes.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report.



    Tomcat Connectors 1.2.29 has been withdrawn because of regression inside Microsoft IIS connector.



    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.29. This is a stable release concentrating mainly on some bug fixes.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

    tomcat-connectors-1.2.41-src/xdocs/news/20050101.xml0000644000000000000020000001457410666607673020055 0ustar rootbin ]> &project; Apache Jakarta Project 2005 News and Status

    8 November - JK-1.2.15 released

    The Apache Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.15. This is Stable release and it contains few bug fixes found in 1.2.14 version.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    13 July - JK-1.2.14 released

    The Apache Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.14. This is Stable release and it contains few bug fixes found in 1.2.13 version.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    7 May - JK-1.2.13 released

    The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.13. This is development release and contains few bug fixes found in 1.2.12 version.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    7 May - JK-1.2.12 released

    The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.12 The release contains a significant number of bug fixes and new features.

    We expect it to be ratified as a Stable release when the vote takes place in the next week.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    29 April - JK-1.2.11 released

    The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.11 The release contains a significant number of bug fixes and new features.

    This version has not been released.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    30 March - JK-1.2.10 released

    The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.10 The release contains a significant number of bug fixes and new features.

    We expect it to be ratified as a Stable release when the vote takes place in the next two weeks.

    Please see the ChangeLog for a full list of changes.

    Since release 1.2.10 the JkShmFile property has been added for Apache 1.3.x and Apache 2.x web servers on UNIX and LINUX platforms. Load balancer will not work properly if this directive is not present.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    18 March - JK-1.2.9-beta released

    The Apache Jakarta Tomcat team is proud to announce the immediate availability of Jakarta Tomcat Connectors 1.2.9-beta. The release contains a significant number of bug fixes and new features.

    We expect it to be ratified as a Stable release when the vote takes place in the next two weeks.

    Please see the ChangeLog for a full list of changes.

    Since release 1.2.9 the JkShmFile property has been added for Apache 1.3.x and Apache 2.x web servers on UNIX and LINUX platforms. Load balancer will not work properly if this directive is not present.

    If you find any bugs during testing this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    tomcat-connectors-1.2.41-src/xdocs/news/20150101.xml0000644000000000000020000000354112555241127020031 0ustar rootbin ]> &project; Apache Tomcat Connectors Project 2015 News & Status

    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.41. This is a maintenance and security release.

    This release includes the fix for CVE-2014-8111.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

    tomcat-connectors-1.2.41-src/xdocs/news/20090301.xml0000644000000000000020000000670112472575314020045 0ustar rootbin ]> &project; Apache Tomcat Connectors Project 2009 News and Status


    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.28. This is a stable release concentrating mainly on some bug fixes.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

    The most important new features in this version are:

    Better Error Detection for Load Balancer Workers

    Local and global error states have been improved. You can fine tune the behaviour with the new "error_escalation_time" attribute (see the timeouts documentation).

    Dynamic Address and Port Change Using the Status Worker

    The status worker now allows you to change the address and the port of an AJP13 worker on the fly. You can e.g. provision dummy workers with a port equal to "0", which will be automatically put into stopped mode during startup. Later, when you want to actually use these workers, you set their address and port to the final values.

    Note that already existing connections will go on using the old address and port. This will be improved in future versions.

    New Data in Status Worker Display

    The status worker display now also contains the timestamp of the last worker errors.

    Improved Proxy Flexibility

    You can now overwrite more request metadata before the request gets send to the backend. This is helpful in case there are other reverse proxies in front of your web server. A new documentation page explains this in detail.

    Improved IIS Support

    IIS support has been improved especially when using mutltiple application pools. Furthermore you can now configure the ISAPI plugin to update the uriworkermap.properies file on a regular interval using the watchdog thread.

    JNI Worker Deprecation

    Workers of type jni are broken since a long time. Since there is no more use for them, they have been deprecated now, and will be removed in a future release.

    tomcat-connectors-1.2.41-src/xdocs/news/20110701.xml0000644000000000000020000000341511603132336020025 0ustar rootbin ]> &project; Apache Tomcat Connectors Project 2011 News and Status


    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.32. This is a stable release concentrating mainly on some bug fixes.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

    tomcat-connectors-1.2.41-src/xdocs/news/20060101.xml0000644000000000000020000000770710666607673020056 0ustar rootbin ]> &project; Apache Tomcat Connectors Project 2006 News and Status

    10 December - JK-1.2.20 released

    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.20. This is a stable release adding new features and a few bug fixes to version 1.2.19. Furthermore the documentation has been reorganised.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    17 September - JK-1.2.19 released

    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.19. This is a stable release adding some features and a few bug fixes to version 1.2.18. Furthermore the non-functional code trees for isapi and domino have been removed.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    13 July - JK-1.2.18 released

    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.18. This is a stable release adding a few bug fixes to the not released 1.2.17 version.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    JK-1.2.17 not released

    Version 1.2.17 of Tomcat Connectors 1.2.17 has not been released due to a bug in the types chosen for socket arguments.

    Please see the ChangeLog for a full list of changes.


    JK-1.2.16 not released

    Version 1.2.16 of Tomcat Connectors 1.2.16 has not been released due to a bug in the jk status worker. This version adds some features and a few bug fixes to the 1.2.15 version. Furthermore some worker attributes have been deprecated.

    Please see the ChangeLog for a full list of changes.


    tomcat-connectors-1.2.41-src/xdocs/news/20081001.xml0000644000000000000020000001716311101703650020026 0ustar rootbin ]> &project; Apache Tomcat Connectors Project 2008 News and Status


    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.27. This is a stable release adding lots of new features and some bug fixes.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

    The most important new features in this version are:

    Watchdog Thread for Periodic Tasks

    The connector has to run some periodic tasks independant of request processing. Examples are probing or closing down idle backend connections, adjusting load numbers and recovering workers from error state.

    Before version 1.2.27 these tasks were done inside the request processing loop. When a new request came in and the task was due, the thread handling the request first executed the internal task and then handled the request. If there were no requests coming in, the tasks would not run. If any of the tasks took unexpectedly long, the response time of the request waiting for the finishing of the task went up.

    Starting with this release you can configure a separate watchdog thread inside the web server to run all those tasks independantly of request processing. This new feature is avaliable for the connector when used with Apache httpd 2.x or with Microsoft IIS. To keep the behaviour of the new version consistent with previous releases, this feature is turned off by default. You can activate the watchdog thread via JkWatchdogInterval for Apache or watchdog_interval for IIS.

    Connection Probing

    In previous releases connection probing (checking whether connections still work) could only be done immediately after a new connection was established and directly before sending each request. Since we now have the watchdog thread available, we also added a periodic probing option, which you can activate with the worker attribute ping_mode. This will also be useful as a protection against the infamous firewall idle connection drop.

    The older attributes connect_timeout and prepost_timeout still exist and work the same way they did in previous releases. Since there are now three different probing options, we recommend to migrate your configuration to the newer attributes ping_mode, ping_timeout and connection_ping_interval.

    Mount Extensions

    Usually one defines workers and mounts for the connector. A worker defines a backend we want to talk to and the configuration parameters of the communication, connection pools etc. The mounts define which URIs we want to forward to which worker (so we also call a mount an URI map rule). In version 1.2.27 you can overwrite certain worker parameter per mount.

    One easy to understand example is reply timeouts. Until this release you had to specify a reply timeout for the whole worker. But reply times depend a lot on the type of request. So normally you want to define a general reply timeout and for some special URLs you need to relax the reply timeout, because you know those URLs take much longer to process (like e.g. reporting or other compute intensive tasks).

    Another possible case is the activation status. You might use a load balancer worker to forward requests to certain webapps in a farm of Tomcat nodes. If you wanted to update some webapp on one node, you previously had to stop forwarding requests for all webapps on this Tomcat node. What was not possible until now, was stopping forwarding requests restricted to the webapp and the node you wanted to update.

    Starting with this release, you can add so-called rule extensions to your uriworkermap file to influence worker parameters per mount. This will work for all Apache versions and for IIS. Remember, that the uriworkermap file automatically gets reloaded after changes without web server restart.

    Improved IIS support

    We improved IIS support im various ways. It is now possible to use multiple IIS 6 application pools with the ISAPI redirector.

    Furthermore some improvements were added as compile time features. The most notable one is chunked encoding support, which was a major refactoring and is therefore still considered experimental. You can download binaries with and without chunked encoding support. In future versions, chunked encoding will likely be availabe in all builds.

    Another new feature is an elegant way of configuring error page redirects. All new features are documented on the documentation page about configuring IIS.

    Enhanced Status Worker

    The status worker now can also manage and show statistics for AJP workers that are not part of a load balancer. Other improvements are the new dump action, the integration of the new configuration attributes, showing average request and transfer rates since the last statistics reset and the ability to display only a single member of a load balancer.

    Unfortunately we had to change some request parameters used for the update action of the status worker.

    Miscellaneous Improvements

    Further enhancements are:

    • Configurable session stickyness indicator: cookie name and URL path parameter name can be freely chosen instead of the servlet spec compliant JSESSIONID and ;jsessionid.
    • Automatically determining the size of the shared memory segment needed to accommodate all workers.
    • New connection establishment timeout socket_connect_timeout.
    • New timeout connection_acquire_timeout for acquiring a free connection from the pool.
    • Improved retry handling by adjusting the meaning of the attribute retries for AJP workers and for load balancers and by adding the new retry_interval.
    • Allowing the web server to provide error pages instead of Tomcat.

    tomcat-connectors-1.2.41-src/xdocs/news/20140201.xml0000644000000000000020000000477612323146623020042 0ustar rootbin ]> &project; Apache Tomcat Connectors Project 2014 News and Status


    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.40. This is a stable release concentrating mainly on bug fixes.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report.


    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.39. This is a stable release containing both bug fixes and few new features like IPV6 support. Note that version 1.2.38 was not released due to some minor issues found in release process.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report.

    tomcat-connectors-1.2.41-src/xdocs/news/20070301.xml0000644000000000000020000001110310732760345020030 0ustar rootbin ]> &project; Apache Tomcat Connectors Project 2007 News and Status

    21 December - JK-1.2.26 released

    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.26. This is a stable release adding few new features and some bug fixes.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    7 August - JK-1.2.25 released

    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.25. This is a stable release adding new features and a few bug fixes.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    27 July - JK-1.2.24 released

    This release has been withdrawn.


    18 May - JK-1.2.23 released

    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.23. This is a stable release adding new features and a few bug fixes to version 1.2.23.

    It fixes an Important vulnerability.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    17 April - JK-1.2.22 released

    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.22. This is a stable release adding new features and a few bug fixes to version 1.2.22.

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    1 March - JK-1.2.21 released

    The Apache Tomcat team is proud to announce the immediate availability of Tomcat Connectors 1.2.21. This is a stable release adding new features and a few bug fixes to version 1.2.20.

    It fixes a Critical vulnerability introduced in version 1.2.19

    Please see the ChangeLog for a full list of changes.

    If you find any bugs while using this release, please fill in the Bugzilla Bug Report. When entering bug select Native:JK Component.


    tomcat-connectors-1.2.41-src/xdocs/news/project.xml0000644000000000000020000001145712472604371020615 0ustar rootbin The Apache Tomcat Connectors - News The Apache Tomcat Connectors - News tomcat-connectors-1.2.41-src/xdocs/empty.xml0000644000000000000020000000247310516516102017316 0ustar rootbin ]> &project; Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Empty template Developer Name $Date: 2006-10-21 23:16:34 +0100 (Sat, 21 Oct 2006) $

    This is a generic template for JK documentation. Please fill in the url and title tags, as well as author tags.

    tomcat-connectors-1.2.41-src/xdocs/project.xml0000644000000000000020000001147012555242253017633 0ustar rootbin The Apache Tomcat Connectors / mod_jk - ISAPI redirector - NSAPI redirector The Apache Tomcat Connectors tomcat-connectors-1.2.41-src/xdocs/webserver_howto/0000755000000000000020000000000012555256551020672 5ustar rootbintomcat-connectors-1.2.41-src/xdocs/webserver_howto/nes.xml0000644000000000000020000004006712472575314022207 0ustar rootbin ]> &project; Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. SunOne -- Netscape/iPlanet HowTo Henri Gomez Jim Jagielski Gal Shachor Mladen Turk $Date: 2015-02-23 10:02:52 +0000 (Mon, 23 Feb 2015) $

    This document explains how to set up Sun ONE Web Server previously known as Netscape web servers to cooperate with Tomcat.

    Normally the Sun ONE Web Servers come with their own Servlet engine, but you can also configure them to send servlet and JSP requests to Tomcat using the NSAPI redirector plugin.

    It is recommended that you also read the Workers HowTo document to learn how to setup the working entities between your web server and Tomcat Engines.

    ${tomcat_home} is the root directory of tomcat. Your Tomcat installation should have the following subdirectories:

    • ${tomcat_home}\conf - Where you can place various configuration files
    • ${tomcat_home}\webapps - Containing example applications
    • ${tomcat_home}\bin - Where you place web server plugins

    In all the examples in this document ${tomcat_home} will be c:\tomcat. A worker is defined to be a tomcat process that accepts work from the Sun ONE Web Server.

    The NSAPI-Tomcat redirector was developed and tested on:

    • WINNT 2000/XP/2003 (should be able to work with other service packs) and some Unixes
    • Sun ONE Web Server 6.1
    • Tomcat 4.1 to Tomcat 8.

    The redirector uses ajp12 and ajp13 to send requests to the Tomcat containers. There is also an option to use Tomcat in process, more about the in-process mode can be found in the in process howto.

    The ajp12 protocol is only available in Tomcat 3.2.x and 3.3.x.

    The ajp12 has been deprecated with Tomcat 3.3.x and you should use instead ajp13 which is the only ajp protocol known by Tomcat 4 and above.

    Of course Tomcat 3.2.x and 3.3.x also support ajp13 protocol.

    Others servlet engines such as jetty have support for ajp13 protocol

    1. The NSAPI-Tomcat redirector is an Netscape service step plugin, Netscape load the redirector plugin and calls its service handler function for request that are assigned to the "servlet" configuration object.
    2. For each in-coming request Netscape will execute the set of NameTrans directives that we added to obj.conf, the assign-name function will check if it's from parameter matches the request URL.
    3. If a match is found, assign-name will assign the servlet object name to the request. This will cause Netscape to send the request to the servlet configuration object.
    4. Netscape will execute our jk_service extension. The extension collects the request parameters and forwards them to the appropriate worker using the ajp13 protocol (the worker="defworker" parameter in jk_service inform it that the worker for this request is named defworker). the workers properties files, workers.properties, will indicate that defworker use ajp13 protocol.
    5. The extension collects the response from the worker and returns it to the browser.

    A pre-built version of the NSAPI redirector, nsapi_redirect.dll, may be available under the win32/i386 directory of tomcat-connectors distribution. For those using Netscape as your browser, try downloading a zip version of the file, if available. You can also build a copy locally from the source present in tomcat-connectors distribution. The Tomcat redirector requires two entities:

    • nsapi_redirect.dll (Windows) -or- nsapi_redirector.so (Unix) - The NSAPI server plugin, either obtain a pre-built DLL/so or build it yourself (see the build section).
    • workers.properties - A file that describes the host(s) and port(s) used by the workers (Tomcat processes). A sample workers.properties can be found under the conf directory.
    The installation includes the following parts:
    • Configuring the NSAPI redirector with a default /examples context and checking that you can serve servlets with Netscape.
    • Adding more contexts to the configuration.

    In this document we'll assume that nsapi_redirect.dll is placed in c:\jk\lib\nsapi_redirect.dll, the properties file is inc:\jk\conf and you created a log directory c:\jk\logs

    • If the built in servlet support is working disable it.
    • Add the redirector plugin into the Netscape server configuration. Edit your server magnus.conf and add the following lines:
    Init fn="load-modules" funcs="jk_init,jk_service" shlib="c:/jk/lib/nsapi_redirect.dll" shlib_flags="(global|now)" Init fn="jk_init" worker_file="c:/jk/conf/workers.properties" log_level="debug" log_file="c:/jk/logs/nsapi.log" shm_file="c:/jk/logs/jk_shm"
    • Edit your server obj.conf and add the following lines:
    In the default object NameTrans section <Object name="default"> NameTrans fn="assign-name" from="/servlets-examples(|/*)" name="jknsapi" NameTrans fn="assign-name" from="/jsp-examples(|/*)" name="jknsapi" .... </Object> Create a new configuration object by adding the following lines to the end of the obj.conf file <Object name="jknsapi"> ObjectType fn=force-type type=text/plain Service fn="jk_service" method="*" worker="worker1" </Object>
    • Edit your worker definition file workers.properties. You should at least choose a connection pool size:
    #An entry that lists all the workers defined. For example: worker.list=worker1 # Entries that define the host and port associated with these workers. worker.worker1.host=localhost worker.worker1.port=8009 worker.worker1.type=ajp13 worker.worker1.connection_pool_size=50
    • Restart Web Server (stop and start the server)

    That's all, now you should start tomcat and ask for http://server:port/servlets-examples/

    The file obj.conf seems to be sensitive to leading white space in lines, especially in the Object element. Make sure you have no leading white space (no indentation) on any line of this file.

    The examples context is useful for verifying your installation, but you will also need to add your own contexts. Adding a new context requires two operations:

    • Adding the context to Tomcat (I am not going to talk about this).
    • Assigning the NSAPI redirector to handle this context.

    Assigning the NSAPI redirector to handle this context is simple, all you need to do is to edit obj.conf and add a NameTrans line that looks like:

    NameTrans fn="assign-name" from="/<context name>/*" name="jknsapi"

    After saving obj.conf restart Netscape and it will serve the new context.

    Sometimes it is better to have Netscape serve the static pages (html, gif, jpeg etc.) even if these files are part of a context served by Tomcat. For example, consider the html and gif files in the examples context, there is no need to serve them from the Tomcat process, Netscape will suffice.

    Making Netscape serve static files that are part of the Tomcat contexts requires the following:

    • Configuring Netscape to know about the Tomcat contexts
    • Make sure that the WEB-INF directory is protected from access.
    • Configuring Netscape to assign the NSAPI redirector only specific requests that requires JSP/Servlet handling.

    Adding a Tomcat context to Netscape requires the addition of a new Netscape virtual directory that covers the Tomcat context.

    For example, adding a /example Netscape virtual directory that covers the c:\tomcat\webapps\examples directory.

    To add a new virtual directory add the following line to your obj.conf:

    NameTrans fn=pfx2dir from=/examples dir="c:/tomcat/webapps/examples"

    WEB-INF protection requires some explanation; Each servlet application (context) has a special directory named WEB-INF, this directory contains sensitive configurations data and Java classes and must be kept hidden from web users. WEB-INF can be protected by adding the following line to the PathCheck section in the default configuration object:

    PathCheck fn="deny-existence" path="*/WEB-INF/*" This line instructs the Netscape server to reject any request with a URL that contain the path /WEB-INF/.

    Configuring Netscape to assign the NSAPI redirector only specific requests is somewhat harder, you will need to specify the exact URL-Path pattern(s) that you want Tomcat to handle (usually only JSP files and servlets).

    This requires a change to NameTrans portion of obj.conf.

    For the examples context it requires to replace the following line: NameTrans fn="assign-name" from="/examples/*" name="jknsapi" with the following two lines: NameTrans fn="assign-name" from="/examples/jsp/*.jsp" name="jknsapi" NameTrans fn="assign-name" from="/examples/servlet/*" name="jknsapi"

    As you can see the second configuration is more explicit, it actually instructs Netscape to assign the redirector with only requests to resources under /examples/servlet/ and resources under /examples/ whose name ends with .jsp.

    You can be even more explicit and provide lines such as:

    NameTrans fn="assign-name" from="/examples/servletname" name="jknsapi" Instructs Netscape to assign the redirector request whose URL-Path equals /example/servletname

    Sometimes you want to serve different contexts with different Tomcat processes (for example to spread the load among different machines). To achieve such goal you will need to define several workers and assign each context with its own worker.

    Defining workers is done in workers.properties, this file includes two types of entries:

    #An entry that lists all the workers defined. For example: worker.list=worker1,worker2 # Entries that define the host and port associated with these workers. worker.worker1.host=localhost worker.worker1.port=8009 worker.worker1.type=ajp13 worker.worker2.host=otherhost worker.worker2.port=8009 worker.worker2.type=ajp13

    The above examples defined two workers, now we can use these workers to serve two different contexts each with it's own worker. Submitting requests to different workers is accomplished by using multiple Service directives in the servlet configuration Object, each with a different path pattern parameter.

    For example, if we want to submit the /examples context to the worker named worker1 and the /webpages context to the worker named worker2 we should use the following configuration:

    <Object name="jknsapi"> ObjectType fn=force-type type=text/plain Service fn="jk_service" worker="worker1" path="/examples/*" Service fn="jk_service" worker="worker2" path="/webpages/*" Service fn="jk_service" worker="worker1" </Object>

    More informations on using and configuring workers in the Workers HowTo and in the worker.properties configuration reference.

    The redirector was developed using Visual C++ Ver.6.0, so having this environment is a prereq if you want to perform a custom build. You should also have NES developer SDK The steps that you need to take are:

    • Change directory to the nsapi plugins source directory.
    • Edit nsapi.dsp and update the include and library path to reflect your own Netscape server installation (search for a /I compiler option and /libpath linker option)
    • Make the source with MSDEV
    Change directory to the nsapi plugins source directory cd c:\home\apache\jk\nsapi Build the sources using MSDEV MSDEV nsapi.dsp /MAKE ALL

    If msdev is not in your path, enter the full path to msdev.exe. This will build both release and debug versions of the redirector plugin. An alternative will be to open the nsapi workspace file (nsapi.dsw) in msdev and build it using the build menu.

    The redirector requires either gcc (Linux) or gcc or the Sun cc compiler (Solaris). The steps that you need to take are:

    • Change directory to the nsapi plugins source directory (src/native).
    • configure for Netscape/iPlanet/SunONE webserver.
    • Change directory to the nsapi netscape directory (./netstape).
    • Set environment variables JAVA_HOME resp. SUITSPOT_HOME to the location of your Java installation resp. Netscape server installation. Depending on the web server version, you must add the subdirectory "plugins" to SUITSPOT_HOME. The variable is correct, if the file $SUITSPOT_HOME/include/nsapi.h exists.
    • Edit Makefile.solaris resp. Makefile.linux and update the variables according to your needs. In the Solaris Makefile, you need to switch the commented lines in order to use the Sun compiler cc instead of GNU gcc.
    • Make the source with gmake.
    Change directory to the nsapi plugins source directory cd /usr/local/src/tomcat-connectors-xxx-src/native configure for Netscape/iPlanet/SunONE webserver ./configure --enable-netscape Change directory to the nsapi netscape directory cd netscape Set JAVA_HOME (ksh example) export JAVA_HOME=/path/to/my/java Set SUITSPOT_HOME (ksh example) export SUITSPOT_HOME=/path/to/my/netscape/server Edit the Makefile vi Makefile.solaris Make the source with gmake gmake -f Makefile.solaris

    After the build, you will have the required nsapi_redirector.so plugin.

    tomcat-connectors-1.2.41-src/xdocs/webserver_howto/iis.xml0000644000000000000020000005734112472575314022211 0ustar rootbin ]> &project; Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. IIS HowTo Henri Gomez Gal Shachor Yoav Shapira $Date: 2015-02-23 10:02:52 +0000 (Mon, 23 Feb 2015) $

    This document explains how to set up IIS to cooperate with Tomcat.

    Normally IIS can not execute Servlets and Java Server Pages (JSPs), configuring IIS to use the JK ISAPI redirector plugin will let IIS send servlet and JSP requests to Tomcat (and this way, serve them to clients).

    It is recommended that you also read the Workers HowTo document to learn how to setup the working entities between your web server and Tomcat Engines. For more detailed configuration information consult the Reference Guide for workers.properties, uriworkermap and IIS.

    ${tomcat_home} is the root directory of tomcat. Your Tomcat installation should have the following subdirectories:

    • ${tomcat_home}\conf - Where you can place various configuration files
    • ${tomcat_home}\webapps - Containing example applications
    • ${tomcat_home}\bin - Where you place web server plugins

    In all the examples in this document ${tomcat_home} will be c:\tomcat. A worker is defined to be a tomcat process that accepts work from the IIS server.

    The IIS-Tomcat redirector works for:

    • WinNT4.0-i386 SP4/SP5/SP6a (should be able to work with other service packs), Win98, WinXP, Win2K, and probably also Win2K3, Vista and Windows 7.
    • IIS4.0 and PWS4.0, IIS 5 to IIS 7.
    • Tomcat 3.2 to Tomcat 8.

    The redirector uses ajp12 and ajp13 to send requests to the Tomcat containers. There is also an option to use Tomcat in process, more about the in-process mode can be found in the in process howto.

    There are extra steps you need to take for configuring Tomcat with IIS 5 and 6. Please see the appropriate links from Tomcat Useful Links.

    There is a known bug in IIS that may result in incomplete log messages. See bug 45769 for further details.

    In a 64 Bit environment - at least for IIS 7 - the used IIS Application Pool should have "Enable 32-bit Applications" set to "False". Otherwise the redirector will not be called and returns an http code 404. If you think, the 32bit version of isapi_redirect.dll would do the job instead, you will get an http code 500, because the library is not loadable into a 64 Bit IIS.

    The ajp12 protocol is only available in Tomcat 3.2.x and 3.3.x.

    The ajp12 has been deprecated with Tomcat 3.3.x and you should use instead ajp13 which is the only ajp protocol known by Tomcat 4 and above.

    Of course Tomcat 3.2.x and 3.3.x also support ajp13 protocol.

    Others servlet engines such as jetty have support for ajp13 protocol

    1. The IIS-Tomcat redirector is an IIS plugin (filter + extension), IIS load the redirector plugin and calls its filter function for each in-coming request.
    2. The filter then tests the request URL against a list of URI-paths held inside uriworkermap.properties, If the current request matches one of the entries in the list of URI-paths, the filter transfers the request to the extension.
    3. The extension collects the request parameters and forwards them to the appropriate worker using the defined protocol like ajp13.
    4. The extension collects the response from the worker and returns it to the browser.

    A pre-built version of the ISAPI redirector server plugin, isapi_redirect.dll, is available under the win32/i386 directory of tomcat-connectors distribution. For those using Netscape as your browser, try downloading a zip version of the file, if available. There can be problems using Netscape to download DLL files. You can also build a copy locally from the source present in tomcat-connectors distribution. The Tomcat redirector requires three entities:

    • isapi_redirect.dll - The IIS server plugin, either obtain a pre-built DLL or build it yourself (see the build section).
    • workers.properties - A file that describes the host(s) and port(s) used by the workers (Tomcat processes). A sample workers.properties can be found under the conf directory.
    • uriworkermap.properties - A file that maps URL-Path patterns to workers. A sample uriworkermap.properties can be found under the conf directory as well.

    The installation includes the following parts:

    • Configuring the ISAPI redirector with a default /examples context and checking that you can serve servlets with IIS.
    • Adding more contexts to the configuration.

    In this document I will assume that isapi_redirect.dll is placed in c:\tomcat\bin\win32\i386\isapi_redirect.dll and that the properties files which you created are in c:\tomcat\conf.

    1. In the registry, create a new registry key named "HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0"
    2. Add a string value with the name extension_uri and a value of /jakarta/isapi_redirect.dll
    3. Add a string value with the name log_file and a value pointing to where you want your log file to be (for example c:\tomcat\logs\isapi.log).
    4. Add a string value with the name log_level and a value for your log level (can be debug, info, error or emerg).
    5. Add a string value with the name worker_file and a value which is the full path to your workers.properties file (for example c:\tomcat\conf\workers.properties)
    6. Add a string value with the name worker_mount_file and a value which is the full path to your uriworkermap.properties file (for example c:\tomcat\conf\uriworkermap.properties)
    7. Using the IIS management console, add a new virtual directory to your IIS/PWS web site. The name of the virtual directory must be jakarta. Its physical path should be the directory where you placed isapi_redirect.dll (in our example it is c:\tomcat\bin\win32\i386). While creating this new virtual directory assign it with execute access.
    8. Using the IIS management console, add isapi_redirect.dll as a filter in your IIS/PWS web site. The name of the filter should reflect its task (I use the name tomcat), its executable must be our c:\tomcat\bin\win32\i386\isapi_redirect.dll. For PWS, you'll need to use regedit and add/edit the "Filter DLLs" key under HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3SVC\Parameters. This key contains a "," separated list of dlls (full paths) - you need to insert the full path to isapi_redirect.dll.
    9. If you're using IIS 6.0 you must also do the following:
      Using the IIS management console, add the Tomcat Isapi Redirector to the Web Service Extensions.
      1. Right-click on Web Service Extensions and choose Add a new Web Service Extension.
      2. Enter tomcat for the Extension Name.
      3. Add the isapi_redirect.dll to the required files.
      4. Check the Set extension status to Allowed.
      5. Click on OK.
    10. Restart IIS (stop + start the IIS service), make sure that the tomcat filter is marked with a green up-pointing arrow. Under Win98 you may need to cd WINDOWS\SYSTEM\inetsrv and type PWS /stop ( the DLL and log files are locked - even if you click the stop button, PWS will still keep the DLLs in memory. ). Type pws to start it again.

    That's all, you should now start Tomcat and ask IIS to serve you the /examples context. Try http://localhost/examples/jsp/index.html for example and execute some of the JSP examples.

    If this does not work successfully, refer to the Troubleshooting section below for help on correcting the problem.

    The examples context is useful for verifying your installation, but you will also need to add your own contexts. Adding a new context requires two operations:

    1. Adding the context to Tomcat (I am not going to talk about this).
    2. Adding the context to the ISAPI redirector.

    Adding a context to the ISAPI redirector is simple, all you need to do is to edit your uriworkermap.properties and to add a line that looks like:

    /context/*=worker_name

    Workers and their name are defined in workers.properties, by default workers.properties comes with a single pre-configured worker named "defworker" so you can use it. As an example, if you want to add a context named "shop", the line that you should add to uriworkermap.properties will be:

    /shop/*=defworker After saving uriworkermap.properties restart IIS and it will serve the new context.

    The above should be all you need for IIS to pass through to Tomcat any request for any URI which corresponds to a Tomcat context (webapp).

    If your webiste is very busy (more than 100 requests/second, or more than 100 simultaneous client connections), it might sometimes be desirable to have IIS serve static content (html, gif, jpeg etc.) directly, even if these files are part of a context served by Tomcat. Allowing IIS to serve such files directly may avoid the small overhead consisting of passing the request to Tomcat via the redirector, and may free up Tomcat somewhat, by using it only to process requests that only Tomcat can handle (e.g. requests to JSP pages and java servlets).

    For example, consider the html and gif files in the examples context : you could serve these files directly with IIS; there is no need to serve them from the Tomcat process.

    However, you should be very careful when you implement the following configuration style, because by doing so you are in fact providing a "back-door" to IIS, and allowing it to serve files out of a Tomcat context without Tomcat's knowledge, thus bypassing any security restrictions which Tomcat itself and the Tomcat context (webapp) may place on those files.

    Making IIS serve static files that are part of the Tomcat contexts requires the following:

    1. Configuring IIS to know about the Tomcat contexts
    2. Configuring the redirector to leave the static files for IIS

    Adding a Tomcat context to IIS requires the addition of a new IIS virtual directory that covers the Tomcat context. For example adding a /example IIS virtual directory that covers the c:\tomcat\webapps\examples directory.

    Configuring the redirector is somewhat harder, you will need to specify the exact URL-Path pattern(s) which you want Tomcat to handle (usually only JSP files and servlets). This requires a change to the uriworkermap.properties : For the examples context it requires to replace the following line /examples/*=defworker with the following two lines /examples/*.jsp=defworker /examples/servlet/*=defworker

    As you can see the second configuration is more explicit, it actually instruct the redirector to redirect only requests to resources under /examples/servlet/ and resources under /examples/ whose name ends with .jsp.

    You can even be more explicit and provide lines such as: /example/servletname=defworker

    that instructs the redirector to redirect all requests whose URL-path matches the leading string "/example/servletname" to the worker named defworker.

    Once again, be aware that by allowing IIS to access the content of your Tomcat context directly, you are potentially bypassing Tomcat's protection of that content. You should thus make sure to protect this content at the IIS level if needed, by using the corresponding IIS management console functions.

    In particular, each servlet application (context) has a special directory named WEB-INF, which contains sensitive configuration data and Java classes, and which should always be kept hidden from web users. Using the IIS management console it is possible to protect the WEB-INF directory from user access, but considering that this is a general requirement, and considering that it is easy to forget to implement this protection at the IIS level, the redirector plugin does it automatically for you, and it will reject any request which contains WEB-INF in its URL-path.

    Sometimes you may want to serve different contexts with different Tomcat processes (for example to spread the load among different machines). To achieve such a goal you will need to define several workers and assign each context to its own worker.

    Defining additional workers is done in the workers.properties file. This file includes two types of entries:

    # An entry that lists all the workers defined worker.list=worker1, worker2 # Entries that define the host and port associated with each of these workers worker.worker1.host=localhost worker.worker1.port=8009 worker.worker1.type=ajp13 worker.worker2.host=otherhost worker.worker2.port=8009 worker.worker2.type=ajp13

    The above example defined two workers, now we can use these workers to serve two different contexts each with its own worker: example uriworkermap.properties fragment /examples/*=worker1 /webpages/*=worker2

    As you can see the examples context is served by worker1 while the webpages context is served by worker2.

    More information on using and configuring workers in the Workers HowTo and in the worker.properties configuration reference.

    The redirector was developed using Visual C++ Ver.6.0, so having this environment is a prerequisite if you want to perform a custom build. You should also have the IIS developer SDK. The steps that you need to take are:

    • Change directory to the isapi plugins source directory.
    • Make the source with MSDEV
    Change directory to the isapi plugins source directory cd c:\home\apache\jk\iis Build the sources using MSDEV MSDEV isapi.dsp /MAKE ALL

    If msdev is not in your path, enter the full path to msdev.exe. This will build both release and debug versions of the redirector plugin. An alternative will be to open the isapi workspace file (isapi.dsw) in msdev and build it using the build menu.

    It is easy to have the ISAPI redirector not work the first time you try to install it.

    If this happens to you, here are some steps to follow to try to correct the problem.

    These steps aren't guaranteed to cover all possible problems, but they should help find the typical mistakes.

    If you make any corrections during these steps, restart the IIS service as described above in the last step of the installation, then retry the step.

    To enable error tracking, make sure web site activity is being logged. For PWS 4.0 make sure "Save Web Site Activity Log" is checked in the Advanced Options of the Personal Web Manager.

    Note: These steps assume your worker_mount_file setting points to an unmodified copy of the uriworkermap.properties file.
    Results may be misleading if worker_mount_file points to a modified uriworkermap.properties or the uriworkermap.properties-auto file.
    It is also assumed that the "/examples" context works correctly if you access Tomcat directly.

    Start the IIS service and Tomcat.

    Check for the presence of the ISAPI redirector log file you specified in the log_file setting. If not found, verify the following:

    • Check the "Filter DLLs" setting in the "HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3SVC\Parameters" key and make sure the path is correct.
    • Check the spelling of the "HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0" key. Case isn't important, but an incorrect letter will prevent the isapi_redirect.dll from finding its registry settings.
    • Check the log_file setting for typos, name and data. Also insure the directory in which the log file will appear already exists.
    • If the above are set correctly, the ISAPI redirector should be able to create the log file.

    Invoke the URL http://localhost/examples/jsp/index.html in your browser. Case is important in Tomcat. The characters following "localhost" in the URL must be lower case. If the page fails to appear, stop the IIS service (required to view the IIS log file). Then examine the last line in the IIS log file in found in SYSTEM/LogFiles/W3SVC1 :

    If the last line contains:

    GET "/examples/jsp/index.html HTTP/1.1" 404

    then the ISAPI redirector is not recognising that it should be handling requests for the "/examples" context. Check the following:

    • Check the extension_uri name for typos.
    • Check the worker_file setting for typos, name and data.
    • Check the worker_mount_file setting typos, name and data.
    • If these are set correctly, the ISAPI redirector should recognise that it should handle requests for the "/examples" context.

    If the last line contains something like:

    GET "/jakarta/isapi_redirect.dll HTTP1.1"

    then the ISAPI redirector is recognising that it should handle the request, but is not successful at getting Tomcat to service the request.

    You should check the HTTP error code following GET "/..." :

    Error 404 GET "/..." 404
    • Make sure you entered the URL correctly.
    • Make sure the virtual directory created was called "jakarta". It should display in Personal Web Manager as "/jakarta" (without the quotes).
    • Make sure the extension_uri data begins with "/jakarta/" (without the quotes).
    Error 500 GET "/..." 500
    • Make sure that "isapi_redirect.dll" follows "/jakarta/" in the extension_uri setting.
    • Check the workers.properties file and make sure the port setting for worker.ajp12.port is the same as the port specified in the server.xml for the "Apache AJP12 support".
    Error 200 or 403 GET "/..." 200 GET "/..." 403
    • Make sure you have checked Execute Access for the jakarta virtual directory in the Advanced Options of the Personal Web Manager.

    If the above settings are correct, the index.html page should appear in your browser. You should also be able to click the Execute links to execute the JSP examples.

    Start the World Wide Web Publishing Service and Tomcat.

    Check for the presence of the ISAPI redirector log file you specified in the log_file setting. If not found, check the following:

    • Check the "executable" you set for the filter in the IIS Management Console and make sure the path is correct.
    • Check the spelling of the "HKEY_LOCAL_MACHINE\SOFTWARE\Apache Software Foundation\Jakarta Isapi Redirector\1.0" key. Case isn't important, but an incorrect letter will prevent the isapi_redirect.dll from finding its registry settings.
    • Check the log_file setting for typos, name and data. Also insure the directory in which the log file will appear already exists.
    • If the above are set correctly, the ISAPI redirector should be able to create the log file.

    Check the tomcat filter you added and make sure its status shows a green upward-pointing arrow. If not, check the following:

    • Check the worker_file setting for typos, name and data.
    • Check the worker_mount_file setting typos, name and data.
    • If the above are set correctly, the green upward-pointing arrow should appear, even if the other settings are wrong.

    Invoke the URL http://localhost/examples/jsp/index.html in your browser. Case is important in Tomcat. The characters following "localhost" in the URL must be lower case. If the page fails to appear, examine the last line in the IIS server log file in found in SYSTEM32/LogFiles/W3SVC1.

    The last line should contain something like: GET "/jakarta/isapi_redirect.dll HTTP1.1", which indicates the ISAPI redirector is recognising that it should handle the request.

    You should check the HTTP error code following GET "/..." :

    Error 404 GET "/..." 404
    • Make sure you entered the URL correctly.
    Error 500 GET "/..." 500
    • Make sure the virtual directory created was called "jakarta".
    • Make sure that the extension_uri setting is correct.
    • Check the workers.properties file and make sure the port setting for worker.ajp12.port is the same as the port specified in the server.xml for the "Apache AJP12 support".
    Error 200 or 403 GET "/..." 200 GET "/..." 403
    • Make sure you have checked Execute Access for the jakarta virtual directory in the Advanced Options of the Personal Web Manager.

    If the above settings are correct, the index.html page should appear in your browser. You should also be able to click the Execute links to execute the JSP examples.

    tomcat-connectors-1.2.41-src/xdocs/webserver_howto/apache.xml0000644000000000000020000012311112472575314022633 0ustar rootbin ]> &project; Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Apache HTTP Server HowTo Henri Gomez Gal Shachor $Date: 2015-02-23 10:02:52 +0000 (Mon, 23 Feb 2015) $

    This document explains how to connect Tomcat to the popular open source web server, Apache httpd. You can use mod_jk, the Tomcat redirector module, with any version of Apache starting with 1.3.

    It is recommended that you also read the Workers HowTo document to learn how to setup the working entities between your web server and Tomcat Engines. For more detailed configuration information consult the Reference Guide for workers.properties, uriworkermap and Apache.

    Waring: If Apache HTTP Server and Tomcat are configured to serve content from the same filing system location then care must be taken to ensure that httpd is not able to serve inappropriate content such as the contents of the WEB-INF directory or JSP source code. This could occur if the httpd DocumentRoot overlaps with a Tomcat Host's appBase or the docBase of any Context. It could also occur when using the httpd Alias directive with a Tomcat Host's appBase or the docBase of any Context.

    This document was originally part of Tomcat: A Minimalistic User's Guide written by Gal Shachor, but has been split off for organisational reasons.

    ${tomcat_home} is the root directory of tomcat. Your Tomcat installation should have the following subdirectories:

    • ${tomcat_home}\conf - Where you can place various configuration files
    • ${tomcat_home}\webapps - Containing example applications
    • ${tomcat_home}\bin - Where you place web server plugins

    In all the examples in this document ${tomcat_home} will be /var/tomcat3. A worker is defined to be a tomcat process that accepts work from the Apache server.

    The mod_jk module was developed and tested on:

    • Linux, FreeBSD, AIX, HP-UX, MacOS X, Solaris and should work on major Unixes platforms supporting Apache 1.3 and/or 2.x
    • WinNT4.0-i386 SP4/SP5/SP6a (should be able to work with other service packs), Win2K and WinXP and Win98
    • Cygwin (until you have an apache server and autoconf/automake support tools)
    • Netware
    • i5/OS V5R4 (System I) with Apache HTTP Server 2.0.58. Be sure to have the latest Apache PTF installed.
    • Tomcat 3.2 to Tomcat 8.

    The redirector uses ajp12 and ajp13 to send requests to the Tomcat containers. There is also an option to use Tomcat in process, more about the in-process mode can be found in the in process howto.

    The ajp12 protocol is only available in Tomcat 3.2.x and 3.3.x.

    The ajp12 has been deprecated with Tomcat 3.3.x and you should use instead ajp13 which is the only ajp protocol known by Tomcat 4 and above.

    Of course Tomcat 3.2.x and 3.3.x also support ajp13 protocol.

    Others servlet engines such as jetty have support for ajp13 protocol

    In a nutshell a web server is waiting for client HTTP requests. When these requests arrive the server does whatever is needed to serve the requests by providing the necessary content.

    Adding a servlet container may somewhat change this behaviour. Now the web server needs also to perform the following:

    • Load the servlet container adaptor library and initialise it (prior to serving requests).
    • When a request arrives, it needs to check and see if a certain request belongs to a servlet, if so it needs to let the adaptor take the request and handle it.

    The adaptor on the other hand needs to know what requests it is going to serve, usually based on some pattern in the request URL, and to where to direct these requests.

    Things are even more complex when the user wants to set a configuration that uses virtual hosts, or when they want multiple developers to work on the same web server but on different servlet container JVMs. We will cover these two cases in the advanced sections.

    mod_jk can be obtained in two formats - binary and source. Depending on the platform you are running your web server on, a binary version of mod_jk may be available.

    It is recommended to use the binary version if one is available. If the binary is not available, follow the instructions given in the below "Building mod_jk" sections for building mod_jk from source. The mod_jk source can be downloaded from a mirror here

    The binaries for mod_jk are now available for several platforms. The binaries are located in subdirectories by platform.

    For some platforms, such as Windows, this is the typical way of obtaining mod_jk since most Windows systems do not have C compilers.

    For others, the binary distribution of mod_jk offers simpler installation.

    For example JK 1.2.x can be downloaded from a mirror here (look for JK 1.2 Binary Releases). The "JK 1.2 Binary Releases" link contains binary version for a variety of operating systems for both Apache 1.3 and Apache 2.x.

    mod_jk requires two entities:

    • mod_jk.xxx - The Apache HTTP Server module, depending on your operating system, it will be mod_jk.so, mod_jk.nlm or MOD_JK.SRVPGM (see the build section).
    • workers.properties - A file that describes the host(s) and port(s) used by the workers (Tomcat processes). A sample workers.properties can be found under the conf directory in the source download.

    Also as with other Apache HTTP Server modules, mod_jk should be first installed on the modules directory of your Apache webserver, ie : /usr/lib/apache and you should update your httpd.conf file.

    If you've previously configured Apache to use mod_jserv, remove any ApJServMount directives from your httpd.conf.

    If you're including tomcat-apache.conf or tomcat.conf, you'll want to remove them as well - they are specific to mod_jserv.

    The mod_jserv configuration directives are not compatible with mod_jk !

    The auto-configure works only for a single Tomcat running on the same machine where Apache HTTP Server is running. The simplest way to configure Apache HTTP Server to use mod_jk is to turn on the Apache HTTP Server auto-configure setting in Tomcat and put the following include directive at the end of your Apache httpd.conf file (make sure you replace $TOMCAT_HOME with the correct path for your Tomcat installation:

    #To be added at the end of your httpd.conf Include $TOMCAT_HOME/conf/jk/mod_jk.conf-auto

    Note: this file may also be generated as $TOMCAT_HOME/conf/auto/mod_jk.conf

    This will tell Apache HTTP Server to use directives in the mod_jk.conf-auto file in the Apache configuration. This file is created by enabling the Apache auto-configuration by creating your workers.properties file at $TOMCAT_HOME/conf/jk/workers.properties and adding the listener to the Engine element in the server.xml file as per the following example. Please note that this example is specific to Tomcat 5.x, unlike other sections of this document which also apply to previous Tomcat branches.

    ... <Engine ...> ... <Listener className="org.apache.jk.config.ApacheConfig" modJk="/path/to/mod_jk.so" /> ... </Engine> ...

    Then restart Tomcat and mod_jk.conf should be generated. For more information on this topic, please refer to the API documentation at the Tomcat docs website.

    You should use custom configuration when :

    • You couldn't use mod_jk.conf-auto since Tomcat engine isn't on the same machine that your Apache web server, ie when you have an Apache in front of a Tomcat Farm.
    • Another case for custom configuration is when your Apache is in front of many different Tomcat engines, each one having it's own configuration, a general case in ISP hosting
    • Also all Apache webmaster will retain custom configuration to be able to tune the settings to their real needs.

    Here is a simple configuration:

    # Load mod_jk module LoadModule jk_module modules/mod_jk.so # Add the module (activate this lne for Apache 1.3) # AddModule mod_jk.c # Where to find workers.properties JkWorkersFile /etc/httpd/conf/workers.properties # Where to put jk shared memory JkShmFile /var/log/httpd/mod_jk.shm # Where to put jk logs JkLogFile /var/log/httpd/mod_jk.log # Set the jk log level [debug/error/info] JkLogLevel info # Send servlet for context /examples to worker named worker1 JkMount /examples/servlet/* worker1 # Send JSPs for context /examples to worker named worker1 JkMount /examples/*.jsp worker1

    We'll discuss here the mod_jk directives and details behind them

    JkWorkersFile specify the location where mod_jk will find the workers definitions. JkWorkersFile /etc/httpd/conf/workers.properties

    JkLogFile specify the location where mod_jk is going to place its log file.

    JkLogFile /var/log/httpd/mod_jk.log

    Since JK 1.2.3 for Apache 2.x and JK 1.2.16 for Apache 1.3 this can also be used for piped logging:

    JkLogFile "|/usr/bin/rotatelogs /var/log/httpd/mod_jk.log 86400"

    JkLogLevel set the log level between :

    • info log will contains standard mod_jk activity (default).
    • error log will contains also error reports.
    • debug log will contains all information on mod_jk activity
    JkLogLevel info

    info should be your default selection for normal operations.

    JkLogStampFormat will configure the date/time format found on mod_jk logfile. See the mod_jk Apache HTTP server reference for details.

    JkLogStampFormat "[%y-%m-%d %H:%M:%S.%Q] "



    You can log mod_jk information using the Apache standard module mod_log_config. The module sets several notes in the Apache httpd notes table. Most of them are are only useful in combination with a load balancer worker. See the mod_jk Apache HTTP server reference for details.

    LogFormat "%h %l %u %t \"%r\" %>s %b %{JK_WORKER_NAME}n %{JK_LB_FIRST_NAME}n \ %{JK_LB_FIRST_BUSY}n %{JK_LB_LAST_NAME}n %{JK_LB_LAST_BUSY}n" mod_jk_log CustomLog logs/access_log mod_jk_log



    You can also log a request protocol in the mod_jk log file instead of the access log. This is not recommended and mostly a backward compatibility feature. The directive JkRequestLogFormat will configure the format of this protocol. It gets configured and enabled on a per virtual host basis. See the mod_jk Apache HTTP server reference for details.

    JkRequestLogFormat "%w %V %T"



    The directive JkOptions allow you to set many forwarding options which will enable (+) or disable (-) following option. Without any leading signs, options will be enabled.

    The four following options +ForwardURIxxx are mutually exclusive. Exactly one of them is required, a negative sign prefix is not allowed with them. The default value is "ForwardURIProxy" since version 1.2.24. It was "ForwardURICompatUnparsed" in version 1.2.23 and "ForwardURICompat" until version 1.2.22. You can turn the default off by switching on one of the other two options. You should leave this at it's default value, unless you have a very good reason to change it.

    All options are inherited from the global server to virtual hosts. Options that support enabling (plus options) and disabling (minus options), are inherited in the following way:

    options(vhost) = plus_options(global) - minus_options(global) + plus_options(vhost) - minus_options(vhost)

    Using JkOptions ForwardURIProxy, the forwarded URI will be partially reencoded after processing inside Apache httpd and before forwarding to Tomcat. This will be compatible with local URL manipulation by mod_rewrite and with URL encoded session ids. JkOptions +ForwardURIProxy

    Using JkOptions ForwardURICompatUnparsed, the forwarded URI will be unparsed. It's spec compliant and secure. It will always forward the original request URI, so rewriting URIs with mod_rewrite and then forwarding the rewritten URI will not work. JkOptions +ForwardURICompatUnparsed

    Using JkOptions ForwardURICompat, the forwarded URI will be decoded by Apache httpd. Encoded characters will be decoded and explicit path components like ".." will already be resolved. This is less spec compliant and is not safe if you are using prefix JkMount. This option will allow to rewrite URIs with mod_rewrite before forwarding. JkOptions +ForwardURICompat

    Using JkOptions ForwardURIEscaped, the forwarded URI will be the encoded form of the URI used by ForwardURICompat. Explicit path components like ".." will already be resolved. This will not work in combination with URL encoded session IDs, but it will allow to rewrite URIs with mod_rewrite before forwarding. JkOptions +ForwardURIEscaped

    JkOptions RejectUnsafeURI will block all URLs, which contain percent signs '%' or backslashes '\' after decoding.

    Most web apps do not use such URLs. Using the option RejectUnsafeURI, you can block several well known URL encoding attacks. By default, this option is not set.

    You can also realise such a check with mod_rewrite, which is more powerful but also slightly more complicated. JkOptions +RejectUnsafeURI

    JkOptions CollapseSlashesAll will collapse multiple adjacent slashes in request URLs before looking for mount or unmount matches. JkOptions +CollapseSlashesAll

    JkOptions CollapseSlashesUnmount will collapse multiple adjacent slashes in request URLs only before looking for unmount matches. This is the default value. JkOptions +CollapseSlashesUnmount

    JkOptions CollapseSlashesNone will never collapse multiple adjacent slashes in request URLs before looking for mount or unmount matches. Using this value might make you vulnerable for attacks bypassing your unmount rules. JkOptions +CollapseSlashesNone

    JkOptions ForwardDirectories is used in conjunction with DirectoryIndex directive of Apache web server. As such mod_dir should be available to Apache, statically or dynamically (DSO)

    When DirectoryIndex is configured, Apache will create sub-requests for each of the local-url's specified in the directive, to determine if there is a local file that matches (this is done by stat-ing the file).

    If ForwardDirectories is set to false (default) and Apache doesn't find any files that match, Apache will serve the content of the directory (if directive Options specifies Indexes for that directory) or a 403 Forbidden response (if directive Options doesn't specify Indexes for that directory).

    If ForwardDirectories is set to true and Apache doesn't find any files that match, the request will be forwarded to Tomcat for resolution. This is used in cases when Apache cannot see the index files on the file system for various reasons: Tomcat is running on a different machine, the JSP file has been precompiled etc.

    Note that locally visible files will take precedence over the ones visible only to Tomcat (i.e. if Apache can see the file, that's the one that's going to get served). This is important if there is more then one type of file that Tomcat normally serves - for instance Velocity pages and JSP pages. JkOptions +ForwardDirectories

    Setting JkOptions ForwardLocalAddress, you ask mod_jk to send the local address of the Apache web server instead of remote client address. This can be used by Tomcat remote address valve for allowing connections only from registered Apache web servers. JkOptions +ForwardLocalAddress

    Setting JkOptions ForwardPhysicalAddress, you ask mod_jk to send the physical peer TCP IP address as the client address. By default mod_jk uses the logical address as provided by the web server. For example the module mod_remoteip sets the logical IP address to the client IP forwarded by proxies in the X-Forwarded-For header. JkOptions +ForwardPhysicalAddress

    JkOptions FlushPackets, you ask mod_jk to flush Apache's connection buffer after each AJP packet chunk received from Tomcat. This option can have a strong performance penalty for Apache and Tomcat as writes are performed more often than would normally be required (ie: at the end of each response). JkOptions +FlushPackets

    JkOptions FlushHeader, you ask mod_jk to flush Apache's connection buffer after the response headers have been received from Tomcat. JkOptions +FlushHeader

    JkOptions DisableReuse, you ask mod_jk to close connections immediately after their use. Normally mod_jk uses persistent connections and pools idle connections to reuse them, when new requests have to be sent to Tomcat.

    Using this option will have a strong performance penalty for Apache and Tomcat. Use this only as a last resort in case of unfixable network problems. If a firewall between Apache and Tomcat silently kills idle connections, try to use the worker attribute socket_keepalive in combination with an appropriate TCP keepalive value in your OS. JkOptions +DisableReuse

    JkOptions ForwardKeySize, you ask mod_jk, when using ajp13, to forward also the SSL Key Size as required by Servlet API 2.3. This flag shouldn't be set when servlet engine is Tomcat 3.2.x (off by default). JkOptions +ForwardKeySize

    JkOptions ForwardSSLCertChain, you ask mod_jk, when using ajp13, to forward SSL certificate chain (off by default). Mod_jk only passes the SSL_CLIENT_CERT to the AJP connector. This is not a problem with self-signed certificates or certificates directly signed by the root CA certificate. However, there's a large number of certificates signed by an intermediate CA certificate, where this is a significant problem: A servlet will not have the possibility to validate the client certificate on its own. The bug would be fixed by passing on the SSL_CLIENT_CERT_CHAIN to Tomcat via the AJP connector.
    This directive exists only since version 1.2.22. JkOptions +ForwardSSLCertChain

    The directive JkEnvVar allows you to forward environment variables from Apache server to Tomcat engine. You can add a default value as a second parameter to the directive. If the default value is not given explicitly, the variable will only be send, if it is set during runtime.
    The variables can be retrieved on the Tomcat side as request attributes via request.getAttribute(attributeName). Note that the variables send via JkEnvVar will not be listed in request.getAttributeNames().

    The variables are inherited from the global server to virtual hosts. JkEnvVar SSL_CLIENT_V_START undefined

    If you have created a custom or local version of mod_jk.conf-local as noted above, you can change settings such as the workers or URL prefix.

    JkMount directive assign specific URLs to Tomcat. In general the structure of a JkMount directive is:

    JkMount [URL prefix] [Worker name] # send all requests ending in .jsp to worker1 JkMount /*.jsp worker1 # send all requests ending /servlet to worker1 JkMount /*/servlet/ worker1 # send all requests jsp requests to files located in /otherworker will go worker2 JkMount /otherworker/*.jsp worker2

    You can use the JkMount directive at the top level or inside <VirtualHost> sections of your httpd.conf file.

    If the Tomcat Host appBase (webapps) directory is accessible by the Apache web server, Apache can be configured to serve web application context directory static files instead of passing the request to Tomcat.

    Caution: For security reasons it is strongly recommended that JkMount is used to pass all requests to Tomcat by default and JkUnMount is used to explicitly exclude static content to be served by httpd. It should also be noted that content served by httpd will bypass any security constraints defined in the application's web.xml.

    Use Apache's Alias directive to map a single web application context directory into Apache's document space for a VirtualHost:

    # Static files in the examples webapp are served by apache Alias /examples /vat/tomcat3/webapps/examples # All requests go to worker1 by default JkMount /* worker1 # Serve html, jpg and gif using httpd JkUnMount /*.html worker1 JkUnMount /*.jpg worker1 JkUnMount /*.gif worker1

    Starting with mod_jk 1.2.6 for Apache 2.x and 1.2.19 for Apache 1.3, it's possible to exclude some URL/URI from jk processing by setting the env var no-jk, for example with the SetEnvIf Directive.

    You could use no-jk env var to fix problem with mod_alias or mod_userdir directive when jk and alias/userdir URLs matches.

    # All URL goes to tomcat except the one containing /home <VirtualHost *:80> ServerName testxxx.mysys DocumentRoot /www/testxxx/htdocs # Use SetEnvIf to st no-jk when /home/ is encountered SetEnvIf Request_URI "/home/*" no-jk # Now /home will goes to /home/dataxxx/ Alias /home /home/dataxxx/ <Directory "/home/dataxxx"> Options Indexes MultiViews AllowOverride None Order allow,deny Allow from all </Directory> JkMount /* myssys-xxx </VirtualHost>

    Use the mod_jk JkAutoAlias directive to map all web application context directories into Apache's document space.

    Attempts to access the WEB-INF or META-INF directories within a web application context or a Web Archive *.war within the Tomcat Host appBase (webapps) directory will fail with an HTTP 403, Access Forbidden

    # Static files in all Tomcat webapp context directories are served by apache JkAutoAlias /var/tomcat3/webapps # All requests go to worker1 by default JkMount /* ajp13 # Serve html, jpg and gif using httpd JkUnMount /*.html ajp13 JkUnMount /*.jpg ajp13 JkUnMount /*.gif ajp13

    If you encoded all your URLs to contain the session id (;jsessionid=...), and you later decide, you want to move part of the content to Apache httpd, you can tell mod_jk to strip off all session ids from URLs for those requests, that do not get forwarded via mod_jk.

    You enable this feature by setting JkStripSession to On. It can be enabled individually for virtual servers. The default value is Off.

    The mod_jk build use the widely used configure system.

    In case you get source from subversion, ie without an existing configure script, you should have autoconf for configuration and installation.

    To create tomcat-connectors's autoconf script, you will need libtool 1.5.2, automake 1.10 and autoconf 2.59 or newer. The use of more recent versions is encouraged, e.g. for reliable detection of the features of recent version of operating systems.

    Those tools will not be required if you are just using a package downloaded from apache.org, they are only required for developers.

    To create the configure script just type : ./buildconf.sh

    Here's how to use configure to prepare mod_jk for building, just type: ./configure [autoconf arguments] [tomcat-connectors arguments]

    You could set CFLAGS and LDFLAGS to add some platform specifics:

    LDFLAGS=-lc ./configure -with-apxs=/home2/local/apache/bin/apxs

    If you want to build mod_jk for different version of Apache httpd, like 1.3 or 2.x, you need to go through the full build process for each of them. Please note, that httpd 2.0, 2.2 or 2.4 modules are not binary compatible. You have to compile the module using the Apache version you plan to run it in. The mod_jk build directory used is "apache-2.0" for all 2.x builds.

    • use configure and indicate the correct Apache httpd apxs location (--with-apxs)
    • use make
    • copy the resulting mod_jk.so binary from the apache-1.3 or apache-2.0 subdirectory to the Apache httpd modules location.
    • make clean (to remove all previously compiled object files)
    • Start over with the apxs location for your next Apache httpd version.

    Apache related parameters
    --with-apxs[=FILE] FILE is the location of the apxs tool. Default is finding apxs in PATH. It builds a shared Apache module. It detects automatically the Apache version. (2.x and 1.3)
    --with-apache=DIR DIR is the path where apache sources are located. The apache sources should have been configured before configuring mod_jk. DIR is something like: /home/apache/apache_1.3.19 It builds a static Apache module.
    --enable-EAPI This parameter is needed when using Apache-1.3 and mod_ssl, otherwise you will get the error message: "this module might crash under EAPI!" when loading mod_jk.so in httpd. Not needed when --with-apxs has been used
    --enable-prefork In case you build mod_jk for a multi-threaded Apache httpd 2.x MPM (Multi-Processing Module), some areas of mod_jk code need to be synchronised to make it thread-safe. Because configure can not easily detect, whether your are using a multi-threaded MPM, mod_jk by default is always build thread-safe for Apache httpd 2.x. If you are sure, that your MPM is not multi-threaded, you can use "--enable-prefork" to force the removal of the synchronisation code (thus increasing performance a bit). For instance, the prefork MPM is not multi-threaded. For Apache httpd 1.3 this flag will be set automatically.
    --disable-trace When using log level "trace", mod_jk traces a lot of function calls with "enter" and "exit" log messages. Even if the log level is not "trace", comparing the log levels to decide about logging has some performance impact.
    If you use "--disable-trace", then the trace log code doesn't get compiled into the module binary and you might save some cycles during execution.
    Even with "--disable-trace" logging debug messages with debug log level will still be possible.
    --enable-api-compatibility Only use httpd API functions available in all httpd production releases of the chosen major httpd release branch. This improves binary compatibility of module builds with httpd releases older than the release against mod_jk is build (only between minor httpd versions).
    --enable-flock In case the operating system supports flock system call use this flag to enable this faster locks that are implemented as system call instead emulated by GNU C library.
    However those locks does not work on NFS mounted volumes, so you can use "--enable-flock" during compile time to force the flocks() calls.

    Apache 1.3 and 2.x build ./configure --with-apxs=/usr/sbin/apxs
    make
    cp ./apache-1.3/mod_jk.so /usr/lib/apache
    make clean
    ./configure --with-apxs=/usr/sbin/apxs2
    make
    cp ./apache-2.0/mod_jk.so /usr/lib/apache2

    The module was developed using Visual C++ version 6.0, so having this environment is a prerequisite if you want to perform a custom build.

    The steps that you need to take are:

    • Change directory to the apache-1.3 or apache-2.0 source directory depending on your version of Apache.
    • If you want to build mod_jk for Apache 1.3, set an APACHE1_HOME environment variable which points to where your Apache 1.3 is installed. A mod_jk module for Apache 2.x build will require APACHE2_HOME environment variable to be set.
    • Copy mod_jk.so to Apache's modules directory.

    An example on how to build mod_jk for Apache 1.3:

    Set location for Apache 1.3 sources set APACHE1_HOME=c:\apache13 Change directory to the mod_jk module for Apache 1.3 cd c:\home\apache\jk\native\apache-1.3 Build the sources using MSDEV MSDEV mod_jk.dsp /MAKE ALL Copy the dll to your apache modules directory cp release\mod_jk.so c:\apache13\modules\

    An example on how to build mod_jk for Apache 2.x:

    Set location for Apache 2.x sources set APACHE2_HOME=c:\apache20 Change directory to the mod_jk module for Apache 2.x cd c:\home\apache\jk\native\apache-2.0 Build the sources using MSDEV MSDEV mod_jk.dsp /MAKE ALL Copy the dll to your apache modules directory cp release\mod_jk.so c:\apache20\modules\

    If msdev is not in your path, enter the full path to msdev.exe. Also, ApacheCore.lib is expected to exist in the ${APACHEX_HOME}\src\CoreD and ${APACHEX_HOME}\src\CoreR directories before linking will succeed. You will need to build enough of the Apache source to create these libraries. This will build both release and debug versions of the redirector plug-in (mod_jk). An alternative will be to open mod_jk.dsp in msdev and build it using the build menu.

    Since OS400 V4R5, System I (AS/400) has used Apache 2.0 as their primary web server, replacing the old IBM webserver. It's now possible to build mod_jk on System I thanks to the help of the IBM Rochester Labs which has provided information and patches to adapt mod_jk to i5/OS.

    You should have at least Apache 2.0.58 (product 5722DG1), a C Compiler and IFS. Apache 2.0.58 is provided with the most recent set of PTFs for the iSeries Apache server, which can be found at http://www.ibm.com/servers/eserver/iseries/software/http/

    The all latest Apache 2 for i5/OS V5R3 (or V5R4) is now 2.0.58 (as of 2007/04/17). Be sure to have the latest PTFs loaded if you want to make use of jk 1.2.15 and higher. NB: The latest mod_jk known to work on i5/OS V5R3 was 1.2.19.

    New in i5/OS V5R4, UTF is required, also for Apache modules, as such Apache modules do not require translations to/from EBCDIC but works should be done to port mod_jk 1.2.23 (and higher) to V5R4. From the V5R4 Infocenter : As of i5/OS(tm) V5R4, modules must be recompiled with a UTF locale. This creates an environment where locale-dependent C runtime functions assume that string data is encoded in UTF-8. Any hardcoded constants can be encoded in UTF-8 by adding a #pragma convert(1208) statement in the module. Additionally, input data from the client will no longer be converted to EBCDIC but will be passed as-is. Output data sent from the module is not converted either so it must be encoded in ASCII or UTF8 as required. APR and HTTP APIs as of V5R4, expect data in UTF-8. Note that several APIs have additional functions that allow a CCSID to be set to indicate the encoding of the parameters being passed. Conversion functions between UTF-8 and EBCDIC have been added. Be sure to review APIs used by your module to be aware of current changes.

    To configure mod_jk on System I use the CL source provided with the mod_jk source.

    • Get the latest mod_jk source and untar it on a Windows or Unix boxes
    • Create a directory in IFS, ie /home/apache
    • Send the whole jk source directory to System I directory via FTP.
    • Then go to the System I command line :
    Create mod_jk library CRTLIB MOD_JK TEXT(‘Apache mod'jk tomcat connector module') Create service program source file CRTSRCPF MOD_JK/QSRVSRC TEXT(‘Service program source file’) Create the CL build program source file CRTSRCPF FILE(MOD_JK/QCLSRC) TEXT(‘Build program source file’) Edit the service program source file STRSEU MOD_JK/QSRVSRC MOD_JK

    In the edited file, specify that only jk_module should be exported : Columns . . : 1 71 Edit MOD_JK/QSRVSRC SEU==> MOD_JK *************** Beginning of data ************************************* 0001.00 STRPGMEXP PGMLVL(*CURRENT) 0002.00 EXPORT SYMBOL("jk_module") 0003.00 ENDPGMEXP ****************** End of data ****************************************

    You could start to build all the modules of mod_jk (cases for V5R4 or previous releases):

    Copy the CL build program source for i5/OS before V5R4 from IFS CPYFRMSTMF FROMSTMF('/home/apache/jk/native/apache-2.0/bldjk.qclsrc') + TOMBR('/QSYS.LIB/MOD_JK.LIB/QCLSRC.FILE/BLDJK.MBR') MBROPT(*REPLACE) Build the CL build program CRTCLPGM PGM(MOD_JK/BLDJK) SRCFILE(MOD_JK/QCLSRC) TEXT('Apache mod_jk build program') Launch the build CALL MOD_JK/BLDJK
    If the build if successfull, copy the new mod_jk module CRTDUPOBJ OBJ(MOD_JK) FROMLIB(MOD_JK) OBJTYPE(*SRVPGM) TOLIB(QHTTPSVR) NEWOBJ(MOD_JK)
    Copy the CL build program source for i5/OS V5R4 from IFS CPYFRMSTMF FROMSTMF('/home/apache/jk/native/apache-2.0/bldjk54.qclsrc') + TOMBR('/QSYS.LIB/MOD_JK.LIB/QCLSRC.FILE/BLDJK54.MBR') MBROPT(*REPLACE) Build the CL build program for i5/OS V5R4 CRTCLPGM PGM(MOD_JK/BLDJK54) SRCFILE(MOD_JK/QCLSRC) TEXT('Apache mod_jk build program') TGTRLS(*CURRENT) Launch the build for i5/OS V5R4 CALL MOD_JK/BLDJK54
    If the build if successfull, copy the new mod_jk module CRTDUPOBJ OBJ(MOD_JK) FROMLIB(MOD_JK) OBJTYPE(*SRVPGM) TOLIB(QHTTPSVR) NEWOBJ(MOD_JK)

    Next, you should restart your Apache 2.0 instance and enjoy this piece of OpenSource on System I.

    ENDTCPSVR SERVER(*HTTP) HTTPSVR(MYSERVER) STRTCPSVR SERVER(*HTTP) HTTPSVR(MYSERVER)

    Mac OS X (10.2.x) build notes :

    Assuming that you are root :

    For Apache 1.3: ./configure --with-apxs=/usr/sbin/apxs cd apache-1.3 make -f Makefile.apxs cp mod_jk.so /etc/libexec/httpd For Apache 2.x: ./configure --with-apxs=/usr/local/apache2/bin/apxs (you should point to the directory where you installed Apache 2.x) cd apache-2.0 make -f Makefile.apxs install

    mod_jk allows to install mod_jk in the Apache source tree to get a statically linked mod_jk. Having mod_jk in the httpd executable brings some performance improvements. The configure option --with-apache prepare mod_jk to install it in the Apache source tree. The option --with-apache works both for Apache 1.3 and Apache 2.x. The examples below show how to get mod_jk in the httpd process.

    /home/apache20/httpd-2.0.43 is the directory where the httpd-2.0 sources are located. ./configure --with-apache=/home/apache20/httpd-2.0.43
    make
    Install the mod_jk library and other files in /home/apache20/httpd-2.0.43/modules: make install
    It is not possible to configure Apache directly because the config.m4 of mod_jk must be added to the configure of httpd-2.x. cd /home/apache20/httpd-2.0.43 sh buildconf configure ... --with-mod_jk make make install

    The enable-jk=share and enable-jk=static are not supported. --with-mod_jk only allow static linking of mod_jk.

    /home/apache/apache_1.3.27 is the directory where the apache-1.3 sources are located. ./configure --with-apache=/home/apache/apache_1.3.27
    make
    Install the libjk library, mod_jk.c, includes and other files in /home/apache/apache_1.3.27/src/modules/jk: make install
    Configure in the Apache sources: cd /home/apache/apache_1.3.27 configure ... --enable-module=dir --disable-shared=dir \ --activate-module=src/modules/jk/libjk.a \ --disable-shared=jk make make install

    The --enable-shared=jk is also working and builds a dso file.

    Just change the configure in the Apache sources: configure ... --enable-module=dir --enable-shared=dir \ --activate-module=src/modules/jk/libjk.a \ --enable-shared=jk
    tomcat-connectors-1.2.41-src/xdocs/webserver_howto/project.xml0000644000000000000020000001152412472604371023060 0ustar rootbin The Apache Tomcat Connectors - Webserver HowTo The Apache Tomcat Connectors - Webserver HowTo tomcat-connectors-1.2.41-src/xdocs/build.xml0000644000000000000020000002143412472633026017265 0ustar rootbin tomcat-connectors-1.2.41-src/xdocs/miscellaneous/0000755000000000000020000000000012555256551020311 5ustar rootbintomcat-connectors-1.2.41-src/xdocs/miscellaneous/doccontrib.xml0000644000000000000020000003016011347450726023157 0ustar rootbin ]> &project; Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. How to Contribute to the Documentation Robert Sowders $Date: 2010-03-15 15:27:18 +0000 (Mon, 15 Mar 2010) $

    This document describes how you can easily contribute to the documentation. I'm going to try to make it easy for everyone to help out with the documentation of Tomcat, more specifically the documentation for the connectors. This is written from a windows user perspective as I believe they will most benefit from it. For people using Unix it should be easy for them to apply these steps. Just substitute Unix syntax where needed.

    The documentation is produced using xml with xsl style sheets. This effectivly seperates the content of the documents from the style, so all that contributers need to worry about the content. It is much easier to use than html.

    It's all really quite simple. Here is what you will need:

    • A recent version of Ant
    • The source code for the connectors from subversion
    • Any ascii text editor

    After you get these tools they are simple to set up.

    Install Ant. The only advice I have is to choose a simple installation path. Now set an environment variable for ANT_HOME, and then add the location of the Ant/bin directory to your PATH variable. Consult your Operating system documentation for information on how to do this. When you are finished verify that you can run ant from the command line.

    Ant is used to build the documentation, among other things, and it must be able to see a file called build.xml. This file is located in the xdocs directory. In the build.xml file there is a target named all that will be used to build the docs.

    Get the sources for tomcat-connectors from the subversion repository. If you'll be editing from a windows platform you will need a windows subversion client. There are several available. I like turtoiseSVN. Unix users should install the subversion client of their choice, if they don't already have one.

    You are ready to download the sources now. Change directory to the location where you want your repository to be. For simplicity we will call this your SVN_HOME. Mine is located in C:\build.

    Run the following command to checkout the sources for the first time. You should only need to do this once. C:\build\>svn checkout http://svn.apache.org/repos/asf/tomcat/jk/trunk/ tomcat-connectors

    You should now be watching all the downloads come in. Now that you have the sources on your machine the hard part is over. From now on, to update your sources all you have to do is cd into any directory in your repository and run the svn update command. To update your xdocs directory simply cd into the xdocs directory and: C:\build\tomcat-connectors\>cd xdocs C:\build\tomcat-connectors\xdocs\>svn update

    Open a command prompt window and cd to the directory where you downloaded the source. Now cd into the xdocs directory so that Ant can see the build.xml file. Then from a command prompt, run the following: C:\build\tomcat-connectors>cd xdocs C:\build\tomcat-connectors\xdocs>ant all

    .

    You should see the ant compiler messages scrolling by rapidly and then stop with the following: [style] Transforming into C:\build\tomcat-connectors\build\docs\news\printer> [style] Processing C:\build\tomcat-connectors\xdocs\news\20041100.xml to C:\build\tomcat-connectors\build\docs\news/20041100.html [style] Loading stylesheet C:\build\tomcat-connectors\xdocs\style.xsl [style] Processing C:\build\tomcat-connectors\xdocs\news\20050101.xml to C:\build\tomcat-connectors\build\docs\news/20050101.html [style] Processing C:\build\tomcat-connectors\xdocs\news\20060101.xml to C:\build\tomcat-connectors\build\docs\news/20060101.html [style] Transforming into C:\build\tomcat-connectors\build\docs> [style] Processing C:\build\tomcat-connectors\xdocs\index.xml to C:\build\tomcat-connectors\build\docs\index.html [style] Loading stylesheet C:\build\tomcat-connectors\xdocs\style.xsl BUILD SUCCESSFUL Total time: 10 seconds C:\build\tomcat-connectors>

    All the xml files present in the xdocs directory structure were transformed to html and copied to the SVN_HOME\tomcat-connectors\build\docs directory. Open one of the html files in your browser and see how it looks.

    I find it easier to use two windows while doing my updates. One I call my build window. I keep this one in the SVN_HOME\tomcat-connectors\xdocs directory and I only run two commands in this window: First I run ant clean Then I run ant all

    My second window I call my edit window and I keep that one in the SVN_HOME\tomcat-connectors\xdocs directory where I'm doing my edits, diffs and svn updates.

    Before you start editing you should always update your local repository to prevent conflicts. You only need to update the xdocs directory C:\build\tomcat-connectors>cd xdocs C:\build\tomcat-connectors\xdocs> C:\build\tomcat-connectors\xdocs>svn update

    Now that your repository is up to date you can begin editing. Find something in the documentation to edit. When you find something remember the name of the file. In your edit window find and edit the xml source file with the same name. After you are done return to the build window, and in the SVN_HOME\tomcat-connectors\xdocs directory run: C:\build\tomcat-connectors\xdocs> ant clean

    This will delete all the previous html files and make the area ready for updated material. Now to make fresh documents that incorporate your changes run: C:\build\tomcat-connectors\xdocs>ant all

    Use your browser to view the edits you just made, they will be in the SVN_HOME\tomcat-connectors\build\docs sub-tree. If it looks good and is ready to go, all that is left to do is to create a patch and submit it.

    From your edit window cd into the directory that contains the xml file you are working on, and run the svn update command. For example, to produce a diff of the index.xml file and call it patch.txt, you would cd into the directory containing the index.xml file and: C:\build\tomcat-connectors\xdocs\>svn diff index.xml > patch.txt.

    Now that you have your patch you are ready to send it in.

    Patches to the documentation are handled just like a bug report. You should submit your patches to http://issues.apache.org/bugzilla/ and include a good one line subject. If this is your first time to use the bug database then you should read http://issues.apach e.org/bugzilla/bugwritinghelp.html. You will need to create a user account. At the web site paste your patch into the web form and don't forget to describe what it is your patch is for. Sooner or later a someone with commit privileges will review your suggestion.

    After you have checked out the sources the first time it is much easier to use subversion. You can cd into any directory of the repository and run svn update to get the latest sources for that directory. For editing purposes you should always update your repository before you start editing to reduce conflicts.

    You will need to run svn diff to generate patches for submission. Again cd into the directory containing the file you are editing and run svn diff name_of_the_file_you_edited > patch.txt to generate a patch for submission.

    Pay attention to the terminal window during the update.

    Lines begining with a A indicate files that have been added.

    Lines begining with a D indicate files that have been deleted.

    Lines begining with a U mean the local copy was patched to update it to the current version in the master repository.

    Lines begining with a G mean your local copy is different from the master copy, and the changes were successfully merged into your copy.

    Lines begining with a C mean there was a conflict in merging the changes and you need to review the file and merge the changes manually. Search for >>>> and merge the changes.

    Lines begining with a ? indicate files that reside on your local system which are not part of the repository. You will normally see this when you are creating new files for submission.

    Only Committers are able to update the web site (http://tomcat.apache.org/connectors-doc/). To do it:

    • Connect to people.apache.org.
    • umask 002
    • Copy the changed files to /www/tomcat.apache.org/connectors-doc/.
    • or use ant from a checkout tomcat/jk/trunk/xdocs repository:
      ant -Dbuild.dir=/www/tomcat.apache.org -Ddist.name=connectors-doc
    • The changes need around 4 hours to be synced to tomcat.apache.org.

    A little help to get you started if you need it

    tomcat-connectors-1.2.41-src/xdocs/miscellaneous/faq.xml0000644000000000000020000002770512472575314021614 0ustar rootbin ]> &project; Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. FAQ Henri Gomez $Date: 2015-02-23 10:02:52 +0000 (Mon, 23 Feb 2015) $

    General Informations and FAQ about JK

    The primary mechanism for support is through the JK documentation included in the doc directory. Documentation is also available on the Apache Tomcat web site devoted to the Apache Tomcat Connectors Project For additional help, the best resource is the Tomcat Users Discussion list. You should start by searching the mail list archive before you post questions to the list. If you are unable to locate the answer to your question in the archive, you can post questions about JK to the user list for assistance. Make sure that you include the version of your Webserver, that you are using as well as the platform you are running on and go here to determine how to subscribe to tomcat mailing list.

    Now that JK moved to the tomcat-connectors repository, the source and the binaries for JK can be downloaded from a mirror at the Tomcat Connectors (mod_jk, mod_jk2) Downloads page.


    JK is a project covering web-servers to Tomcat connectors, whereas mod_jk is the Apache module developed in JK.

    IIS webserversupport is implemented on JK, using a redirector called isapi redirector.

    Netscape/SunONE/Sun webserverwebserver support is implemented on JK, using a redirector called nsapi redirector.

    For JK 1.2.x, you should read :

    For more detailed information, have a look at the Reference Guide. You could also try searching the mailing list archives for "JK" or look at the source.

    Ajp13 is a newer protocol, it's faster, and it works better with SSL. You almost certainly want to use it now that ajp12 is deprecated.

    Also ajp13 is supported by all Apache Tomcat versions starting with Tomcat 3.2.

    Others Servlet engines like jetty have support for Ajp13.

    Ajp13 uses persistant connections where the traffic could be null if there is no request to be sent to Tomcat. Firewalls use to drop inactive connections and will make your web server and Tomcat think the connection is valid.

    Starting with JK 1.2.0, a socket_keepalive property as been added to ajp13 settings, and you should take a look at it in Workers HowTo and workers.properties reference. If nothing else helps, you can try JkOptions +DisableReuse, but this will have strong performance implications.

    Under heavy load, Apache Web Server creates many children to handle the load, which will in turn create many connections to Tomcat to forward the requests they should handle. Apache Web Server will normally kill the children/threads when the load decreases. But if the load is still there and even if only Apache handles the requests, ie static contents, the children are kept and with them all the ajp13 connections, even if they are no more used.

    To close connections after some time of inactivity you can use connection_pool_timeout, for more informations refer to workers.properties reference.

    Informations and FAQ about mod_jk and Apache Web Servers.

    The Ajp13 protocol keeps an open socket between Tomcat and Apache. Release of mod_jk present in J-T-C handles the network failure. But with very ancient releases of mod_jk, you may have to restart Apache as well.

    Many versions of Apache use a modified API, known at Extended API, developed for use with the mod_ssl module. Starting with Apache 2.0 there is no more difference.

    For example, Apache 1.3 present in certains recent Linux distributions include the mod_ssl module.

    So if you got such 'Extended Apache', you need to use mod_jk.so-eapi.

    You should use mod_jk.so-noeapi only for 'Standard Apache' (ie without mod_ssl).

    It's wise to avoid using EAPI modules on STD API Apache or to use standard API modules on EAPI Apache. Allways be sure to have the mod_jk.so witch match your version of Apache

    It's related to Apache EAPI, the message 'mod_jk.so is garbled - perhaps this is not an Apache module DSO ?' just told you, that your're trying to install a mod_jk.so DSO module that was compiled on an Apache using EAPI, like apache-mod_ssl or apache from Redhat distro 6.2/7.0 but your system use the standard apache with normal API.

    Also related to EAPI, the message '[warn] Loaded DSO /usr/lib/apache/mod_jk.so uses plain Apache 1.3 API, this module might crash under EAPI! (please recompile it with -DEAPI)', the mod_jk.so was compiled under normal Apache with standard API and you try to install the module on an Apache using EAPI.

    APXS is a Perl script that is created when you build the Apache web server from source. Chances are that if you are getting these errors and you obtained Apache as a binary distribution, that APXS is not configured correctly for your system. Your best bet is to get the Apache source from http://httpd.apache.org and build it yourself. Use the following for a basic build (read the Apache docs for other options): cd /usr/local/src
    gzip -dc apache_1.3.19.tar.gz|tar xvf -
    cd apache_1.3.19
    ./configure --prefix=/usr/local/apache \
    --enable-module=most \
    --enable-shared=max
    make
    make install

    Note: The above steps assume that you downloaded the Apache source and placed it in your /usr/local/src directory.

    Since the Apache API can change between versions, any Apache module contains the Apache API version used to compile the module. This is called the Magic Module Number.

    At start time Apache checks that the version in the module header is compatible with the Apache server. If not it will deny to start and log an error.

    Note that minor versions are forward compatible. If the module was compiled using Apache 2.x.y the resulting binary should work with any other version 2.x.z where z is bigger or equals to y. If you also need compatibility for versions 2.x.z with z smaller than y, use the configure flag --enable-api-compatibility. Note that the module compiled with any 2.x will never be compatible with 2.y for x different from y.

    mod_jk works well with Apache 2.x from 2.0 to 2.4.

    Important parts of the functionality of mod_jk have been reimplemented as Apache httpd modules mod_proxy_ajp and mod_proxy_balancer. These are part of the standard distributoin of Apache 2.2. The new modules do not contain all features of mod_jk, but you get them automatically with every Apache 2.2 and later.

    JNI workers have been deprecated. They will likely not work. Do not use them.

    JNI support requires a multi-threaded environment which is not the general case for Apache 1.3. You should verify if Apache 1.3 has been build with thread support and if not you could add the the pthreads library to your httpd.conf file.

    # Add pthread to Apache in httpd.conf LoadModule "/usr/lib/libpthreads.so"

    Also keep in mind that JNI is suited for multi-threaded servers and you should consider upgrading to Apache 2.x to support JNI.

    JNI workers have been deprecated. They will likely not work. Do not use them.

    Under Linux, you should set some environment variables BEFORE launching your Apache server :

    export LD_LIBRARY_PATH=$jre/bin:$jre/bin/classic:$LD_LIBRARY_PATH

    Also some Linux distributions have enabled a GLIBC feature called 'floating stacks' which may not works with kernel less than 2.4.10 on SMP machines. You should disable floating stacks by exporting an environment variable :

    export LD_ASSUME_KERNEL=2.2.5

    You could have to update your service scripts, ie /etc/rc.d/init.d/httpd, to set these env vars before your httpd server starts.

    configure assume you have some GNU tools already installed and configured for your system, and ad minima libtool.

    Also some systems may have mixed cc and gcc setup which may make you puzzled when trying to link an Apache built with native c compiler with a jk/jk2 build with gcc.

    In case the make processing doesn't work as expected, you should use a GNU make gmake.

    tomcat-connectors-1.2.41-src/xdocs/miscellaneous/reporttools.xml0000644000000000000020000000664211266621226023430 0ustar rootbin ]> &project; Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Reporting Tools Glenn Nielsen $Date: 2009-10-18 15:13:42 +0100 (Sun, 18 Oct 2009) $

    The mod_jk source distribution contains two perl scripts in the tools/reports directory which can be used to analyze the mod_jk logs, save statistical data, and generate report graphs.

    tomcat_trend.pl log_dir archive_dir

    Script for analyzing mod_jk.log data when logging tomcat request data using the JkRequestLogFormat Apache mod_jk configuration. Generates statistics for request latency and errors. Archives the generated data to files for later use in long term trend graphs and reports.

    tomcat_reports.pl archive_dir reports_dir

    Script for generating reports and graphs using statistical data generated by the tomcat_trend.pl script. The following graphs are created:

    • tomcat_request.png - Long term trend graph of total number of tomcat requests handled.
    • tomcat_median.png - Long term overall trend graph of tomcat request latency median.
    • tomcat_deviation.png - Long term overall trend graph of tomcat request mean and standard deviation.
    • tomcat_error.png - Long term trend graph of requests rejected by tomcat. Shows requests rejected when tomcat has no request processors available. Can be an indicator that tomcat is overloaded or having other scaling problems.
    • tomcat_client.png - Long term trend graph of requests forward to tomcat which were aborted by the remote client (browser). You will normally see some aborted requests. High numbers of these can be an indicator that tomcat is overloaded or there are requests which have very high latency.

    A great deal of statistical data is generated but at this time only long term trend graphs are being created and no reports. This is only a start. Many more graphs and reports could be generated from the data. Please consider contributing back any new reports or graphs you create. Thanks.

    These perl scripts depend upon the following perl modules and libraries:

    • GD 1.8.x graphics library http://www.boutell.com/gd/
    • GD 1.4.x perl module
    • GD Graph perl module
    • GD TextUtil perl module
    • StatisticsDescriptive perl module

    tomcat-connectors-1.2.41-src/xdocs/miscellaneous/project.xml0000644000000000000020000001156412472604371022503 0ustar rootbin The Apache Tomcat Connectors - Miscellaneous Documentation The Apache Tomcat Connectors - Miscellaneous Documentation tomcat-connectors-1.2.41-src/xdocs/miscellaneous/jkstatustasks.xml0000644000000000000020000001722210772307412023745 0ustar rootbin ]> &project; Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Status Worker Ant Tasks Peter Rossbach $Date: 2008-03-25 23:47:22 +0000 (Tue, 25 Mar 2008) $

    Since version 1.2.19 the JK release contains additional ant tasks. They can be used to manage the JK web server plugins via the special status worker.

    <?xml version="1.0" encoding="UTF-8"?> <project name="modjk-status" xmlns:jk="urn:org-apache-jk-status" default="status" basedir="."> <property name="profile" value=""/> <property file="jkstatus${profile}.properties"/> <property file="jkstatus.properties.default"/> <path id="jkstatus.classpath"> <fileset dir="${catalina.home}/bin"> <include name="commons-logging-api-*.jar"/> </fileset> <pathelement location="${catalina.home}/server/lib/catalina-ant.jar"/> <pathelement location="../dist/tomcat-jkstatus-ant.jar"/> <pathelement location="${catalina.home}/server/lib/tomcat-util.jar"/> </path> <typedef resource="org/apache/jk/status/antlib.xml" uri="urn:org-apache-jk-status" classpathref="jkstatus.classpath"/> <target name="status" > <jk:status url="${jkstatus.url}" username="${jkstatus.username}" password="${jkstatus.password}" resultproperty="worker" echo="off" failOnError="off"/> <echoproperties prefix="worker" /> </target> </project>

    [echoproperties] #Ant properties [echoproperties] #Sun Dec 10 20:40:21 CET 2006 [echoproperties] worker.node01.lbmult=1 [echoproperties] worker.loadbalancer.lock=Optimistic [echoproperties] worker.node02.transferred=0 [echoproperties] worker.loadbalancer.sticky_session=false [echoproperties] worker.node01.distance=0 [echoproperties] worker.node01.client_errors=0 [echoproperties] worker.node02.lbmult=1 [echoproperties] worker.node01.port=7309 [echoproperties] worker.node01.elected=0 [echoproperties] worker.loadbalancer.good=2 [echoproperties] worker.loadbalancer.method=Sessions [echoproperties] worker.server.port=2090 [echoproperties] worker.loadbalancer.map.2.type=Wildchar [echoproperties] worker.node02.route=node02 [echoproperties] worker.node01.route=node01 [echoproperties] worker.node01.lbvalue=0 [echoproperties] worker.node01.lbfactor=1 [echoproperties] worker.node01.max_busy=0 [echoproperties] worker.node01.busy=0 [echoproperties] worker.node01.redirect= [echoproperties] worker.node02.distance=0 [echoproperties] worker.loadbalancer.name=loadbalancer [echoproperties] worker.loadbalancer.sticky_session_force=false [echoproperties] worker.node02.state=N/A [echoproperties] worker.node01.state=N/A [echoproperties] worker.node01.transferred=0 [echoproperties] worker.loadbalancer.map.length=2 [echoproperties] worker.node01.type=ajp13 [echoproperties] worker.node01.address=127.0.0.1\:7309 [echoproperties] worker.result.type=OK [echoproperties] worker.loadbalancer.member_count=2 [echoproperties] worker.loadbalancer.map_count=2 [echoproperties] worker.loadbalancer.mtime_to_maintenance_min=12 [echoproperties] worker.loadbalancer.mtime_to_maintenance_max=75 [echoproperties] worker.node02.lbfactor=1 [echoproperties] worker.node02.max_busy=0 [echoproperties] worker.jk_version=mod_jk/1.2.21-dev [echoproperties] worker.loadbalancer.bad=0 [echoproperties] worker.node02.redirect= [echoproperties] worker.node01.host=localhost [echoproperties] worker.node02.activation=ACT [echoproperties] worker.loadbalancer.map.1.source=JkMount [echoproperties] worker.loadbalancer.retries=2 [echoproperties] worker.node02.elected=0 [echoproperties] worker.loadbalancer.map.2.source=JkMount [echoproperties] worker.node02.port=7409 [echoproperties] worker.loadbalancer.length=2 [echoproperties] worker.node02.lbvalue=0 [echoproperties] worker.loadbalancer.degraded=0 [echoproperties] worker.loadbalancer.map.1.type=Wildchar [echoproperties] worker.loadbalancer.map.2.uri=/myapps* [echoproperties] worker.node02.client_errors=0 [echoproperties] worker.length=1 [echoproperties] worker.node01.domain=d20 [echoproperties] worker.loadbalancer.recover_time=60 [echoproperties] worker.server.name=localhost [echoproperties] worker.node02.domain= [echoproperties] worker.result.message=Action finished [echoproperties] worker.node02.busy=0 [echoproperties] worker.node01.readed=0 [echoproperties] worker.node01.errors=0 [echoproperties] worker.node02.address=127.0.0.1\:7409 [echoproperties] worker.node02.readed=0 [echoproperties] worker.loadbalancer.busy=0 [echoproperties] worker.web_server=Apache/2.0.59 (Unix) mod_jk/1.2.21-dev [echoproperties] worker.node02.errors=0 [echoproperties] worker.node02.type=ajp13 [echoproperties] worker.loadbalancer.map.1.uri=/ClusterTest* [echoproperties] worker.node01.activation=ACT [echoproperties] worker.loadbalancer.max_busy=0 [echoproperties] worker.loadbalancer.type=lb [echoproperties] worker.node02.host=localhost

    <target name="updatelb" > <jk:updateloadbalancer url="${jkstatus.url}" username="${jkstatus.username}" password="${jkstatus.password}" loadbalancer="loadbalancer" method="Busyness" retries="2" recoverWaitTime="60" lock="Optimistic" forceStickySession="false" stickySession="false"/> </target>

    <target name="updatew" > <jk:updateworker url="${jkstatus.url}" username="${jkstatus.username}" password="${jkstatus.password}" loadbalancer="loadbalancer" worker="node01" lbfactor="2" activation="Active" redirect="" domain="" route="node01" distance="0"/> </target>

    <target name="reset" > <jk:reset url="${jkstatus.url}" username="${jkstatus.username}" password="${jkstatus.password}" loadbalancer="loadbalancer" worker="node01" /> </target>

    tomcat-connectors-1.2.41-src/xdocs/miscellaneous/changelog.xml0000644000000000000020000030644112555240755022771 0ustar rootbin ]> &project; Mladen Turk Rainer Jung Henri Gomez Tim Whittington Changelog

    This is the Changelog for Apache Tomcat Connectors. This changelog does not contain all updates and fixes to the Tomcat connectors (yet). It should contain fixes made only after November 10th 2004, when the new documentation project for JK was started.


    AJP, LB: Reduce lock contention during maintenance function. This was observable when using a big number of AJP13 and LB workers, especially in combination with the Apache httpd prefork MPM. (rjung) 57060: Allow building from outside of source tree. Patch contributed by Petr Sumbera. (rjung) 56703: Status: Fix inflated counter for current number of backend connections especially when a connection timeout occurred on the backend. (rjung) 56661: Fix Servlet API getLocalAddr(). Works for Tomcat 6.0.42, 7.0.55 and 8.0.11 and Apache and ISAPI plugins. (rjung) Status: Log old and new values when changing worker attributes. (rjung) 56667: Status: Fix log message when changing activation state of all members. (rjung) 56565: Fix IPV6 address resolve on non-dual network stacks. (mturk) 50511: Reduce log level for "OPTIONS *" requests from warning to debug. (rjung) Apache: Copy log notes instead of using references to prevent access to memory from closed pool. (rjung) Add option to control handling of multiple adjacent slashes in mount and unmount. New default is collapsing the slashes only in unmount. Configuration is done via new JkOption for Apache ("CollapseSlashesAll", "CollapseSlashesNone" or "CollapseSlashesUnmount") and via property "collapse_slashes" for IIS (values "all", "none", "unmount"). This is the fix for CVE-2014-8111. (rjung) Add more checks for shared memory allocation. (rjung) 56869: Status: Add maximum number of open backend connections to status worker. Patch contributed by Martin Knoblauch. (rjung) 56770: AJP: Add worker name to all log messages. Patch contributed by Martin Knoblauch. (rjung) 50186: Docs: Clarify relation between "connection_pool_timeout" and "keepAliveTimeout" or "connectionTimeout" in the Tomcat AJP connector configuration. (rjung) 52334: LB: Calculate worker recovery time based on last recovery attempt time instead of original error time after the first recovery attempt. (rjung) 54596 part 1: IIS: Fix missing last character when parsing relative file names with no ".." directory components from configuration. (rjung) 54596 part 2: IIS: Fix using relative file names in config with ".." path segments that go up the directory hierarchy higher than the starting point of the relative file name. (rjung) Status: Add logging if status worker output was dropped due to insufficient buffer size. (rjung) Reduce log buffer from 8KB to 1KB. Add logging in case of failed logging and add trailing "..." to lines which were likely truncated. (rjung) Replace fixed allocation of 32 entries for fail_on_status by dynamic allocation. (rjung) Enforce implementation restriction on maximal length "60" of worker attributes "name", "host", "route", "domain", "redirect", "session_cookie", "session_path" and "set_session_cookie". Checks were added to configuration file processing and configuration updates via the status worker. (rjung) 52483: Apache: Add debug logging for result of JkOptions configuration processing. (rjung) 54177: Status: Use numeric time stamps instead of textual ones to avoid non-well-formed XML output. Textual timestamps are formatted according to locale settings and reencoding them to UTF-8 would be cumbersome. (rjung) 56618: Status: Use percent decoding when reading query string parameters. For example this fixes editing IPv6 addresses via the status worker if the client encodes ":" as "%3A". Patch contributed by Christopher Schultz. (rjung) 56452: Fix crash in debug logging for IPv6 adresses. Patch contributed by Christopher Schultz. (rjung) 34526: Apache: Improve compatibility with mod_deflate request body inflation. An automatic detection of mod_deflate inflation is not implemented. Use the new Apache environment variable JK_IGNORE_CL instead, to let mod_jk ignore an existing Content-Length request header. (rjung) 44454: LB: Add warning to docs about problems with "busyness" load balancing method. (rjung) 44454: Improve busy counter by using atomics. (rjung) 56703: Status: Improve connected counter. Use atomics and for mod_jk (Apache) currectly count down connections closed by child processes that are stopped. (rjung) 44571: Ensure that we return with status 503 if we can not get and endpoint for a worker. (rjung) Apache: Improve log handling during graceful or normal restart. (rjung) Don't update last access time of worker connections during optional checking of idle connections using CPing. Updating the time stamp breaks closing idle connections. (rjung) Adjust linger parameters used during connection shutdown. (rjung) Fix annoying redefine warnings for the autoconf PACKAGE defines during configure based builds. (rjung) Status: Use multi-line table headers and fix invalid xml output. (rjung) 44571: Implement an optional limit on concurrent requests allowed for a worker (attribute "busy_limit"). Original patch contributed by zealot0630 at gmail dot com. (rjung) Correct log message "all endpoints are disconnected" to "no usable connection found, will create a new one". Tone done from info log level to debug for the common case. (rjung) 57536: AJP: Allow to configure connection source address. This should only be used on multi-homed hosts. The feature is experimental. (rjung) 57540: AJP: Forward name of SSL protocol used for handling the request (SSLv3, TLSv1, TLSv1.1, TLSv1.2). (rjung)

    Fix forwarding of chunked requests, which is broken in version 1.2.39. (rjung) 56352: Fix regression in memory release. (mturk) Fix status worker display of worker IP address after name or port was changed. (rjung) 56297: Improve key hash function. Copied from APR. (rjung) 55683: Remove quotes from quoted session cookies. (rjung) 53542: ISAPI: Fix grammar in 503 error page. (rjung) 55696: Crash on Mac OS X 10.9 during config parsing. (rjung)

    Deprecate nt_service from Apache Tomcat Connectors. (mturk) 56133: Fix possible crash when a request fails during request body transfer to the back end and reply_timeout was set. Patch contributed by Hiroto Shimizu. (rjung) Fix status worker not updating parameters for all members. (mturk) 55853: HTTPD: Use the correct API for setting Content-Length. Patch contributed by areese yahoo-inc.com. (rjung) Add IPV6 support for connection to webserver. New directive prefer_ipv6 has been added to control the hostname resolution and preserve backward compatibility. (mturk) Add --disable-sock-cloexec to configure to disable use of SOCK_CLOEXEC (using FD_CLOEXEC + fnctl instead) so built modules will work with Linux kernels prior to 2.6.27. (timw) Clean up config file parsing. Worker names are now restricted to 60 bytes. (rjung) Allow to set a stickyness cookie in case a web framework breaks Tomcat's adding of the routing ID to the end of the JSESSIONID cookie. (rjung) Use max_packet_size also for request body forwarding. (rjung) Apache 2.4: By default forward logical client address as provided by mod_remoteip. When setting JkOptions ForwardPhysicalAddress mod_jk will instead forward the physical peer address. (rjung) Minor documentation improvements. (rjung)

    Fix regression which can crash webserver in case worker is defined both as member of load balancer and as standalone worker. (mturk) Fix core if debug log level is specified and there is no session identifier present. (mturk)

    Use named shared memory objects so that we preserve runtime configured data instead of resetting on each child creation. (mturk) Fix dead-lock caused by not releasing mutex on close. (mturk) Fix compilation of mod_jk for HTTPD 1.3. (rjung) 46893: HTTPD 1.3: Apply fix to HTTPD 1.3. It was fixed for HTTPD 2.x already in version 1.2.30. (rjung) HTTPD 1.3: Allow to set path parameter used when doing JkStripSession. This was available for HTTPD 2.x already since mod_jk 1.2.27. (rjung)

    HTTPD: Fix crash on unknown worker names. (mturk) IIS: Fix crash on worker process recycle. (mturk) 52659: IIS: Fix shared memory corruption. (mturk) 52921: HTTPD: Fix crash in uri mapping. (mturk)

    52793: AJP: Fix default value of forwarded worker activation state. Contributed by Yoshihito Fukuyama. (rjung) HTTPD: Improve support for HTTPD 2.4 by using client_* instead of remote_* variables. (rjung) 52564: Fix building with format checking gcc security hardening cflags. Contributed by Tony Mancill. (rjung) 52567: Balancer member in recovery state can switch back into error state if it is idle. (rjung) Log error if unable to load URI workermap file, and improve logging of unreadable worker files on IIS. (timw) Remove deprecated JNI worker and build dependency on Java SDK. (mturk) 51253: Forward WWW-Authenticate header when using server generated error pages (rjung, mturk). 46406: IIS: Support relative paths in configuration. The paths are presumed to be relative from isapi_redirect.dll. (mturk) 50233: Do not use hard limit on uri size (mturk). IIS: Use Windows Server 2003 SP1, Windows XP SP2 as minimal version supported. (mturk) 47038: Fix compiler warning when using --enable-flock for configure. (rjung) 51326: URI Map: Add "session_cookie" and "session_path" rule extensions. Contributed by Eiji Takahashi. (rjung) 51333: IIS: Document configuration requirement for 64 Bit environment. (rjung) 51743: HTTPD: Support rule extensions when defining the request worker with an environment variable (e.g. JK_WORKER_NAME). (rjung) 51769: IIS: Allow URIs which contain "META-INF" or "WEB-INF" as long as they are not path components of the URI. (rjung) 52056: HTTPD: JK request log does not always log correct response status. Fixed by refactoring JK request log to use the standard request log hook. (rjung) HTTPD: Allow to choose a sticky worker using the environment variable JK_ROUTE. This can be used if sessions and routes are send with the request in a non-standard way. (rjung) URI Map: Add "sticky_ignore" extension attributes to uri worker map. It allows to disable stickyness for individual mounts. (rjung) HTTPD: Allow dynamic disabling of stickyness using the environment variable JK_STICKY_IGNORE. This can be useful to break cookie stickyness for non-sticky requests like login forms. (rjung) LB: New balancing method "Next" to distribute sessions in a round-robin way. (rjung) LB: Add counter for created sessions to status worker and HTTPD notes. It actually counts the number of requests that do not carry a session id. (rjung) URI Map: Add "stateless" extension attributes to uri worker map. This can improve session load balancing. (rjung) HTTPD: Allow dynamic switching of requests to "stateless" using the environment variable JK_STATELESS. (rjung) AJP: Improve logging when request does not fix into an AJP packet. (rjung)

    51417: Fix worker busy detection by querying the worker endpoint. Abandoned connections can leave a worker in busy state without decrementing busy counter. (mturk) 50339: Fix whitespace trimming when parsing attribute lists. (rjung) 41263: Support Servlet API getRemotePort(). Works for Tomcat 5.5.28, 6.0.20 and 7.0.0 and Apache and ISAPI plugins. (rjung) 41923: AJP: Close AJP connection to Tomcat on client write error when recovery_options 4 is specified, aborting the response write on the Tomcat side. (timw) AJP: Cap the lingering bytes that will be read when shutting down an AJP socket at 32k to prevent CPU spikes in the web server when a client aborts on a large response body. Also reduce total linger time to 2s. (timw) 50839: AJP: Fix 30sec CPU spike due to incorrect counting of lingering bytes causing a busy loop when a client aborts connection during a response write. Fixes regression in 1.2.31. (timw) LB: Forward worker activation state as request attribute "JK_LB_ACTIVATION". Possible values are "ACT" (active), "DIS" (disabled) and "STP" (stopped). (rjung) HTTPD: Forward WWW-Authenticate from backend when status is 401 and server generated error pages are used. (rjung) 50363: IIS: Prevent chunk encoding of empty message bodies for 204, 205 and 304 responses. (timw) 50975: IIS: Fix hanging of Transfer-Encoding: chunked requests when Content-Length header is present in request as well. Also addresses situation where IIS appears to create a Content-Length header for a small chunk encoded request when none was present in the original request. (timw) 47679: IIS: stop truncation of request headers when ISAPI redirector used as an extension without the corresponding filter installed. (timw) NSAPI: Use lower case header names for responses. Otherwise the web server might add chunked transfer encoding header in addition to our content length header. Docs: Improve load balancer documentation. (rjung)

    49413: AJP13: Drop flush packets send by the backend after the response has been finished. (rjung) AJP: Log the local and remote socket address. (mturk) Watchdog: Move the maintain workers outside the critical section allowing other threads to use the connection pool during maintenance. (mturk) Common: Add svn revision to init log message. (rjung) Common: Don't destroy errno during trace logging. (rjung) Apache: Add support for Apache 2.3/2.4. (rjung) Apache: Added version number resource for mod_jk.so on Windows. (timw) 48501: IIS: Added rotatelogs style log rotation to ISAPI Redirector. (timw) 38895: IIS: Use RAW headers instead of CGI headers by default to prevent conversion of underscores '_' to hyphens '-' in header names. Old behaviour can be enabled by defining USE_CGI_HEADERS. (timw) 49511: IIS: Do not override IIS log information when subsequent requests on a keep-alive connection are not mapped into the ISAPI Redirector. (timw) Docs: Document SSLOptions needed for SSL information forwarding. (rjung) Docs: Grammar and style improvements and clarification about serving static content by IIS. Patch provided by André Warnier. (rjung) Docs: Update subversion paths used in docs. (rjung)

    Apache: Improve compatibility with Apache 2.3. (rjung) 46632: Apache: Do not register child cleanup for our pools. (mturk) 46893: Apache: Log warning only if JkShmSize was actually set in the configuration. (mturk) IIS: Include optional chunking support. Off by default. (mturk) 48763: IIS: Do not send Content-Length when using chunked encoding or length larger 4GB. (mturk) 48223: IIS: Propagate correct backend error code to IIS. (rjung) 47867: IIS: crash during startup, when compiled with VS2008 and workers.properties contains unsupported properties. Patch provided by Indrek Juhani (rjung) 47628: IIS: Fix deadlock when restarting the Application Pool caused by not releasing the critical section lock. Patch provided by Bret Prucha. (mturk) IIS/NSAPI: Correct log file flushing after each line. (mturk) NSAPI: Add Microsoft Visual C++ Makefile. (mturk) AJP: Improve socket shutdown handling. (mturk) AJP: Ensure we never reuse a non reusable socket. (mturk) AJP: Tolerate a single excess packet when waiting for cpong. (mturk) AJP: Check protocol correctness more strictly. (mturk) 48410: AJP: Use poll instead select so we can work with more then 1024 sockets. (mturk) 46503: AJP/Status: Garbage data in worker domain and route. (mturk) 48276: AJP: When worker contact cannot be resolved mark the worker as disabled instead failing to start the server. (mturk) 48169: AJP: Improve CGI interoperability by closing all sockets during EXEC. (mturk) Status: Add number of open backend connections to status worker. This feature is experimental, the displayed value might not be accurate. (mturk) 47224: Status: When address gets changed invalidate all opened sockets in the endpoint cache. This will cause new backend connections to get opened using new address. (mturk) 48305: Status: Do not show "secret" property when doing dump. (mturk) 45610: Status: Don't accept requests with empty value for sub worker parameter. (rjung) 45610: Status: Fix erroneous unsetting of sticky_session and sticky_session_force when updating other load balancer attributes via the status worker. (rjung) 47222: Status: Add ping_timeout to the shared memory and allow dynamic configuration. (mturk) Status: Remove duplicate "errors" line in property view of AJP13 workers that are part of a load balancer. (rjung) LB: Fix route logging. (rjung) Logging: Automatically detect size of thread id for logging. (rjung) Logging: Add optional log file locking for Windows when defining JK_LOG_LOCKING. (mturk) Configuration: Update example configuration. (rjung) Docs: Update information about tools needed to create a release. (rjung) 47983: Docs: Fix typo in example config which breaks startup. (rjung) Build: Force copy of automake files. (rjung) Build: Tomcat code repository structure cleanup reflected in documentation and build script. (rjung, mturk)

    Apache: Add more environment variables to overwrite request information. Useful in case a proxy is in front of Apache and sends us original request information e.g. via custom headers. (rjung) Apache: No longer preallocate entries for JK request log. (rjung) 46352: Apache: Fix crash when using SetHandler jakarta-servlet in VHost without any JkMount. Crash due to incorrect initialization of mount extensions. (rjung) Apache: JkWatchdogInterval had wrong interval calculation causing a 10 times higher watchdog interval then configured. (mturk) Apache: Activate forwarding of SSL key size by default. (rjung) 46169: Apache 1.3: Backport use_server_errors mount extension. (rjung) 46763: Apache 2.0: Survive the log mutex during graceful restart. Patch provided by Eiji Takahashi. (mturk) 46416: Apache 2.0 on Windows: Include mstcipip.h even if the apr doesn't include it. (mturk) IIS: Update uriworkermap.properties file on a regular interval. This requires both worker_mount_reload and watchdog_interval to be defined. (mturk) IIS: Remove obsolete entries from registry file. (mturk) 46579: IIS: Use local environment table instead environment variables for setting the JKISAPI_PATH and JKISAPI_NAME. (mturk) LB: Add new property error_escalation_time to fine tune escalation of local errors to global errors. (rjung) LB: If the sticky session affinity mark contains a dot, treat the part before the dot as the domain name. This allows to have full node session affinity with domain failover. (mturk) LB: make forced recovery work with local error states. (rjung) LB: Only update error state and error time, if we actually have a new state. (rjung) LB: Set global worker state to error when we reach max_reply_timeouts, or fail_on_status triggered hard error. (rjung) AJP: Add a new error type JK_AJP_PROTOCOL_ERROR. (mturk) AJP: Allow worker ports lower or equal to 1024. (rjung) AJP: Improve some AJP error log messages. (mturk) Status: Allow changing worker address and port of AJP workers. The address is resolved on next request for that worker. (mturk) Status: Allow update actions to show error messages in the result page. (rjung) Status: Refactor update actions. (rjung) Status: Do not redirect to the show or list page, if an error occured during an action. (rjung) Status: Include error time in display. (rjung) Status: Remove redundant port information from worker display. Rename address column and remove its explanation from the legend. (rjung) Status: Optimize forced uriworkermap.properties reload. (mturk) Status: Fix crash in text display. (rjung) Status: Show - Edit - Show always ends in single lb member show, even when started from all members lb show. (rjung) Status: Wildcards in sub worker names were broken for update actions. (rjung) Status: Add use_server_errors to map display. (rjung) SHM: Move locking into the data pull and push methods. (rjung) JNI: Deprecate JNI workers. (rjung) Netware: Missing define for MAX_PATH. Patch by Guenter Knauf. (rjung) Docs: Add a new HowTo page about reverse proxies. (rjung) Docs: Add an explanation of local error states to the timeouts documentation. (rjung) Docs: Clarify relation between socket_timeout and socket_connect_timeout. (rjung) Docs: Clarify IIS URL rewrite feature. (rjung) 46834,46734: Docs: Fix a couple of missing or broken links. (markt,rjung) Docs: Add 2008 news to main page and menues. (mturk, rjung)

    46109: Decay reply_timeouts even when lb method is busyness. Also reset reply_timeouts during forced recovery. (rjung) AJP13: Recycle connection if previous request didn't complete. (mturk) Maintain should not run multiple times in parallel. (mturk) Apache: Fix small memory leak during restart. (mturk) Improve signal handling during socket shutdown. (mturk) URI Map: Add debug dump function for uri worker map. (rjung) Add revision number to version info for non-release builds. (rjung) IIS: Optionally allow chunked encoding for responses. At the moment only usable, if build with ISAPI_ALLOW_CHUNKING defined. Based on patch by Tim Whittington. (rjung) IIS: Optionally use raw headers instead of CGI headers. Fixes problem "underscore=dash" problem in header names. At the moment only available, if build with USE_RAW_HEADERS defined. (rjung) IIS: Optionally improve IIS 5.1 compatibility. At the moment only available, if build with AUTOMATIC_AUTH_NOTIFICATION defined. Based on patch by Tim Whittington. (rjung) IIS: Fix memory corruption due to parallel initialization by multiple threads. (rjung) Windows: Use non-default socket keepalive interval. (mturk) IIS: Add environment variables JKISAPI_PATH and JKISAPI_NAME. (mturk) Added socket_connect_timeout directive for setting the connect timeout for the socket. This enables to have low connection timeout but higher operational timeouts. (mturk) AJP13: [CVE-2008-5519] Always send initial POST packet even if the client disconnected after sending request but before providing POST data. In that case or in case the client broke the connection in a middle of read send an zero size packet informing container about broken client connection. (mturk) AJP13: Added connection_acquire_timeout directive for setting the absolute timeout the worker will wait for a free endpoint. (mturk) Apache: Allow to set path parameter used when doing JkStripSession. (mturk) Refactor retries implementation and change semantics of retries attributes. (mturk) Status: Allow showing only a single member for a load balancer. (rjung) Status: Add display of seconds since last statistics reset and access and transfer rates. (rjung) AJP13: Add a configurable retry_interval time. (rjung) Documentation: Enhance description of connection_pool_size. (rjung) IIS: Refactor error page generation. (mturk) IIS: SERVER_NAME variable can be the same for multiple different server instances if requests are handled according to the ip:port combination. Use INSTANCE_ID variable to which the request belongs instead. (mturk) Allow forwarding server error pages. This can be done on per-uri basis using new use_server_errors extension. (mturk) Added session_cookie and session_path for configuring default session identifiers. (mturk) Use max_packet_size also as TCP send and receive buffer size. (mturk) Apache: Do not allow Apache to start in multi-threaded mode if mod_jk was only build for single threaded server (prefork). (mturk) 45812: Add done() service method that causes sending EOS bucket for Apache httpd 2.x. This allows filter chain to work properly. (mturk) Added connection_ping_interval, ping_timeout and ping_mode directives. (mturk) Apache: Use correct ld flags provided by apxs when building module. Prevents some crashes on AIX for httpd 1.3 module. (rjung) Documentation: "val" attribute numbering in status worker needs to start with 0 instead of 1. (rjung) Documentation: Remove JNI parameters from sample configuration in the workers common howto. (rjung) 45026: For Apache httpd 2.x add "Unknown Reason" as the reason phrase, if we get an empty one from the backend. Otherwise httpd 2.x returns status 500. (rjung) Build: Fix Cygwin build. (rjung) Documentation: Add info to docs, that variables sent via JkEnvVar are not listed in request.getAttributeNames(). (rjung) Add watchdog background thread for Apache 2.x and IIS doing internal maintenance (idle connection checks, backend probing). See JkWatchdogInternal (Apache) and watchdog_interval (IIS). (mturk) Change log level of some messages from error to info. (mturk) Documentation: Fix docs for worker attribute "secret". (rjung) Detect correct plugin name for various web servers via additional preprocessor defines. (rjung) LB: Do not put loadbalancer node in error state if there is opened channel. This fixes the bug when new connection fails due to busyness, causing opened connections fail stickyness. This brings back per-node busy counter and private state array for each request. We can mark the state as error for failover to work while still operating and reporting node as OK if there are opened working connections. (mturk) 44738: Fix merging of JkOption ForwardURI* between virtual hosts. Patch contributed by Toshihiro Sasajima. (rjung) URI Map: Add extension attributes to uri worker map. Allowed are reply_timeout, active/disabled/stopped and fail_on_status. Usage currently only implemented for httpd and IIS. (rjung+mturk) URI Map: Make dynamic reloading atomic and free memory not needed any longer. (rjung) Configure: Don't use post httpd 2.2.0 API functions when building with new --enable-api-compatibility configure switch. (rjung) Apache: JkAutoAlias does not work in combination with JkMountCopy if there are no JkMount in virtual host. (rjung) LB: Optimize state macros to improve performance. (rjung) Apache: Allow dynamic setting of reply timeout using the environment variable JK_REPLY_TIMEOUT. (rjung) Status: Add manageability for ajp parameters of ajp workers and ajp lb members. (rjung) Status: Change parameter names of update action to make them more easily distinguishable from other parameters. (rjung) Status: Add ajp worker statistics also for workers, that are not lb members. (rjung) AJP: Refactor factories, move ajp13/ajp14 common parts into ajp_factory. (rjung) Status: Only sync shm worker config values of the workers for which we changed values. (rjung) Status: Set lb_factor instead of distance. (rjung) Status: Minor layout changes, use drop down instead of multiple text links. (rjung) SHM: Use local copies of read mostly attributes of lb sub workers in lb and status worker. (rjung) Status: Add "dump" action to dump our initial configuration. (rjung) Status: Use property table to decide which cmd action uses which output elements. (rjung) Common: Include original configuration map in worker_env to make it available for workers, e.g. the status worker. (rjung) LB: Refactor "route" return for httpd note. Don't use a member of the worker_record, because that's not thread safe. (rjung) Common: Refactor "retries", remove from service and jk_worker, move into ajp worker instead. (rjung) SHM: Use distinct structs for lb and ajp13 in shm. Improves type safety and saves a few bytes. (rjung) SHM: Remove unused attributes. (rjung) SHM: Automatically determine shm size for all web servers. (rjung) SHM: Make open/attach logging consistent for all web servers. (rjung) Status: Include server local time in output. (rjung) 44116: Fix handling of multiple JSESSIONID cookies. (rjung) 37850: Use thread safe localtime_r where appropriate. (rjung) Use thread safe strtok_r on more platforms, especially AIX. (rjung) Status: Improve XSS hardening. (rjung) 35303: Move initialization of service members with defaults from web server specific code to our generic jk_init_ws_service() function. (rjung) 36385: Add missing prepost CPing/CPong directly after connect in case prepost CPing is used, but no connect CPing. (rjung) 37322: Apache: Enhance robustness of message formating in jk_error_exit(). (rjung) 44147: Multiple load balancing workers problem. (rjung)

    42003: Allocate memory instead using fixed size from the stack. (mturk) 43229: Load balancer does not do fail over after reply timeouts. (rjung) JKStatus: Repair detailed Apache httpd version display. This was broken for httpd version 2.2.4+. (rjung) LB/AJP: Refactoring of jk_connect.c, jk_ajp_common.c, jk_lb_worker.c (rjung) Configure: Repair broken apxs auto-detection. (rjung) Configure: Remove trace logging from compiled code via new --disable-trace configure switch. (rjung) Common: Maintain idle connections in decreasing (LRU) slot order. (rjung) Apache: Create JK_WORKER_ROUTE and JK_REQUEST_DURATION notes for access log even if no JkRequestLogFormat is set. (rjung) JKStatus: Enhance URI to worker map listing for Apache httpd. We now list maps for all virtual servers and not only the one, in which JKStatus itself was called. (rjung) JKStatus: Enhance URI to worker map listing. Update stale uriworkermap.properties immediately. (rjung) 43873: Fix small memory leak occuring during httpd restart. (rjung) Common: Allow '*' for the worker name in exclusion rules (resp. JkUnMount) which will override all workers. (rjung) 42038: Correct overlay of mounts and unmounts for IIS. (rjung) 43684: Replace JkMountFile by JkMountFileReload in uriworkermap.properties docs. (rjung) Apache: Add new value "All" for JkMountCopy. (rjung) 43516: Memory leak for Apache httpd module of size 8KB for every virtual host without JK directive after each restart. (rjung) Apache: Cleanup init and destroy of server configuration. (rjung) Apache: Remove global configuration items from per server configuration. (rjung) Apache: Remove unused attributes secret_key and automount/JkAutoMount. (rjung) Cleanup of jk_uri_worker_map. (rjung) Documentation: Small additions to JkShmFile documentation. Contributed by Gerhardus Geldenhuis. (rjung) AJP13: Ignore flush packets before we received the response headers. (rjung) Fix crash during startup when using worker configuration inheritance (attribute "reference") and log level debug. (rjung) AJP13: Match header names exactly against pre defined constants. Avoid possible confusion with custom header names using a standard header name as a prefix. (rjung) jkstatus: Fix correct parameter validation at JkStatusUpdateTask and JkStatusUpdateLoadbalancerTask ant tasks. Reported by Christian Mittendorf. (pero)

    IIS: Fix shm shutdown behaviour. (rjung) General: fail_on_status used in a load balancer can optionally do fail over without putting the failed worker in error state. (rjung) NSAPI: Improve build description for Unix. (rjung) NSAPI: Add initialization startup message containing JK version. (rjung) General: Declare static functions as static. (jim) Documentation: Clarify fail_on_status behaviour. (rjung) General: Do fail_on_status before returning the response headers. (rjung) NSAPI: Fix shm shutdown behaviour. (rjung) NSAPI: Set return status even if request ended with an error. (rjung) NSAPI: Allow using without shm_file on WIN32 and Netware. (rjung) NSAPI: Fix Crash of nsapi for log level debug and unset refect_unsafe. (rjung) NSAPI: Improve Solaris and Linux Makefiles for nsapi build. (rjung) Build: Improve pid_t type detection during configure on Solaris. (rjung) Build: Experimental build support for gcc on WIN32 and Netware. (fuankg) Build: Makefile optimizations for Apache httpd 1.3/Netware . (fuankg) General: Fix missing flush bug introduced in 1.2.24. (rjung)

    Documentation: Improved workers.properties description in the reference guide. (rjung) Documentation: Add a HowTo about the various timeouts. rjung) Logging: add milliseconds to the default timestamp format, if we have gettimeofday(). (rjung) Apache: add milliseconds (%Q) and microseconds (%q) as possible JkLogStampFormat conversion specifiers. This does not use strftime(), but needs gettimeofday(). (rjung) IIS & Sun: Log service failures also, if return code is negative. (rjung) 42849: Abort startup of Apache httpd 1.3 in case mod_jk initialization failed. We already do the same for Apache httpd 2.x. (rjung) 42849: Refuse to operate with IIS in case the initialization failed. Instead requesting isapi_redirect.dll 500 will be returned to the user. This is as closest as it can get to Apache Httpd where we refuse to start the server in case of fatal initialization errors. (mturk) Load Balancer: Fix a deadlock in lb worker, which was exposed on Solaris for threaded Apache MPMs. (rjung) Logging: handle LWP IDs as 32 Bit unsigned. Try to make it work, although pthread IDs are opaque. (rjung) JkStatus: Added manipulation of max_reply_timeouts. (rjung) LB, Status: Add feature max_reply_timeouts, to make lb tolerant against occasional long running requests. (rjung) JkStatus: Added OK/IDLE as the successor of N/A. (rjung) Status worker: Renamed runtime states. All states have a major state (OK or ERR) and a substate. Changed the name N/A to OK/IDLE. Added docs about the meaning of the states to the status worker page in the reference guide. No new states have been added to code. (rjung) Common: Add recovery options for recovering idempotent http methods HEAD and GET. (rjung) Correct documentation for worker attributes retries and recovery_options. (rjung) Make writing log lines and line endings more atomic. (rjung) Common: Refactored and unified jk_map_read_prop* and jk_map_load_prop* for all use cases. (rjung) Common/Apache/IIS/Netscape: Add an option to check decoded URLs for potentially malicious constructions. (rjung) IIS: Document auth_complete and uri_select. (rjung) Apache/IIS/Netscape: Change the default forwarding encoding to the new proxy method. (jfclere, rjung) Common: Optionally reencode URIs before forwarding to the backend. Based on the URI reencoding done bei httpd mod_proxy. (jfclere, rjung) Common: auto-detect correct print format for pid_t. This fixes at least compiler warnings on Solaris. (rjung) 42608: Handle Content-length as unsigned 64Bit to allow for huge up- and downloads. (rjung) Apache: Add forwarding uri to debug log. (rjung) Docs: Clarify relation between worker names and jvmRoute for load balancing. (rjung) Use initial zero timeout for jk_is_socket_connected. The resulting detection is the same but offers a huge performance increase with mod_jk. In most cases the Operating System does not favor the 1 microsecond timeout, but it rather rounds that up to much higher value (frequency of interrupt timer which on most systems defaults to 100Hz). Patch provided by David McLaughlin. (mturk) NSAPI: Check correct log file and shm file configuration during startup. (rjung) NSAPI: Add support for the general options concerning retries, flushing and connection persistance. (rjung) NSAPI: fix crashes due to use of mount attribute in workers.properties. Changed initialization order. (rjung) Improved handling of libtool and discrepancies between CC env variable and CC used during apache build by configure script. (rjung) Always build with thread support, unless flag --enable-prefork is set during for configure. (rjung) Use snprintf/vsnprintf from ap_snprintf.c for platforms other than Windows, which might lack snprintf/vsnprintf implementations when NOT build for Apache httpd 2.x/APR (e.g. Sub Web Server) or without using configure. (fuankg) Imported ap_snprintf() from Apache 1.3. (fuankg) Fix incorrect log object cleanup during statup, leading to crashes at least on iSeries. (rjung) Add jk_stat() and jk_file_exists() as wrapper functions. i5/OS V5R4 expects filename in ASCII for fopen but requires them in EBCDIC for stat(). (hgomez) i5/OS (AS/400) V5R4 port where Apache 2.0 modules should now use UTF8. (hgomez) Docs: Add comments on i5/OS build for V5R4 and previous releases. (hgomez)

    [CVE-2007-0450] and [CVE-2007-1860]: Change the default value of JkOptions to ForwardURICompatUnparsed. The old default value was ForwardURICompat. This should make URL interpretation between Apache httpd and Tomcat consistent (prevent double decoding problems). (rjung)

    Refactor line endings logging to make it correct for all platforms and webservers. (mturk) Added command line windows make files. (mturk) Allow fail_on_status directive to be multi line. (mturk) 42076: Fix name of new option from ForwardCertChain to ForwardSSLCertChain as documented. (rjung) Docs: Fix a couple of typos, change format of a few tables, fix links to news pages. (rjung) Fix correct URL for TC 6 examples in new IIS rewrite.properties configuration example file. (rjung) Add svn properties to several files. (rjung) Add TC 6 examples to uriworkermap.properties in config examples. (rjung) Allow multiple status codes for fail_on_status directive. The status codes can be delimited by space or comma characters. (mturk) IIS. Added pcre like regular expressions for url rewrite rules. (mturk) 41922: Apache 1.3. Enable JkEnvVar. (mturk) Apache. Add --enable-flock configure parameter for explicit compilation of faster flock() system calls for OS supporting those calls. By default the fcntl system call for locking will be used that is a little bit slower but it can work on NFS mounted volumes as well. (mturk) 41562: Add Debug logging for read from client in ISAPI Redirector. Contributed by Tim Whittington. (mturk) Apache. Add ForwardSSLCertChain JkOption. Contributed by Patrik Schnellmann. (mturk) IIS. Do not forbid access to web-inf or meta-inf if there is no mapped worker. This allows to have resource with those names that are outside mapped contexts. (mturk) Apache. Use process id for creating shared memory name and delete shared memory and shared memory lock files on exit. (mturk) IIS. Fix Keep-Alive regression introduced in 1.2.21. (mturk) Delete unused check for empty init_map during startup. (rjung) 41770: Fix startup error if no JkWorkersFile is used. (rjung) Use JK_TRUE/JK_FALSE instead of OK/!OK as return values in init_jk(). (rjung) Minor adjustments to apache startup log messages (when to use STDERR, remove deprecated NOERRNO flag, shm warning and warnings for usage of default files). (rjung) Replace APR precompiler directive by httpd mpm_query to detect MPM threading. Add a debug log message about auto-detected pool size. (rjung) Make MMN check easier to understand and a little more precise (for new ap_get_server_banner()/ap_get_server_description()). We use the new API only for Apache httpd 2.3. This way our binaries are not tightly coupled to a minor 2.0 version, and we don't use ap_get_server_banner() any way. (rjung) Use the full description string ap_get_server_description() instead of the truncated info from ap_get_server_banner(), because this info gets used internally (status worker display and ajp14 backend communication) and is not send back to the normal user. (rjung) 41757: Document the "--enable-prefork" flag of configure. (rjung) Enhance log messages for failures when parsing attribute maps. (rjung) Correct log message during worker initialization, in case remote host could not be resolved. We logged the default host name "localhost" instead of the configured one. (rjung) 41770: Fix the second part of the bug: local_worker and local_worker_only is missing from the list of deprecated attributes (and not supported either), so prevents the web server from startup. (rjung)

    [CVE-2007-0774]: A denial of service and critical remote code execution vulnerability. Caused by buffer overflow in map_uri_to_worker() when URL were longer that 4095 bytes. Reported by ZDI (www.zerodayintiative.com). Please note this issue only affected versions 1.2.19 and 1.2.20 of the Apache Tomcat JK Web Server Connector and not previous versions. Tomcat 5.5.20 and Tomcat 4.1.34 included a vulnerable version in their source packages. Other versions of Tomcat were not affected. Check the worker. parameters and don't start if the parameter is not a valid one. (jfclere) 41439: Allow session IDs to get stripped off URLs of static content in Apache by adding JkStripSession directive (configurable per vhost). (mturk) Change semantics of empty defaults for JkEnvVar variables. Until 1.2.19: not allowed. In 1.2.20: send variables as empty strings, if neither set to non empty in config, nor during runtime. Starting with 1.2.21: If config has no second argument only send variable if set (even when set to empty string) during runtime. Allows good combination with condition attribute in tomcat access log. (rjung) 41610: Fix incorrect detection of missing Content-Length header leading to duplicate headers. Contributed by Boris Maras. (rjung) Better build support for SunONE (Netscape/iPlanet) webservers. (jim) Add warning if duplicate map keys are read and are not allowed, e.g. when parsing uriworkermap.properties. (rjung) Don't concat worker names, if uriworkermap.properties has a duplicate pattern, instead overwrite the worker. (rjung) Log deprecation message even in duplication case. (rjung) uriworkermap.properties: Fix off-by-one problem when deleting URL mapping during reloading of uriworkermap.properties. (rjung) 41439: Allow session IDs to get stripped off URLs of static content in IIS (configurable). (rjung) 41333: Refactoring isapi_plugin configuration reading. (rjung) 41332: Add some more errno logging and unify the format. (rjung) JkStatus: Improved logging by adding status worker name to messages. Added messages to the recover worker action. (rjung) JkStatus: Refactoring searching for workers and sub workers. (rjung) 41318: Add configuration to make status worker user name checks case insensitive. (rjung) JkStatus: Add estimated time until next global maintenance to other mime types and adopt jkstatus ant task. (rjung) JkStatus: Show estimated time until next global maintenance. Change displayed time until next recovery to a min/max pair. (rjung) JkStatus: Allow a user of a read/write status worker to switch it to and from read_only mode temporarily. (rjung) JkStatus: Do not show read/write commands in a read_only status worker. (rjung) JkStatus: Allow lb sub workers in error state to be marked for recovery administratively from the status worker. (rjung) Load Balancer: Do not try to recover multiple times in parallel. Use additional runtime states "PROBE" and "FORCED". (rjung) JkStatus: Improve data synchronization between different processes. (rjung) 41381: Fix segfault in feature fail_on_status (wrong order of log arguments). Patch by Juri Haberland. (rjung) Use correct windows line endings for log file on WIN32 platform. (rjung)

    JkStatus Ant Task documentation page. (pero/rjung) JkStatus Ant Tasks: Add new tasks for update and reset. (pero) JkStatus Ant Tasks: Update for new xml status format. (pero) Allow integer and string values when setting enumeration/boolean attributes via status worker update action. (rjung) Docs: New reference guide page for status worker. (rjung) Docs: Renaming the config dir to reference and using the title Reference Guide in the docs. (rjung) Added retry_on_status for workers directive. (mturk) Status Worker: Add directive to make property prefix and good/bad rule configurable. (rjung) Status Worker: Omit lb members when att=nosw. (rjung) Status Worker: New command cmd=version for a short version output. (rjung) Status Worker: New output stype mime=prop produces property lists. (rjung) Apache: Fix incorrect handling of JkEnvVar when Vars are set multiple times. (rjung) Renamed jvm_route to route. Deprecated jvm_route, but still use it as fallback when parsing the worker configuration. (rjung) IIS: Make uriworkermap file reload check interval configurable. (mturk) Apache: Make uriworkermap file reload check interval configurable. (rjung) Status Worker: Add directives for customizing the XML output (ns, xmlns, doctype). (mturk) Docs: New page with description of uriworkermap. (rjung) Docs: Added short description of max_packet_size to worker reference. (rjung) Status Worker: All functions accessible also for xml and txt mime types (list, show, update, reset). (rjung) Status Worker: New global health indicators for load balancers named bad (error, recovering or stopped), degraded (busy or disabled) and good (the rest, active and OK or N/A). (rjung) Status Worker: New edit page, to change one attribute for all members of a load balancer. (rjung) Status Worker: Standard logging for status worker. (rjung) Status Worker: code refactoring. (rjung) Status Worker: New attribute user (list) denies access, if the request user in the sense of remote_user is not in this list. Empty list = no deny (rjung) Status Worker: New attribute read_only disables the parts of the status worker, that change states and configurations. (rjung) 36121: Don't change main uri when mod_jk serves included uri. (markt) Apache VHosts: Merge JkOptions +base - -base + +vhost - -vhost. (rjung) Apache Docs: Adding requirements, context information, default values and inheritance rules to the Apache config documentation. (rjung) Status Worker: Add source type to status worker, remove the redundant "context" column in the map listing (context=uri). (rjung) uriworkermap: On reload of the file, all old entries from the previous file version get deleted, before the new ones are being read. (rjung) Keep normal maps and exclusion maps internally separate. Don't treat them as the same when adding a rule. (rjung) Status Worker: Display mapping rules also for non-lb workers and in global view. (rjung) Apache VHosts: Use the vhost log files instead of the main log. (rjung) Apache VHosts: Allow individual timestamp formats by refactoring the formatting method. (rjung) Apache VHosts: Adding all missing config items to the virtual host level. Don't overwrite the settings from the global server, but inherit them in case they are not set in the virtual host. (rjung) Apache: remove unnecessary function names from log messages. (rjung) Apache: add a default log file location and a message, if the default gets used. (rjung) Apache: add missing JK_IS_DEBUG_LEVEL() (rjung) Apache VHosts: Allow JkWorkersFile, JKWorkerProperty, JkShmFile and JkShmFileSize only in global virtual server. (rjung) Add some more jk_close_socket() and reduce log level for some info messages. (rjung) Load Balancer: Added the Sessions strategy. Contributed by Takayuki Kaneko. (rjung) Docs: Minor enhancements and syncing with more recent versions. (rjung) 40997: Separate uri mappings from their '!' counterpart when checking for duplicates in uriworkermap reloading. (rjung) 40877: Make sure the shared memory is reset on attach for multiple web server child processes. (mturk) IIS: Added shm_size property to be able to deal with over 64 workers configurations. (mturk) IIS: Increase default thread count to 250, so its the same as Apache Httpd default configuration. (mturk) 40966: Fix socket descriptor checks on windows. (mturk) 40965: Initialize missing service parameters. (mturk) 40938: Fix releasing of rewrite map. Thanks to Chris Adams for spotting that. (mturk) Apache: Added +FlushHeader JkOptions. (mturk) Added explicit flush when AJP body packet size is zero. (mturk) 40856: Fixing case sensitivity bug in URL mapping. (rjung) 40793: Documentation: Improvements to Apache HowTo provided by Paul Charles Leddy. (markt) 40774: Fixing wrong recursion termination. This one restricted the "reference" feature unintentionally to 20 workers. (rjung) 40716: Adding "reference" feature to IIS and Netscape. (rjung) Documentation: Corrected SetEnvIf syntax in JK_WORKER_NAME example. (rjung) Documentation: Added forgotten STATE and ACTIVATION notes for load balancer logging in Apache. (rjung) Apache: Use instdso.sh instead libtool: libtool does not work on HP-UX for example. (jfclere)

    Docs: Add SetHandler and new env var to Apache config docs. (rjung) Apache 1.3: Backport "no-jk" feature. (rjung) Apache: Add an environment variable to make SetHandler "jakarta-servlet" more useful. The variable is JK_WORKER_NAME, but can be changed by the new directive JkWorkerIndicator. (rjung) LB: Don't use single worker shortcut, if the single worker is being diabled. (rjung) Status worker: Add short explanation of activation and error states to legend. (rjung) Docs: Add meaning of zero timeout values for various timeouts in workers.properties. (rjung) LB: Cleanup of Mladens forced recovery. (rjung) LB: Do not change lb_value for recovering workers to max, if we are using BUSYNESS method. (rjung) Apache: Since 1.2.14 mod_jk failed to detect client abort. (rjung) Docs: Corrected description of JkEnvVar. (rjung) Solaris: Detect filio.h in configure to make the new connection detection build on solaris (r432825). (rjung) Add feature to force the recovery of workers that are member of loadbalancer if all the members are in error state. This fixes the time gap where 503 was returned caused by recovery_timeout although the backend was ready to handle the requests. (mturk) Docs: Seperate deprecated directives in their own table. (rjung) Docs: Allow "-" and "_" in worker names. (rjung) Allow multiple lines with attributes "balance_workers" and "mount". (rjung) Make jk_is_some_property match more precisely. (rjung) JkStatus: Make refresh interval changeable. (rjung) JkStatus: Adjust display of recover time wrt. global maintenance. (rjung) LB: Resetting worker state from OK to NA, if worker has been idle too long. (rjung) Avoid compiler warnings concerning the use of lb_*_type arrays. Use functions instead. (rjung) Added %R JkRequestLogFormat option for Apache 1 and Apache 2. (mturk) Allow changing jvm Route from status manager. (mturk) Do not retun 400 if Tomcat fails in the midle of the post request. Return 500 insted. (mturk) LB: Combine ok/error/recovering/busy runtime states into a single scalar. (rjung) LB: Combine active/disabled/stopped configuration states into a single scalar. (rjung) LB: Add several Apache notes to enable standard logging for load balancer results. (rjung) LB: Reorganisation of the main load balancer service loop. (rjung) Implement hierarchical worker configuration via attribute "reference". (rjung) Log deprecated properties. (rjung) IIS: Fix simple_rewrite for the cases where the rewritten url is larger then the original one. (mturk) New JkOption "DisableReuse" to disable connection persistence. (jim) LB: Move sessionid retrieval out of get_most_suitable_worker into service. (rjung) Code cleanup for all service methods (use TRACE, JK_LOG_NULL_PARAMS, null pointer checks). (rjung) JKSTATUS: add refresh link. No refresh for updates. Redirect to list view after update. (rjung) Add new hook add_log_items into servers. (rjung) APACHE httpd: Rename apache logging notes. (rjung) LB: Rename lock and method constants. Add constants for defaults. (rjung) Default log level should be INFO and not DEBUG. Default log level should be the same for all server types. (rjung) Make rewrite_rule_map and log_level as non mandatory directives for isapi_redirect. (mturk) 40107: Rewrite is_socket_connected function. Non blocking socket is not used any more. (mturk) Allow building with VS2005 without too many warnings. (mturk) Decide by MMN, which piped log API we should use. mod_jk 1.2.18 broke compilation with Apache 1.3 pre 1.3.28. (rjung)

    Using socklen_t in getsockopt. Also introducing jk_sock_t. (mturk) Allow recovery wait time below 60 seconds (new minimum is 1 second). (mturk)

    Fix hanging jk status worker when certain attributes are being updated due to double locking. (rjung) Allow JkMount to behave like uriworkermap.properties by parsing pipe symbol as two directive marker. (mturk)

    Added simple rewrite capability for IIS. Although simple it will fulfill most needs. (mturk) Added RECOVER_ABORT_IF_CLIENTERROR recovery_option that closes the connection if client connection is broken during the request. (mturk) Renamed cache_timeout directive to connection_pool_timeout. (mturk) Added connection_pool_minsize directive. (mturk) Deprecate recycle_timeout directive. (mturk) Corrected some HTML syntax bugs in output of status worker. (rjung) Added the refresh=n parameter to the status worker. It will update the display every n seconds. (rjung) Balancer: Add attribute distance to balanced workers to express preferences between workers. (rjung) Balancer: Add attribute jvm_route to balanced workers to be able to use the same target in different balancers. (rjung) Status: Add lb_mult to status. (rjung) Balancer: Make different balancing strategies work in a similar way (use lb_value, use decay during global maintenance, use integer factors for weights. (rjung) Balancer: Improve locking. (rjung) Balancer: Workers start slower after recovering. (rjung) Balancer: Make different balancing strategies work in a similar way (use lb_value, use decay during global maintenance, use integer factors lb_mult for weights). (rjung) Balancer: Move recovery check to global maintenance. (rjung) Balancer: Add global maintenance method, that is called in only one process. (rjung) Extend our use of autoconf to find a 32Bit and a 64Bit unsigned type and their printf formats. (rjung) Logging: piped loggers for JkLogFile and Apache 1.3. (rjung) Logging: Add PID to log lines for each log level apart from REQUEST. (rjung) Logging: flush buffered logs to keep lines in correct order. Output final newline together with log message. (rjung) Reducing shm size. (rjung) Only log removing of old worker, when we actually do it. (rjung) 37469: Fix shared memory close for forked childs. The shared memory will be closed by the parent process. (mturk) 37332: Fix potential misuse of buffer length with snprintf functions. (mturk) 38859: [CVE-2006-7197] Protect mod_jk against buggy or malicious AJP servers in the backend. Patch provided by Ruediger Pluem. (mturk) 38889: Use worker map sorting depending on the path elements, to comply with Servlet spec. Patch provided by Steve Revilak. (mturk) 36138: Added Busyness lb method. Patch provided by Chris Lamprecht. (mturk) Fix pessimistic locking mode. The patch correctly handles the burst load, by syncing the access to the shared memory data. (mturk) 38806: Reclycle worker even if it is disabled. This fixes hot-standby workers in error state. (mturk) 37167: Allow building with BSD-ish like make. (mturk) ISAPI plugin (isapi_redirect.dll) did not provide correct request data for IIS to include in the IIS log. (markt)

    Fix AJP13 Cookie2 parsing. Cookie2 was always send as Cookie. Patch provided by Andre Gebers. (mturk) 35862: NSAPI plugin attempts to read freed memory and attempts to dereference a null pointer. Patch provided by Brian Kavanagh. (markt)

    Fix lb for worker mpm's with cachesize set to lower number then ThreadsPerChild is. If retries is set to value larger then 3 sleep for 100 ms on each attempt. This enables to tune the connection cache, and serialize incoming connections instead returning busy if connection count is larger then cachesize. (mturk) 36525: Solaris core dump. (mturk) 36102: Worker actions do not persist. (mturk) 35864: Status worker doesn't list workers. Patch provided by Martin Goldhahn. (mturk) 35809: JkMountCopy don't work for Apache 2.0 Patch provided by Christophe Dubach. (mturk) 35298: Multiple JK/ISAPI redirectors on a single IIS site are not supported Patch provided by Tim Whittington. (mturk)

    34397: Emergency was handled as Error. (jfclere) 34474: // in URL were not handled correctly with Apache-1.3. (jfclere) Use 64 bits int for transferred/read bytes. Added JkOptions +FlushPackets used to optimize memory usage when sending large data. (mturk) Added lock directive for load balancer that allows more acurate load balancing in case of burst load. (mturk) Added worker.maintain directive to allow customizing default 10 second timeout. On busy servers this value needs to be set on higher value. (mturk) Fix for NetWare compiler to deal with different types between AP13 and AP2 SDKs. (fuankg) Emit much more legible user.dmp crash analysis output for WIN32. (wrowe) 34558: Fix first failover request. (mturk)

    Added ForwardLocalAddress JkOptions flag for passing local instead remote address. Useful for remote addr valve. (mturk) Fix that worker does not get used, when stopped flag is set to true. (pero) Add loadbalance default worker secret attribute to the documentation (pero)

    Backport SC_M_JK_STORED from JK2 for passing arbitrary methods instead failing the request. (mturk) Added missing SEARCH and ACL http methods. (mturk) Add worker secret attribute to the documentation (pero) Add a stopped flag to worker configuration. Set flag to true and the complete traffic to the worker will be stopped. Also update the Ant JkStatusUpdateTask at Tomcat 5.5.10 release. Only usefull in a replicated session cluster.(pero) Added worker maintain function that will maintain all the workers instead just the current one. This enables to recycle the connections on all workers. (mturk) Use shutdown when recycling connections instead hard breaking the socket. (mturk) Add unique directives checking. The directives if unique are now overwritten instead concatenated. (mturk) Allow multiple worker.list directives. (mturk) 34577: For IIS log original request instead loging the request for ISAPI extension. (mturk) 34558: Make sure the returned status codes are the same for ajp and lb workers. (mturk) 34423: Use APR_USE_FLOCK_SERIALIZE for setting log lock on platforms like FreeBSD. Patch provided by Allan Saddi. (mturk) 33843: Fix obtaining LDFLAGS that were used for building Apache HTTPD. Patch provided by Beat Kneubuehl. (mturk) 34358: Enable load balancer method configuration. (glenn) 34357: In some situations Apache 2 mod_jk could segfault when the JkAutoAlias directive is used. (glenn) Add --enable-prefork to the documentation (pero) Update tomcat_trend.pl for new error log string formatting. (glenn)

    Set default shared memory to 64K instead 1M. (mturk) Do not mark the worker in error state if headers are larger then AJP13 limit. (mturk) On iSeries you should use the latest PTF for Apache 2.0 (which is now 2.0.52) and ad minima SI17402/SI17061 or cumulative including them. (hgomez) Change the xml status format to xml attribute syntax (pero) 33248: Fix builds where apxs defines multiple directories for APR includes. (mturk) 32696: Return 404 instead 403 when WEB-INF is requested to comply with Servlet spec. (mturk) Added ANT task for managing jkstatus. (pero) If socket_timeout is set, check if socket is alive before sending any request to Tomcat. (mturk) Added JkMountFile for Apache web servers. This file can contain uri mappings in the form (/url=worker), and is checked for updates at regular 60 second interval. (mturk) Added status worker for managing worker runtime data using web page. (mturk) Added load balancer method directive that is used for setting the algorithm used for balancing workers. Method can be either Request (default) or Traffic. (mturk) Added shared memory to allow dynamic configuration. Shared memory is needed only for unix platform and web servers having multiple child processes. For Apache web server two new directives has been added (JkShmFile and JkShmSize). (mturk) Added textupdate mode to status worker to handle remote updates from ant tasks.(pero) 33562: Fix Reply_timeout when recovery_options is larger than 1. Patch provided by Takashi Satou. (mturk) 33308: Fix segfaults when ForwardDirectories is enabled with Apache 1.3

    Allow anyone to debug and diagnose stack dumps using windbg or any other debugging tool, and (if they add the .pdb files to their installation) to make sense of dr watson logs. Patch provided by William A. Rowe (wrowe) Fix in_addr_t usage by using the real struct ignoring typedef. Patch provided by William A. Rowe (wrowe) Fix url rewriting by restoring the in place uri from which the jsessionid was removed. (mturk) Make load balancer algorithm thread safe by introducing mutex to the load balancer worker. (mturk) Fix sending error pages for IIS to client by adding Content-Type header using correct api function call. (mturk) 32696: Prevent IIS from crushing when web-inf url was requested. (mturk) Use default cachesize for servers that support discovering the number of threads per child process. (mturk). Fix Apache content-length header parsing using case insensitive compare. (billbarker) Fix parsing AJP headers using case insensitive compare. (mturk) Use infinite socket timeout if socket_timeout is set to zero or less then zero. (mturk) Change balanced_workers to balance_workers but keep backward compatibility preserving the old directive. (mturk). Fix ajp initialization for workers with cache_size set to zero. (mturk) 32317: Making mod_jk replication aware (Clustering Support). Patch provided by Rainer Jung. (mturk). 31132: Core dump when JkLogFile is missing from conf. (mturk)

    Added new property named recover_time that can be used to change the default 60 second recover time. (mturk) Added custom retries for worker, so we don't depend on default setting. If set to a number grater then 3, it will sleep for 100ms on retry greater then 3 and then try again. (mturk) Added JkWorkerProperty directive that enables omiting workers.properties file. For example: JkWorkerProperty worker.ajp13a.port=8009. (mturk) Check all JSESSIONID cookies for a valid jvmRoute. If you have multiple Tomcats with overlapping domains, then you can get multiple cookies without a defined order. This will route correctly as long as the different domains don't have any Tomcats in common. (billbarker) Added JkUnMount directive for negative mappings that works as opposite to JkMount directives. It is used for blocking of particular URL or content type. (mturk) Added wildchar match uri mappings. One can now use JkMount to map /app/*/servlet/* or /app?/*/*.jsp. (mturk) Rewrite the logging by adding Trace options. (mturk) Added socket_timeout property that sets the timeout for the socket itself. (mturk) Changed socket_timeout property to recycle_timeout. This better explains what the directive actually does. (mturk) Changed the load balancer algorithm. The idea behind this new scheduler is the following: lbfactor is how much we expect this worker to work, or the worker's work quota. lbstatus is how urgent this worker has to work to fulfill its quota of work. We distribute each worker's work quota to the worker, and then look which of them needs to work most urgently (biggest lbstatus). This worker is then selected for work, and its lbstatus reduced by the total work quota we distributed to all workers. Thus the sum of all lbstatus does not change.(*) If some workers are disabled, the others will still be scheduled correctly. (mturk) Fix iis redirector that was figuring .properties file on each request. (mturk) Start fixing 64/32 bit compatibility issues. (mturk)

    Fix POST Recovery problems in LB mode. (hgomez) Add CPING/CPONG support to avoid problems with hang tomcats. (hgomez) Make POST recovery in LB configurable. (hgomez) Update to Apache License 2.0. (hgomez) For Apache 2.0, when the env var no-jk is present, mod_jk didn't handle request (declined) and as such dont forward requests to tomcats even if URL match. To be used with SetEnvIf or BrowserMatch directives for example to exclude some URL/URI or Browser (hgomez). Add a fix for iSeries (AS/400) which use XOPEN/Unix98 APIs and need sa_len to be set when calling connect(), it will resolve the error EINVAL in jk_connect. (hgomez)

    Fix a thread safe bug when mapping URI's. (billbarker) Fix a thread safe bug when resolving worker host name when using mod_jk with Apache 2 and the worker MPM. (hgomez) Remove an unnecessary error message when connections to all load balanced workers fail. (glenn) When mod_jk cannot connect to a worker include the name of the worker in the error message. This is especially helpful when you are using load balanced workers. (glenn) Fix problem with mod_jk.log getting opened multiple times for Apache 2. Only one mod_jk.log can be configured. (glenn) Fix Apache 2 connector so that DirectoryIndex works for an index.jsp page if JkOptions ForwardDirectories was configured. (hgomez) Fix exposure of JSP source if a //path/to.jsp URL was requested in Apache 1.3 and Apache 2.0 connector. (billbarker)

    Fix use of libtool for Apache mod_jk builds with more recent versions of Apache 2. (jfclere) Use reentrant version of strtok() for web server's which use threads. This fixes a thread safe bug under Apache 2 and the worker MPM. (glenn) Fix the Apache 2 mod_jk hook priority so that mod_jk works well with both mod_alias and mod_dir. (glenn)

    Add the ability to configure JkLog to pipe its log output to an executable such as Apache rotatelogs or cronolog. Apache 2.0 only. (glenn) Add JkAutoAlias to Apache 2.0. (glenn) Apache 2/1.3, if Tomcat returns an error but not content, let Apache handle processing the error returned by Tomcat. (glenn) Added the load balancer sticky_session property. If set to 0 requests with servlet SESSION ID's can be routed to any Tomcat worker. Default is 1, sessions are sticky. (glenn) Cleaned up detection and reporting of aborted client connections. This cleanup also makes sure that mod_jk does not pass any requests on to Tomcat if the remote client aborted its connection. (glenn) Fixed a bug in Apache 2.0 which caused a POST request forwarded to Tomcat to fail if it generated SSI directives which were post processed by mod_include. (glenn) Fixed a bug in JkRequestLogFormat when printing the request URI that could cause a URI with hex escapes sequences to be formatted wrong. (glenn)

    tomcat_trend.pl updated script to support changed logging of aborted requests. (glenn) jk set correctly the content-type in Apache 2.0, making it ready to works with mod_deflate and AddOutputFilterByType. (hgomez) jk will check result of get_endpoint and handle a failure. This call can fail if the allocation for the endpoint fails because of low memory conditions causing a dereference of NULL when we try and access the endpoint. (mmanders)

    14282: Don't send initial chunk for chunked encoding. (costin) Add perl scripts for analyzing mod_jk logs and generating graphs/reports. (glenn) Make JK honor the CanonicalHost directive. (hgomez) Log cleanup. (costin) Fix typos in jk xdocs/docs. (hgomez) Add JkRequestLogFormat to Apache 2.0. (hgomez) Final patches to make JK iSeries compliant. (hgomez)

    JK2 has been put in maintainer mode and no further development will take place. The reason for shutting down JK2 development was the lack of developers interest. Other reason was lack of users interest in adopting JK2, caused by configuration complexity when compared to JK.

    tomcat-connectors-1.2.41-src/xdocs/style.css0000644000000000000020000000361110666607673017327 0ustar rootbin/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ div.screen { margin: 10px 0px 10px 20px; font-size: smaller; color: #ffffff; } div.example { background-color: #e5ecf3; color: #000; padding: 0.5em; margin: 1em 2em 1em 1em; } pre { font-family: "Courier New", Courier, monospace; font-weight: normal; font-style: normal; font-size: smaller; } em.screen { font-weight: normal; font-style: normal; color: #c0c0c0; } p.screen { background-color: #000000; border-style: none; color: #c0c0c0; margin-left: 10px; margin-right: 0px; text-align: left; } b.screen { font-weight: normal; font-style: normal; color: #c0c0c0; } code.screen { background-color: #000000; border-style: none; color: #c0c0c0; margin-left: 10px; margin-right: 0px; text-align: left; } b.code { font-weight: normal; font-style: normal; color: #023264; } p.todo { background-color: #ffffff; border-style: none; color: #000000; margin-left: 20px; margin-right: 10px; text-align: justify; font-size: smaller; }